@slopus/happy-terminal 0.3.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/LICENSE-CODEX +203 -0
- package/LICENSE-GROK-BUILD +204 -0
- package/LICENSE-HAPPY +21 -0
- package/README.md +60 -0
- package/THIRD-PARTY-NOTICES.md +34 -0
- package/dist/HappyTerminalUserError.d.ts +12 -0
- package/dist/app/AppTranscriptEntry.d.ts +33 -0
- package/dist/app/AppendOnlyStreamingRender.d.ts +12 -0
- package/dist/app/CodexFileDiff.d.ts +20 -0
- package/dist/app/CodexMcpToolCall.d.ts +25 -0
- package/dist/app/CodingAssistantAgentBackend.d.ts +81 -0
- package/dist/app/CodingAssistantApp.d.ts +128 -0
- package/dist/app/CompletedTurn.d.ts +11 -0
- package/dist/app/FileMentionAutocomplete.d.ts +30 -0
- package/dist/app/HappyTerminalProcessTerminal.d.ts +7 -0
- package/dist/app/NoticeChild.d.ts +4 -0
- package/dist/app/SecretMenuController.d.ts +31 -0
- package/dist/app/SelectionList.d.ts +24 -0
- package/dist/app/SessionDraftSync.d.ts +51 -0
- package/dist/app/StartupStatusApp.d.ts +34 -0
- package/dist/app/StartupStatusCardModel.d.ts +22 -0
- package/dist/app/TemporaryFullscreenController.d.ts +9 -0
- package/dist/app/TerminalColorLevel.d.ts +1 -0
- package/dist/app/TerminalOutputTrace.d.ts +12 -0
- package/dist/app/TerminalTheme.d.ts +11 -0
- package/dist/app/TranscriptEntryRenderCache.d.ts +10 -0
- package/dist/app/applyWorkflowRunUpdate.d.ts +2 -0
- package/dist/app/blendComposerBackground.d.ts +2 -0
- package/dist/app/boundedJsonStringify.d.ts +1 -0
- package/dist/app/calculateCacheHitPercent.d.ts +2 -0
- package/dist/app/codexDiffAnsi.d.ts +17 -0
- package/dist/app/compactCompletedTurnEntries.d.ts +2 -0
- package/dist/app/containsMarkdownTable.d.ts +1 -0
- package/dist/app/createAgentMarkdownTheme.d.ts +3 -0
- package/dist/app/createBackgroundTerminalViewer.d.ts +16 -0
- package/dist/app/createCompletedTurn.d.ts +6 -0
- package/dist/app/createEditorTheme.d.ts +3 -0
- package/dist/app/createFileMentionAutocompleteItems.d.ts +3 -0
- package/dist/app/createSecretInputPanel.d.ts +12 -0
- package/dist/app/createSelectionPanel.d.ts +14 -0
- package/dist/app/createSerialTaskQueue.d.ts +1 -0
- package/dist/app/createSessionPicker.d.ts +17 -0
- package/dist/app/createSlashCommands.d.ts +7 -0
- package/dist/app/createStopOnceHandler.d.ts +1 -0
- package/dist/app/createSubagentMonitor.d.ts +17 -0
- package/dist/app/createTerminalInputBurstHandler.d.ts +5 -0
- package/dist/app/createWorkflowMonitor.d.ts +15 -0
- package/dist/app/defaultTerminalTheme.d.ts +1 -0
- package/dist/app/describeModelChoice.d.ts +4 -0
- package/dist/app/describeProviderSignIn.d.ts +2 -0
- package/dist/app/describeReasoningLevel.d.ts +4 -0
- package/dist/app/detectCodexDiffLanguage.d.ts +1 -0
- package/dist/app/encodeModelChoice.d.ts +1 -0
- package/dist/app/endsAfterOpeningCodeFence.d.ts +1 -0
- package/dist/app/findFileMentionContext.d.ts +9 -0
- package/dist/app/findFileMentionPrefix.d.ts +5 -0
- package/dist/app/formatActivityElapsedTime.d.ts +1 -0
- package/dist/app/formatCodexMcpToolResult.d.ts +3 -0
- package/dist/app/formatCompactTokens.d.ts +1 -0
- package/dist/app/formatFileMention.d.ts +1 -0
- package/dist/app/formatProviderError.d.ts +6 -0
- package/dist/app/formatRelativeTime.d.ts +2 -0
- package/dist/app/formatResetDuration.d.ts +1 -0
- package/dist/app/formatSessionPickerEntry.d.ts +14 -0
- package/dist/app/formatSessionTokenStatus.d.ts +6 -0
- package/dist/app/formatSessionUsageSummary.d.ts +3 -0
- package/dist/app/formatStartupStatusUsageRemaining.d.ts +2 -0
- package/dist/app/formatStartupStatusUsageRows.d.ts +2 -0
- package/dist/app/formatSubagentToolCall.d.ts +10 -0
- package/dist/app/formatToolPermissionNotice.d.ts +3 -0
- package/dist/app/formatToolResultForDisplay.d.ts +2 -0
- package/dist/app/formatTurnUsageSummary.d.ts +2 -0
- package/dist/app/formatWorkUsageSummary.d.ts +14 -0
- package/dist/app/highlightAgentCode.d.ts +1 -0
- package/dist/app/highlightCodexDiffLine.d.ts +2 -0
- package/dist/app/highlightShellCommand.d.ts +1 -0
- package/dist/app/humanizeGoalStatus.d.ts +2 -0
- package/dist/app/humanizeMcpName.d.ts +1 -0
- package/dist/app/humanizePermissionMode.d.ts +2 -0
- package/dist/app/humanizePermissionReviewLevel.d.ts +2 -0
- package/dist/app/humanizeProviderId.d.ts +1 -0
- package/dist/app/humanizeReasoningLevel.d.ts +1 -0
- package/dist/app/humanizeSubagentStatus.d.ts +2 -0
- package/dist/app/humanizeToolName.d.ts +1 -0
- package/dist/app/humanizeWorkflowStatus.d.ts +2 -0
- package/dist/app/installResumeInstructions.d.ts +26 -0
- package/dist/app/installTerminalCrashCleanup.d.ts +26 -0
- package/dist/app/isLightTerminalBackground.d.ts +2 -0
- package/dist/app/layoutCodexFileDiff.d.ts +13 -0
- package/dist/app/looksLikeAuthenticationFailure.d.ts +5 -0
- package/dist/app/nearestXtermColorIndex.d.ts +2 -0
- package/dist/app/parseCodexMcpToolInvocation.d.ts +2 -0
- package/dist/app/parseSessionCommand.d.ts +6 -0
- package/dist/app/providerErrorResetAt.d.ts +2 -0
- package/dist/app/providerQuotaToStartupStatusUsage.d.ts +3 -0
- package/dist/app/readClipboardImage.d.ts +9 -0
- package/dist/app/renderActivityWave.d.ts +3 -0
- package/dist/app/renderAgentMarkdown.d.ts +8 -0
- package/dist/app/renderBackgroundTerminalCompletion.d.ts +1 -0
- package/dist/app/renderBackgroundTerminalInteraction.d.ts +2 -0
- package/dist/app/renderBackgroundTerminalSummary.d.ts +1 -0
- package/dist/app/renderChildRows.d.ts +13 -0
- package/dist/app/renderCodexDiffLine.d.ts +3 -0
- package/dist/app/renderCodexFileDiff.d.ts +7 -0
- package/dist/app/renderCodexMcpToolCall.d.ts +2 -0
- package/dist/app/renderCompletedTurnStats.d.ts +2 -0
- package/dist/app/renderExecCommand.d.ts +11 -0
- package/dist/app/renderExploration.d.ts +9 -0
- package/dist/app/renderFullscreenComponent.d.ts +8 -0
- package/dist/app/renderHappyTerminalBanner.d.ts +6 -0
- package/dist/app/renderHappyTerminalVersion.d.ts +1 -0
- package/dist/app/renderNoticeWithChildren.d.ts +7 -0
- package/dist/app/renderPendingSteeringMessages.d.ts +1 -0
- package/dist/app/renderStartupStatusCard.d.ts +7 -0
- package/dist/app/renderSubagentSummary.d.ts +6 -0
- package/dist/app/renderTurnCompletionSeparator.d.ts +1 -0
- package/dist/app/renderWorkflowSummary.d.ts +1 -0
- package/dist/app/resolveInputBackground.d.ts +3 -0
- package/dist/app/resolveStartupProviderQuota.d.ts +3 -0
- package/dist/app/resolveStartupSessionId.d.ts +18 -0
- package/dist/app/resolveTerminalColorLevel.d.ts +2 -0
- package/dist/app/resolveTerminalStyle.d.ts +1 -0
- package/dist/app/resolveTerminalTheme.d.ts +5 -0
- package/dist/app/runApp.d.ts +27 -0
- package/dist/app/runClipboardCommand.d.ts +8 -0
- package/dist/app/sanitizeTerminalText.d.ts +1 -0
- package/dist/app/shortenHomePath.d.ts +2 -0
- package/dist/app/sortSubagentsForDisplay.d.ts +2 -0
- package/dist/app/subagentElapsedMs.d.ts +2 -0
- package/dist/app/subagentLogMessageText.d.ts +2 -0
- package/dist/app/surfaceThemedLine.d.ts +3 -0
- package/dist/app/truncatePathToWidth.d.ts +1 -0
- package/dist/app/truncateTextForDisplay.d.ts +5 -0
- package/dist/app/truncateUtf8BytesForDisplay.d.ts +1 -0
- package/dist/app/upsertSubagentSummary.d.ts +2 -0
- package/dist/app/workflowDisplay.d.ts +2 -0
- package/dist/client/HappyAgentEventHub.d.ts +25 -0
- package/dist/client/RemoteAgent.d.ts +74 -0
- package/dist/client/RemoteAgentRunError.d.ts +4 -0
- package/dist/client/RemoteTerminalAttachment.d.ts +19 -0
- package/dist/client/RemoteTerminalClientReplica.d.ts +14 -0
- package/dist/client/ensureLocalProtocolServer.d.ts +10 -0
- package/dist/client/fetchProviderQuotas.d.ts +10 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/loadAgentCatalog.d.ts +32 -0
- package/dist/config/createProjectConfigSecurityNotice.d.ts +10 -0
- package/dist/config/defaultConfig.d.ts +2 -0
- package/dist/config/getDefaultGlobalConfigPath.d.ts +1 -0
- package/dist/config/getDefaultLocalConfigPath.d.ts +1 -0
- package/dist/config/getDefaultRuntimeConfigPath.d.ts +1 -0
- package/dist/config/getHappyConfigDirectory.d.ts +1 -0
- package/dist/config/getHappyTerminalHome.d.ts +1 -0
- package/dist/config/index.d.ts +15 -0
- package/dist/config/loadConfig.d.ts +2 -0
- package/dist/config/mergeConfigValues.d.ts +2 -0
- package/dist/config/parseConfigToml.d.ts +7 -0
- package/dist/config/readConfigFile.d.ts +2 -0
- package/dist/config/readProjectConfigFile.d.ts +2 -0
- package/dist/config/resolveConfigPaths.d.ts +2 -0
- package/dist/config/runtimeConfigLock.d.ts +1 -0
- package/dist/config/types.d.ts +74 -0
- package/dist/config/updateRuntimeConfig.d.ts +2 -0
- package/dist/config/updateRuntimePreferences.d.ts +2 -0
- package/dist/config/withoutProjectMachineSettings.d.ts +7 -0
- package/dist/config/writeRuntimeConfig.d.ts +3 -0
- package/dist/config/writeRuntimeConfigDefaults.d.ts +2 -0
- package/dist/daemon/createUnixSocketFetch.d.ts +2 -0
- package/dist/daemon/daemonPid.d.ts +11 -0
- package/dist/daemon/ensureHappyAgentBinary.d.ts +15 -0
- package/dist/daemon/ensureLocalProtocolServer.d.ts +24 -0
- package/dist/daemon/getHappyDaemonPaths.d.ts +16 -0
- package/dist/daemon/happyAgentBinaryConfig.d.ts +15 -0
- package/dist/daemon/index.d.ts +5 -0
- package/dist/daemon/runDaemonCommand.d.ts +4 -0
- package/dist/debug/DebugLog.d.ts +11 -0
- package/dist/debug/closeNodeInspector.d.ts +1 -0
- package/dist/debug/createDebugJsonReplacer.d.ts +1 -0
- package/dist/debug/createRequestDebugDirectory.d.ts +1 -0
- package/dist/debug/getDebugRootDirectory.d.ts +1 -0
- package/dist/debug/getNodeInspectorUrl.d.ts +1 -0
- package/dist/debug/index.d.ts +8 -0
- package/dist/debug/openNodeInspector.d.ts +1 -0
- package/dist/debug/registerHappyTerminalDebugRoot.d.ts +5 -0
- package/dist/docs/DESIGN.md +2191 -0
- package/dist/docs/README.md +93 -0
- package/dist/docs/agents-and-collaboration.md +365 -0
- package/dist/docs/architecture.md +468 -0
- package/dist/docs/extending.md +561 -0
- package/dist/docs/happy.md +386 -0
- package/dist/docs/permissions-and-sandbox.md +342 -0
- package/dist/docs/workspaces.md +281 -0
- package/dist/errorToMessage.d.ts +1 -0
- package/dist/formatCliFailure.d.ts +10 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +17151 -0
- package/dist/main.js +18946 -0
- package/dist/observability/daemonContext.d.ts +16 -0
- package/dist/observability/index.d.ts +1 -0
- package/dist/processes/BoundedOutputBuffer.d.ts +20 -0
- package/dist/processes/NativeProcessManager.d.ts +66 -0
- package/dist/processes/ProcessGroupReaper.d.ts +32 -0
- package/dist/processes/index.d.ts +7 -0
- package/dist/processes/isProcessRunning.d.ts +1 -0
- package/dist/processes/isTargetProcessAlive.d.ts +1 -0
- package/dist/processes/killProcessTree.d.ts +2 -0
- package/dist/processes/resolveSystemShell.d.ts +1 -0
- package/dist/processes/startProcessTransport.d.ts +33 -0
- package/dist/processes/types.d.ts +41 -0
- package/dist/processes/waitForProcessExit.d.ts +2 -0
- package/dist/protocol/AppletProtocol.d.ts +101 -0
- package/dist/protocol/Attachment.d.ts +96 -0
- package/dist/protocol/ClientProtocolTypes.d.ts +481 -0
- package/dist/protocol/DocumentProtocol.d.ts +109 -0
- package/dist/protocol/EventId.d.ts +1 -0
- package/dist/protocol/FolderProtocol.d.ts +236 -0
- package/dist/protocol/FolderSharingProtocol.d.ts +97 -0
- package/dist/protocol/GitHubPluginProtocol.d.ts +43 -0
- package/dist/protocol/GlobalSecurityProtocol.d.ts +7 -0
- package/dist/protocol/HappyCloudProtocol.d.ts +178 -0
- package/dist/protocol/InstallationProtocol.d.ts +80 -0
- package/dist/protocol/OnboardingProtocol.d.ts +47 -0
- package/dist/protocol/P2pCredentialProtocol.d.ts +273 -0
- package/dist/protocol/P2pIdentityProtocol.d.ts +8 -0
- package/dist/protocol/P2pPairingProtocol.d.ts +68 -0
- package/dist/protocol/P2pProtocol.d.ts +185 -0
- package/dist/protocol/PluginWireTypes.d.ts +81 -0
- package/dist/protocol/ProfileProtocol.d.ts +127 -0
- package/dist/protocol/ProjectFileProtocol.d.ts +63 -0
- package/dist/protocol/ProjectProtocol.d.ts +646 -0
- package/dist/protocol/ProtocolVersion.d.ts +8 -0
- package/dist/protocol/ServiceNotice.d.ts +175 -0
- package/dist/protocol/SessionProtocol.d.ts +1156 -0
- package/dist/protocol/SharingProtocol.d.ts +159 -0
- package/dist/protocol/SlotProtocol.d.ts +270 -0
- package/dist/protocol/TimelineProtocol.d.ts +88 -0
- package/dist/protocol/WorkletProtocol.d.ts +159 -0
- package/dist/protocol/createEventIdFactory.d.ts +7 -0
- package/dist/protocol/index.d.ts +34 -0
- package/dist/readPackageVersion.d.ts +1 -0
- package/dist/readPackageVersion.js +16 -0
- package/dist/reportCliFailure.d.ts +2 -0
- package/dist/runHappyTerminal.d.ts +6 -0
- package/dist/terminal/index.d.ts +2 -0
- package/dist/terminal/types.d.ts +39 -0
- package/dist/types.d.ts +6 -0
- package/dist/writeStderrSync.d.ts +5 -0
- package/package.json +97 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# The Happy family
|
|
2
|
+
|
|
3
|
+
Happy is a family of two products, built by the same authors as Happy Agent, that put
|
|
4
|
+
people in touch with the coding agents working for them. Both connect to Happy Agent,
|
|
5
|
+
and both can be the thing on the other end of a conversation you are having.
|
|
6
|
+
|
|
7
|
+
- **Happy** is _end-to-end encrypted remote access to your coding agents_. A
|
|
8
|
+
mobile and web client lets you watch and steer agents that are running on your
|
|
9
|
+
own machine, from anywhere. The relay in the middle carries only ciphertext
|
|
10
|
+
and can read nothing.
|
|
11
|
+
- **Happy 2** is Happy's _desktop collaborative sibling_: a self-hosted,
|
|
12
|
+
Slack-like workspace where people and coding agents build together —
|
|
13
|
+
conversations, files, documents, workspaces, and agents in one app, started
|
|
14
|
+
with a single command and keeping all of its state on the machine that runs
|
|
15
|
+
it.
|
|
16
|
+
|
|
17
|
+
They solve two halves of the same problem. Happy answers "my agent is working
|
|
18
|
+
on my machine and I am not at my machine." Happy 2 answers "my team and our
|
|
19
|
+
agents need one shared place to work." Happy Agent is the coding-agent runtime
|
|
20
|
+
underneath both: Happy synchronizes your live Happy Agent sessions to your phone, and
|
|
21
|
+
Happy 2 executes its agents as Happy Agent sessions.
|
|
22
|
+
|
|
23
|
+
A naming note, because the two products share a word. In this documentation,
|
|
24
|
+
**Happy** always means the encrypted remote-access product, and **Happy 2**
|
|
25
|
+
always means the collaborative desktop workspace. Happy 2 is started with
|
|
26
|
+
`npx happy2` and keeps its state under `.happy2`, so its package names,
|
|
27
|
+
configuration keys, and paths read `happy2`. Happy Agent's own `happy_integration`
|
|
28
|
+
setting belongs to **Happy**, not to Happy 2 — and Happy 2 deliberately turns that
|
|
29
|
+
integration off in the private Happy Agent runtime it manages.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
# Happy — encrypted remote access to your agents
|
|
34
|
+
|
|
35
|
+
## What it is
|
|
36
|
+
|
|
37
|
+
Happy is a mobile app (iOS and Android) and a web app that act as a remote
|
|
38
|
+
control for coding agents running on your own computer. You start work in a
|
|
39
|
+
terminal, walk away, and keep reading the transcript, answering questions,
|
|
40
|
+
sending new instructions, or stopping a run from your phone. Nothing about
|
|
41
|
+
where the agent runs changes: the agent stays on your machine, with your files,
|
|
42
|
+
your credentials, and your permission boundary.
|
|
43
|
+
|
|
44
|
+
The design constraint that shapes everything else is that the server in the
|
|
45
|
+
middle must not be able to read your work.
|
|
46
|
+
|
|
47
|
+
## Architecture
|
|
48
|
+
|
|
49
|
+
Happy has three parts:
|
|
50
|
+
|
|
51
|
+
| Part | Where it runs | What it does |
|
|
52
|
+
| ---------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
53
|
+
| **Client** | Your phone or browser | Renders sessions, transcripts, and machines; sends messages, permission answers, and control commands. |
|
|
54
|
+
| **Relay server** | Hosted | Stores and routes opaque encrypted blobs, delivers realtime updates and push notifications. Holds no readable content. |
|
|
55
|
+
| **CLI / daemon** | Next to the agent, on your machine | Runs or wraps the coding agent, encrypts everything before it leaves, and executes commands that arrive from the client. |
|
|
56
|
+
|
|
57
|
+
On your own machine, the Happy CLI is installed globally (`npm install -g
|
|
58
|
+
happy`) and used in place of the agent command — `happy claude`, `happy codex`.
|
|
59
|
+
It keeps local state under `~/.happy` (relocatable with `HAPPY_HOME_DIR`):
|
|
60
|
+
`access.key` holds the local key material, `settings.json` the profile and
|
|
61
|
+
onboarding state, `daemon.state.json` the background daemon's PID, control
|
|
62
|
+
port, and version, and `logs/` the CLI and daemon logs. The daemon is what lets
|
|
63
|
+
the client reach a machine when no terminal is attached: it registers the
|
|
64
|
+
machine, spawns sessions on request, and keeps machine state synchronized.
|
|
65
|
+
|
|
66
|
+
The relay is a Fastify server with Socket.IO for realtime, Postgres for
|
|
67
|
+
storage, and S3-compatible blob storage for uploads. Its API surface deals in
|
|
68
|
+
sessions, machines, messages, artifacts, and a key-value store — but for all of
|
|
69
|
+
those, the interesting fields are ciphertext it never opens.
|
|
70
|
+
|
|
71
|
+
## What "the relay sees only ciphertext" actually means
|
|
72
|
+
|
|
73
|
+
Clients encrypt before sending and decrypt after receiving. The server stores
|
|
74
|
+
and forwards the result as opaque strings and bytes. This covers session
|
|
75
|
+
metadata, session agent state, every session message, machine metadata, daemon
|
|
76
|
+
state, artifact headers and bodies, key-value entries, and access keys.
|
|
77
|
+
|
|
78
|
+
Two encryption variants are in use:
|
|
79
|
+
|
|
80
|
+
- **Legacy**, when a client only holds a 32-byte shared secret: NaCl secretbox
|
|
81
|
+
(XSalsa20-Poly1305) with a 24-byte nonce, laid out as nonce followed by
|
|
82
|
+
ciphertext and authentication tag.
|
|
83
|
+
- **DataKey**, when a client supports per-session and per-machine data keys:
|
|
84
|
+
AES-256-GCM with a 12-byte nonce and 16-byte tag, laid out as a version byte,
|
|
85
|
+
nonce, ciphertext, and tag. The content key itself is wrapped with
|
|
86
|
+
NaCl-compatible X25519/XSalsa20-Poly1305 under an ephemeral keypair and
|
|
87
|
+
travels as a versioned bundle
|
|
88
|
+
in fields such as `dataEncryptionKey`.
|
|
89
|
+
|
|
90
|
+
Everything encrypted becomes base64 on the wire. Identifiers, versions, and
|
|
91
|
+
timestamps stay in plaintext, because the server has to route and order things.
|
|
92
|
+
Separately, and unrelated to your content, the server encrypts certain
|
|
93
|
+
third-party tokens at rest with a server-only key; those are not end-to-end
|
|
94
|
+
encrypted, and they are the server's own secrets, not yours.
|
|
95
|
+
|
|
96
|
+
Practical consequence: the operator of the relay can see that a machine exists,
|
|
97
|
+
that sessions exist, and roughly when they were active. They cannot see your
|
|
98
|
+
prompts, the model's replies, your file contents, your tool calls, or your
|
|
99
|
+
machine's name.
|
|
100
|
+
|
|
101
|
+
## How Happy Agent connects to Happy
|
|
102
|
+
|
|
103
|
+
Happy Agent speaks the Happy protocol natively. It does not wrap another CLI; a Happy Agent
|
|
104
|
+
daemon registers itself as a machine and synchronizes its sessions directly.
|
|
105
|
+
|
|
106
|
+
**Turning it on and off.** Happy integration is enabled by default. It is a machine-level
|
|
107
|
+
decision controlled by `happy_integration = false` under `[settings]` in the user-wide
|
|
108
|
+
configuration file. Repository-level configuration cannot enable or disable it.
|
|
109
|
+
|
|
110
|
+
**Credentials.** When the integration is enabled, the Happy Agent daemon imports newer
|
|
111
|
+
credentials from `~/.happy` at startup, so a machine already paired with the
|
|
112
|
+
Happy CLI needs no extra step. To pair from Happy Terminal directly, `happy-terminal happy auth`
|
|
113
|
+
prints a QR code — a real PNG in terminals that support Kitty or iTerm2 image
|
|
114
|
+
protocols, and a compact text QR everywhere else — which you scan with the
|
|
115
|
+
Happy app. Happy Agent keeps its copy of the access key, machine identity, and settings
|
|
116
|
+
under its own home directory, separate from the CLI's `~/.happy`.
|
|
117
|
+
|
|
118
|
+
**What Happy Agent publishes.** Every primary Happy Agent session you open is synchronized live.
|
|
119
|
+
Happy Agent registers itself as a Happy Agent-kind machine and publishes its display name, host,
|
|
120
|
+
platform, version, and the complete model catalog: each provider, each model,
|
|
121
|
+
its available reasoning levels and default level, its service tiers, and its
|
|
122
|
+
context window. It also publishes Happy Agent's four permission modes with
|
|
123
|
+
human-readable names and descriptions, so the client can offer them. Session
|
|
124
|
+
metadata carries the live activity of a session — the current activity state,
|
|
125
|
+
running processes, queued and running subagents, task counts, and workflow
|
|
126
|
+
counts — along with the current model, provider, and the capabilities the
|
|
127
|
+
session supports.
|
|
128
|
+
|
|
129
|
+
**What a person can do from the app.** Send messages into a running or idle
|
|
130
|
+
session; attach encrypted images; answer permission requests and interactive
|
|
131
|
+
questions; stop the active turn; switch the session's model to any
|
|
132
|
+
provider-qualified model in the catalog and pick a supported reasoning level;
|
|
133
|
+
and ask the machine to spawn a new session in a directory, choosing the
|
|
134
|
+
provider, model, effort, and permission mode. Spawning in a directory that does
|
|
135
|
+
not exist comes back as an explicit request to approve creating it, rather than
|
|
136
|
+
silently creating directories on your machine.
|
|
137
|
+
|
|
138
|
+
A small set of remote procedures is also exposed against a synchronized
|
|
139
|
+
session, so the client can act on the machine through the agent's own
|
|
140
|
+
boundaries: `abort`, `bash`, `listFileTree`, `readFile`, `writeFile`, `ripgrep`, and
|
|
141
|
+
`communication` (the reply channel for interactive questions). These run
|
|
142
|
+
through the same `AgentContext`, filesystem boundary, and sandbox as the
|
|
143
|
+
agent's own tools — the app does not get a wider door than the agent has.
|
|
144
|
+
|
|
145
|
+
**There is no separate remote mode.** Messages that arrive from a phone enter
|
|
146
|
+
the same session, the same queue, and the same permission boundary as messages
|
|
147
|
+
typed into the terminal. You do not hand control back and forth; both surfaces
|
|
148
|
+
are attached to one durable session.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
# Happy 2 — the desktop collaborative workspace
|
|
153
|
+
|
|
154
|
+
## What it is
|
|
155
|
+
|
|
156
|
+
Happy 2 is a self-hosted, Slack-like work and coding app: channels and chats,
|
|
157
|
+
direct messages, documents, files, activity, calls, apps and plugins, and
|
|
158
|
+
administration — with coding agents as first-class members of conversations
|
|
159
|
+
rather than a separate tool you switch to.
|
|
160
|
+
|
|
161
|
+
This page describes the **local, self-hosted** Happy 2, the only mode that
|
|
162
|
+
matters here: the app you start on your own machine, keeping all of its state
|
|
163
|
+
on that machine.
|
|
164
|
+
|
|
165
|
+
- One command starts everything: `npx happy2`, then open
|
|
166
|
+
<http://127.0.0.1:3000>. Node.js 24 or later is required.
|
|
167
|
+
- Everything durable lives under `.happy2` in the directory where Happy 2 was
|
|
168
|
+
started: the SQLite database, uploaded files, generated JWT keys and password
|
|
169
|
+
pepper, plugin state, agent workspaces, and Happy 2's private Happy Agent runtime.
|
|
170
|
+
- The same React application runs in a browser and in an Electron desktop app.
|
|
171
|
+
- `npx happy2 daemon start` and `daemon stop` run it in the background with a
|
|
172
|
+
PID file and logs under `.happy2`; `npx happy2 service start` and
|
|
173
|
+
`service stop` install it as a per-user macOS LaunchAgent or print the
|
|
174
|
+
systemd commands for Linux.
|
|
175
|
+
- Configuration is a partial TOML file merged over built-in defaults, selected
|
|
176
|
+
by `--config`, `HAPPY2_CONFIG`, or `./.happy2/happy2.toml`.
|
|
177
|
+
|
|
178
|
+
## Local architecture
|
|
179
|
+
|
|
180
|
+
| Piece | Role |
|
|
181
|
+
| ------- | ------------------------------------------------------------------------------------- |
|
|
182
|
+
| Server | Fastify backend: authentication, SQLite persistence, files, realtime, agent execution |
|
|
183
|
+
| State | Framework-independent client state; immutable snapshots plus realtime reconciliation |
|
|
184
|
+
| UI | Reusable design system and component workbench |
|
|
185
|
+
| App | The React product, shared by web and desktop |
|
|
186
|
+
| Web | Browser entry point and production web build |
|
|
187
|
+
| Desktop | Electron app that supervises child processes and can host the Happy Terminal surface |
|
|
188
|
+
|
|
189
|
+
The all-in-one executable starts the API on an ephemeral loopback port, serves
|
|
190
|
+
the packaged single-page app on the configured public port, and proxies the API
|
|
191
|
+
internally, so the browser talks to one origin for HTTP, uploads, and
|
|
192
|
+
server-sent events. All useful HTTP endpoints live under a `/v0` prefix; `/` is
|
|
193
|
+
only a small status response. Server APIs use GET and POST only, and POST paths
|
|
194
|
+
name explicit actions rather than CRUD verbs.
|
|
195
|
+
|
|
196
|
+
## How Happy 2 uses Happy Agent
|
|
197
|
+
|
|
198
|
+
Happy 2 drives Happy Agent in **two separate ways**. They are easy to confuse, so keep
|
|
199
|
+
them apart:
|
|
200
|
+
|
|
201
|
+
1. **Server-side agent execution.** The Happy 2 server starts and owns a
|
|
202
|
+
private, bundled Happy Agent daemon and creates one Happy Agent session per agent
|
|
203
|
+
conversation. This is how an agent that is a member of a channel actually
|
|
204
|
+
thinks and works.
|
|
205
|
+
2. **The desktop Happy Terminal surface.** The Electron app hosts Happy Terminal against a Happy
|
|
206
|
+
Agent daemon _you_ already run yourself and shows its projects, sessions, transcripts, files,
|
|
207
|
+
and terminals inside Happy Desktop.
|
|
208
|
+
|
|
209
|
+
### 1. The private Happy Agent runtime that executes agent turns
|
|
210
|
+
|
|
211
|
+
An `[agents]` table configures this path — whether it is enabled, the daemon
|
|
212
|
+
socket and token paths, the Happy Agent command, and the default working directory for
|
|
213
|
+
agent workspaces. Its defaults point at a private Happy Agent runtime under
|
|
214
|
+
`.happy2/agent`, with workspaces under `.happy2/workspaces`.
|
|
215
|
+
|
|
216
|
+
What follows from the implementation:
|
|
217
|
+
|
|
218
|
+
- Happy 2 starts the Happy Agent executable **installed with its own server package**, never a
|
|
219
|
+
global `happy-terminal` binary, with `HAPPY_HOME_DIR` pointing at its private `.happy2` state.
|
|
220
|
+
That home holds the daemon's configuration, session state, socket, and token.
|
|
221
|
+
- Its generated machine configuration disables Happy synchronization, so this private runtime
|
|
222
|
+
never appears as a machine in Happy's encrypted mobile sync.
|
|
223
|
+
- The daemon mode defaults to _managed_: Happy 2 writes an exact internal
|
|
224
|
+
runtime configuration (durable global event queue on, Happy integration off),
|
|
225
|
+
hashes it, checks the running daemon's version, replaces the daemon when
|
|
226
|
+
either drifts, and stops it during shutdown. A separately supervised
|
|
227
|
+
deployment may instead run _attached_, in which case Happy 2 neither rewrites
|
|
228
|
+
nor stops the daemon.
|
|
229
|
+
- Happy 2 talks to the daemon over its Unix socket using the token file beside
|
|
230
|
+
it, and enables the durable global event queue so it can follow one global
|
|
231
|
+
event stream with a cursor and trim it periodically.
|
|
232
|
+
|
|
233
|
+
**One Happy Agent session per agent conversation.** When an agent must answer in a
|
|
234
|
+
chat, Happy 2 resolves or creates a binding of (chat, agent) to a Happy Agent session:
|
|
235
|
+
|
|
236
|
+
- A per-agent sandbox directory pair is created under the configured agent
|
|
237
|
+
working directory, and an OCI container (Docker or Podman) is created from
|
|
238
|
+
that agent's image, with the workspace bind-mounted at `/workspace` and the
|
|
239
|
+
agent home at `/home`.
|
|
240
|
+
- The Happy Agent session is created against that existing container with
|
|
241
|
+
`/workspace` as the working directory, the chat's model, and the agent's
|
|
242
|
+
effort.
|
|
243
|
+
- Child channels reuse their parent conversation's container and working
|
|
244
|
+
directory, so related channels share one environment; their images must
|
|
245
|
+
match.
|
|
246
|
+
- Sessions are created with the `full_access` permission mode. That is
|
|
247
|
+
deliberate: the agent is already confined by a dedicated container sandbox,
|
|
248
|
+
so **full access here means "no extra Happy Agent-side sandbox inside an already
|
|
249
|
+
sandboxed container", not "free rein on the user's machine".**
|
|
250
|
+
- Per-agent and per-channel secrets are registered with Happy Agent and reconciled onto
|
|
251
|
+
the session, so environment values are attached and detached as bindings
|
|
252
|
+
change.
|
|
253
|
+
|
|
254
|
+
**Turns.** Messages addressed to agents become durable turns that Happy 2
|
|
255
|
+
drains one at a time per chat. A channel has a default agent and may address
|
|
256
|
+
additional agent members; a direct message can only address its own agent.
|
|
257
|
+
Happy 2 submits the prompt to Happy Agent, streams the agent-loop events back out of the
|
|
258
|
+
global event stream, and turns them into Happy 2 messages, typing indicators,
|
|
259
|
+
live activity (phase, tool names, subagents, background terminals, token
|
|
260
|
+
counts), and a final reply. Steering delivers new user text into a running
|
|
261
|
+
turn; stopping a run ends it in Happy Agent and releases the worker lease.
|
|
262
|
+
|
|
263
|
+
**Terminals and previews.** Happy 2 can open Happy Agent remote terminals inside the
|
|
264
|
+
agent's container and attach them to the app over WebSocket. Optional
|
|
265
|
+
port-sharing configuration publishes a range of container ports through a
|
|
266
|
+
wildcard preview domain with per-share audiences.
|
|
267
|
+
|
|
268
|
+
### 2. The desktop Happy Terminal surface
|
|
269
|
+
|
|
270
|
+
Happy Desktop can host `@slopus/happy-terminal` against the Happy Agent you installed yourself:
|
|
271
|
+
|
|
272
|
+
- The main process can use the embedded package or the standalone `happy-terminal` command,
|
|
273
|
+
resolves the daemon socket and token, and refuses to connect when the protocol is incompatible.
|
|
274
|
+
- It proxies that daemon connection to the renderer, which uses Happy Agent's client
|
|
275
|
+
library to keep the transcript, session list, model catalog, inbox, provider
|
|
276
|
+
usage, changed files, and terminals live.
|
|
277
|
+
- This is a normal Happy Agent daemon on your machine: your projects, your workspaces,
|
|
278
|
+
your credentials. It is _not_ the private Happy Agent runtime described above.
|
|
279
|
+
|
|
280
|
+
**Remote Happy Agents are in progress.** A prototype in the desktop main process
|
|
281
|
+
reaches another machine over OpenSSH: it asks the machine for its default
|
|
282
|
+
daemon socket and token with one fixed command, forwards that Unix socket to a
|
|
283
|
+
private local one, and then speaks the ordinary daemon protocol over it, so a
|
|
284
|
+
remote daemon looks identical to a local one above the connection boundary. The
|
|
285
|
+
intended destination is that a remote Happy Agent is added by naming a machine the way
|
|
286
|
+
you already reach it over SSH, its projects appear in the sidebar beside local
|
|
287
|
+
ones, Connect and Disconnect work on demand, a disconnected Happy Agent degrades
|
|
288
|
+
cleanly, and no application code above the connection layer branches on remote
|
|
289
|
+
versus local. Treat that polished experience as **planned**; the SSH transport
|
|
290
|
+
exists today.
|
|
291
|
+
|
|
292
|
+
## Files and documents
|
|
293
|
+
|
|
294
|
+
- **Files** are stored by the server under `.happy2/files` with signed URLs,
|
|
295
|
+
quotas, optional malware scanning, and resumable uploads. A chat's workspace
|
|
296
|
+
files are reachable through dedicated workspace endpoints.
|
|
297
|
+
- **Documents** exist today as server-owned collaborative documents with a
|
|
298
|
+
Documents tab, presence, attach and detach to chats, and an approval flow for
|
|
299
|
+
write requests, exercised by a built-in documents plugin.
|
|
300
|
+
- **Planned:** moving document ownership to the Happy Agent instance rather than to
|
|
301
|
+
projects, so each connected Happy Agent exposes its own Documents tab and local
|
|
302
|
+
collection stored in a defined folder on that machine, every saved document
|
|
303
|
+
keeps a normalized Markdown file beside its collaborative state, a document
|
|
304
|
+
can be attached to a session without being owned by it, and agent edits enter
|
|
305
|
+
as versioned changes rather than replacing the collaborative state. A later
|
|
306
|
+
step would synchronize documents between Rigs through an encrypted relay that
|
|
307
|
+
never owns the data.
|
|
308
|
+
- **Planned:** a unified set of file surfaces — Changed files, All files, and an
|
|
309
|
+
in-app preview component for images, video, and Markdown, reused wherever a
|
|
310
|
+
file or link is opened.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
# What an agent under Happy Agent should know
|
|
315
|
+
|
|
316
|
+
## When your session is driven through Happy
|
|
317
|
+
|
|
318
|
+
Your execution does not change. You are an ordinary local Happy Agent session with your
|
|
319
|
+
normal permission mode, working directory, and sandbox. What changes is who is
|
|
320
|
+
watching and who can interrupt:
|
|
321
|
+
|
|
322
|
+
- **A person may be reading along from a phone.** Your text blocks, tool calls,
|
|
323
|
+
and activity are mirrored live. Write as if someone is following on a small
|
|
324
|
+
screen away from their desk.
|
|
325
|
+
- **Messages can arrive from anywhere.** A message sent from the app enters the
|
|
326
|
+
same session and the same queue as terminal input; there is no separate
|
|
327
|
+
remote mode and no reduced boundary. Steering and stopping mid-turn are
|
|
328
|
+
normal outcomes, not failures.
|
|
329
|
+
- **Permission answers and question answers may come from the app.** A reply to
|
|
330
|
+
an interactive question is a trusted user answer regardless of which surface
|
|
331
|
+
it came from.
|
|
332
|
+
- **The model or reasoning level may change under you.** A person can switch
|
|
333
|
+
the session's model and effort from the app. Do not assume the model that
|
|
334
|
+
answered last time.
|
|
335
|
+
- **Your content is encrypted end to end, but it is still leaving the
|
|
336
|
+
machine.** Session content is encrypted before it goes to the relay and the
|
|
337
|
+
relay cannot read it. That is not a reason to treat the transcript as
|
|
338
|
+
private-by-default: it is a normal conversation with a person who may be
|
|
339
|
+
anywhere.
|
|
340
|
+
|
|
341
|
+
## When your session is driven through Happy 2
|
|
342
|
+
|
|
343
|
+
If your session was created by the Happy 2 server, your environment is
|
|
344
|
+
different in ways that matter:
|
|
345
|
+
|
|
346
|
+
- **You are inside a container.** Your working directory is `/workspace` and
|
|
347
|
+
`HOME` is `/home`, both bind-mounted from the host's agent workspace tree.
|
|
348
|
+
You are not in the user's own repository checkout unless someone put it
|
|
349
|
+
there.
|
|
350
|
+
- **Your permission mode is `full_access` by design.** The container is the
|
|
351
|
+
security boundary, not Happy Agent's sandbox. Being unsandboxed inside it is not an
|
|
352
|
+
invitation to act outside the task you were asked to do; behave as carefully
|
|
353
|
+
as you would in Auto mode.
|
|
354
|
+
- **Your conversation is a chat.** Your reply becomes a message in a channel or
|
|
355
|
+
direct message that people and possibly other agents read. Your text blocks,
|
|
356
|
+
tool calls, subagents, and background terminals are surfaced live, so partial
|
|
357
|
+
work is visible while you are still working.
|
|
358
|
+
- **Turns are queued and steerable.** New user messages can be delivered into a
|
|
359
|
+
running turn, and a reader can stop your run at any time. A stopped or steered
|
|
360
|
+
turn is a normal outcome.
|
|
361
|
+
- **Secrets are attached, not discoverable.** Agent- and channel-scoped secrets
|
|
362
|
+
are attached to your session. Use them through the mechanisms Happy Agent exposes; do
|
|
363
|
+
not go looking for credential stores.
|
|
364
|
+
- **Model and effort are chosen by the chat.** They are set and reconciled from
|
|
365
|
+
the chat and agent configuration.
|
|
366
|
+
- **Happy Agent's bundled documentation may not be mounted.** Happy Agent exposes these pages at
|
|
367
|
+
`/happy/docs` only in containers it creates itself. Happy 2 supplies its own
|
|
368
|
+
container, so that path is generally absent there; read documentation from
|
|
369
|
+
the workspace or ask, instead of assuming the path exists.
|
|
370
|
+
|
|
371
|
+
If instead you are an ordinary local Happy Agent session that the Happy 2 **desktop
|
|
372
|
+
app** is displaying, nothing about your execution changes either. Happy 2 is
|
|
373
|
+
only a client watching the same daemon your terminal uses, so a person may be
|
|
374
|
+
reading along, sending messages, switching your model, or stopping your run
|
|
375
|
+
from a window you never see.
|
|
376
|
+
|
|
377
|
+
## Related pages
|
|
378
|
+
|
|
379
|
+
- [architecture.md](architecture.md) — how Happy Agent itself is put together: daemon,
|
|
380
|
+
protocol, sessions, providers, persistence.
|
|
381
|
+
- [permissions-and-sandbox.md](permissions-and-sandbox.md) — the permission
|
|
382
|
+
modes referenced above and how review and escalation actually work.
|
|
383
|
+
- [agents-and-collaboration.md](agents-and-collaboration.md) — subagents,
|
|
384
|
+
messaging between agents, scheduling, and durable waits.
|
|
385
|
+
- [extending.md](extending.md) — plugins, skills, MCP servers, and building on
|
|
386
|
+
Happy Agent from the inside.
|