@rubytech/create-realagent 1.0.612 → 1.0.614
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/package.json +1 -1
- package/payload/platform/plugins/cloudflare/PLUGIN.md +1 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/index.js +370 -96
- package/payload/platform/plugins/cloudflare/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts +16 -0
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts.map +1 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js +41 -0
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js.map +1 -1
- package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +48 -161
- package/payload/platform/plugins/docs/references/deployment.md +3 -1
- package/payload/platform/templates/agents/admin/SOUL.md +20 -0
- package/payload/platform/templates/agents/public/SOUL.md +12 -0
- package/payload/server/public/assets/{admin-DOSuO0gX.js → admin-Df1liz4Y.js} +4 -4
- package/payload/server/public/assets/{public-Ca1REKj1.js → public-ZM0fHAOE.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-DdQbdD_u.css → useVoiceRecorder-CaFVzk8y.css} +1 -1
- package/payload/server/public/index.html +3 -3
- package/payload/server/public/public.html +3 -3
- package/payload/platform/knowledge/maxy.md +0 -794
- /package/payload/server/public/assets/{useVoiceRecorder-DdYY7cm9.js → useVoiceRecorder-OB_Gtr0e.js} +0 -0
|
@@ -1,199 +1,86 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: setup-tunnel
|
|
3
|
-
description: Set up a Cloudflare Tunnel using deterministic MCP tools
|
|
3
|
+
description: Set up a Cloudflare Tunnel using deterministic MCP tools. All subdomain input comes from a rendered UI component — the agent never synthesises or parses domain fragments from free text.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Set Up Cloudflare Tunnel
|
|
7
7
|
|
|
8
|
-
Create a Cloudflare Tunnel so the platform is accessible from the public internet
|
|
8
|
+
Create a Cloudflare Tunnel so the platform is accessible from the public internet. `cloudflare-setup` is the single orchestrator. Every choice the user must make is collected by a UI component that `cloudflare-setup` names in its response — the agent is a courier between UI and tool.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Rules of engagement
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- **Never ask the user for a domain, subdomain, FQDN, tunnel name, or label in chat.** Those fields come only from rendered components.
|
|
13
|
+
- **Never synthesise tool parameters from free text.** If the user types `rogerblack.maxy.bot` in chat, do not pass any part of that string as `adminLabel`, `publicLabel`, `selectedZoneName`, or `selectedTunnelId`. Render the component, let the UI collect the value.
|
|
14
|
+
- **Never retry `cloudflare-setup` with different parameter values on error.** Every error is structured — relay the message and render whatever component the response's `data.render` field names.
|
|
15
|
+
- **Treat every `awaiting_*` status as a render instruction.** Read `data.render`, call `render-component` with its `name` and `data` verbatim, then stop. Wait for the submission to come back as a user message before calling `cloudflare-setup` again.
|
|
13
16
|
|
|
14
17
|
## User-facing language
|
|
15
18
|
|
|
16
|
-
Never say
|
|
19
|
+
Never say API token, scoped token, cert.pem, Zone, DNS, CNAME, ingress, tunnel name, or any Cloudflare-internal terminology to the user. Use plain language: "domain", "address", "remote access", "connection".
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|---------------|-------------|
|
|
20
|
-
| API token / cert.pem | connection |
|
|
21
|
-
| Zone | domain |
|
|
22
|
-
| DNS records | domain routing |
|
|
23
|
-
| Nameservers | domain settings |
|
|
24
|
-
| CNAME | routing entry |
|
|
25
|
-
| Tunnel ID | (don't mention) |
|
|
26
|
-
| Ingress rules | (don't mention) |
|
|
21
|
+
## The flow
|
|
27
22
|
|
|
28
|
-
|
|
23
|
+
1. **Show the browser.** Call `render-component` with `name: "browser-viewer"` and `data: { title: "Cloudflare" }`. Skip when the viewer is already visible.
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Before starting, call `tunnel-status` to assess the current state.
|
|
33
|
-
|
|
34
|
-
- **Tunnel already running with no DNS warnings:** Tunnel is set up. Confirm to the user and stop.
|
|
35
|
-
- **Tunnel running but DNS NOT RESOLVING warning:** The tunnel process works but URLs are dead because nameservers don't point to Cloudflare. Proceed to "Check domain status."
|
|
36
|
-
- **cloudflared not installed:** Call `tunnel-install`. If it fails, tell the user and stop.
|
|
37
|
-
- **`tokenValid: true`, not running:** Token is valid — skip auth. Proceed to "Check domain status."
|
|
38
|
-
- **`hasCert: true` but `hasToken: false`:** cert.pem exists but credentials haven't been derived. Call `tunnel-login` — it will derive credentials from the cert automatically.
|
|
39
|
-
- **`hasCert: false` and `hasToken: false`:** Full flow required. Proceed to "Connect to Cloudflare."
|
|
40
|
-
|
|
41
|
-
## Connect to Cloudflare
|
|
42
|
-
|
|
43
|
-
The platform needs to connect to the user's Cloudflare account. Three deterministic tool calls — no screenshots, no snapshots, no specialist.
|
|
44
|
-
|
|
45
|
-
### Flow
|
|
46
|
-
|
|
47
|
-
1. **Show the browser.** Call `render-component` with `name: "browser-viewer"` and `data: { title: "Cloudflare" }`.
|
|
48
|
-
|
|
49
|
-
2. **Start the login.** Call `tunnel-login`. It returns an auth URL. Store the auth URL.
|
|
50
|
-
|
|
51
|
-
3. **Open the auth URL.** Two deterministic Playwright calls — no specialist, no evaluation:
|
|
52
|
-
- `browser_navigate` with the auth URL
|
|
53
|
-
- `browser_tabs` with `action: "select"` on the current tab (brings it to front in VNC)
|
|
54
|
-
|
|
55
|
-
4. **Tell the user what to do.** Say exactly: "Sign in to your Cloudflare account in the browser and click Authorize when you see the prompt. Let me know when you're done." Then STOP and WAIT. Do not take screenshots. Do not check the page. Do not dispatch a specialist. Just wait.
|
|
56
|
-
|
|
57
|
-
5. **When the user confirms:** Call `tunnel-login` again. It detects the cert and derives credentials automatically. If it returns "Credentials derived" — done, proceed to "Check domain status." If it returns an error, tell the user and ask them to try again in the browser. Maximum 3 attempts.
|
|
58
|
-
|
|
59
|
-
## Check domain status
|
|
60
|
-
|
|
61
|
-
7. **Call `cf-zone-status`** to list all domains on the account with their activation status and nameservers.
|
|
62
|
-
|
|
63
|
-
8. **Handle the domain status.**
|
|
64
|
-
- **Domain is Active:** Proceed to "Create the tunnel."
|
|
65
|
-
- **Domain is Pending:** Nameservers haven't been updated yet. Proceed to "Update nameservers."
|
|
66
|
-
- **No domain on the account:** Call `cf-add-zone` with the domain. If it succeeds, proceed based on the returned status (Active → create tunnel; Pending → update nameservers). If it fails due to permissions, tell the user: "I need you to add your domain to Cloudflare. Sign in at cloudflare.com, click 'Add a site', and enter your domain. Let me know when it's done." Then re-run `cf-zone-status` to confirm.
|
|
67
|
-
|
|
68
|
-
### Update nameservers
|
|
69
|
-
|
|
70
|
-
9. **Get the Cloudflare nameservers** from the `cf-zone-status` output (two hostnames ending in `.ns.cloudflare.com`).
|
|
71
|
-
|
|
72
|
-
10. **Ask the user which registrar they use.** "Your domain needs to be pointed to Cloudflare. Which company did you register your domain with? (e.g., Namecheap, GoDaddy, Porkbun)"
|
|
73
|
-
|
|
74
|
-
11. **Show the browser** (if title changed). Call `render-component` with:
|
|
75
|
-
- `name: "browser-viewer"`
|
|
76
|
-
- `data: { title: "Registrar" }`
|
|
77
|
-
|
|
78
|
-
12. **Navigate to the registrar in the VNC browser.** Dispatch personal-assistant:
|
|
79
|
-
|
|
80
|
-
> Navigate to {registrar_url}. Take a screenshot. Report whether a sign-in page is shown or the user is already signed in.
|
|
81
|
-
|
|
82
|
-
13. **User signs in to their registrar.** Tell the user: "Sign in to your {registrar} account in the browser. Let me know when you're signed in."
|
|
83
|
-
|
|
84
|
-
14. **Navigate to nameserver settings.** Dispatch personal-assistant:
|
|
85
|
-
|
|
86
|
-
> Find the domain "{domain}" in the registrar dashboard. Navigate to its DNS or nameserver settings. Take a screenshot. Report the current nameservers and whether there is an option to set custom nameservers.
|
|
87
|
-
|
|
88
|
-
15. Tell the user to update the nameservers:
|
|
89
|
-
|
|
90
|
-
> Update the nameservers in the browser to:
|
|
91
|
-
> - `{cf_nameserver_1}`
|
|
92
|
-
> - `{cf_nameserver_2}`
|
|
93
|
-
>
|
|
94
|
-
> Replace the existing nameservers and save. Let me know when done.
|
|
25
|
+
2. **Call `cloudflare-setup` with no arguments** the first time. The tool discovers current state (auth, tunnels on account, zones on account, persisted tunnel state) and returns a structured result. Parse `status` and act according to the table below.
|
|
95
26
|
|
|
96
|
-
|
|
27
|
+
## Status table
|
|
97
28
|
|
|
98
|
-
|
|
29
|
+
| Returned `status` | What to do |
|
|
30
|
+
|-------------------------------|-----------|
|
|
31
|
+
| `awaiting_auth` | Call `browser_navigate` with `data.authUrl`, then `browser_tabs` with `action: "select"` to bring it front. Tell the user: "Sign in to your Cloudflare account in the browser and click Authorize. Let me know when you're done." Stop. When they confirm, call `cloudflare-setup` again with no arguments. |
|
|
32
|
+
| `awaiting_nameservers` | Relay the message verbatim. The user updates nameservers at their registrar, confirms, and you call `cloudflare-setup` again. |
|
|
33
|
+
| `awaiting_tunnel_selection` | The account has existing tunnels. Call `render-component` with `data.render` verbatim. When the user submits, the payload is `{"selectedTunnelId":"<value>"}`. Call `cloudflare-setup` with `{ selectedTunnelId: "<value>" }`. The literal value `"__new__"` means the user chose to create a new tunnel. |
|
|
34
|
+
| `awaiting_zone_selection` | More than one active domain on the account. Call `render-component` with `data.render` verbatim. When submitted, payload is `{"selectedZoneName":"<value>"}`. Call `cloudflare-setup` with `{ selectedZoneName: "<value>" }`. |
|
|
35
|
+
| `awaiting_zone_add_dashboard` | Zero domains on the account. Relay the message. The user adds a domain at `cloudflare.com` in the VNC browser, confirms, and you call `cloudflare-setup` again with no arguments. |
|
|
36
|
+
| `awaiting_labels` | Call `render-component` with `data.render` verbatim — this is the `tunnel-route-picker`. When the user submits, the payload is `{"adminLabel":"...","publicLabel":"..."}` (public may be absent). Call `cloudflare-setup` with `{ adminLabel: ..., publicLabel?: ... }`. |
|
|
37
|
+
| `tunnel-name-taken` | The chosen admin address is already used by another device on the same account. Relay the message and call `render-component` with `data.render` verbatim — this re-renders the picker with an inline error on the Admin field. Proceed as for `awaiting_labels` when the user resubmits. |
|
|
38
|
+
| `label-taken` | DNS for one of the requested addresses is already owned by another device. Relay the message and call `render-component` with `data.render` verbatim — the picker re-renders with the error on the offending field. |
|
|
39
|
+
| `awaiting_password` | Relay the message. The user sets the remote-access password in their own browser (not the VNC browser) at the `setupUrl`. Wait, then call `cloudflare-setup` again. **Important:** always wrap `setupUrl` in backticks — double underscores in `/__remote-auth/setup` are markdown-escaped otherwise. |
|
|
40
|
+
| `complete` | Relay the message with the admin URL (and public URL if present). Done. |
|
|
41
|
+
| `error` | Relay the message. Do not retry with mutated parameters. |
|
|
99
42
|
|
|
100
|
-
##
|
|
101
|
-
|
|
102
|
-
17. **Ask the user what subdomain names they want.** Suggest `admin` for the admin interface and `public` for the public chat as defaults. The user can override either or decline the public endpoint entirely.
|
|
103
|
-
|
|
104
|
-
> "I'll set up two addresses for your device:
|
|
105
|
-
> - An admin address for managing things (default: `admin.{domain}`)
|
|
106
|
-
> - A public address for your chat (default: `public.{domain}`)
|
|
107
|
-
>
|
|
108
|
-
> Want to use these defaults, or would you prefer different names? You can also skip the public address if you only need admin access."
|
|
109
|
-
|
|
110
|
-
Map the user's response to `adminSubdomain` and `publicSubdomain` values. If the user provides a custom name like "joel", that becomes `adminSubdomain: "joel"`. If the user wants no public endpoint, omit `publicSubdomain`.
|
|
111
|
-
|
|
112
|
-
## Create the tunnel
|
|
113
|
-
|
|
114
|
-
18. **Call `tunnel-create`** with `domain`, `adminSubdomain`, and optionally `publicSubdomain`. `tunnel-create` is idempotent — safe to call again. It creates the tunnel on Cloudflare's edge, configures ingress rules, and creates CNAME records for the specified hostnames. If a hostname already points to a different tunnel (collision), the tool refuses and asks for a different subdomain. If the SDK DNS calls fail due to token scope, it falls back to CLI-based DNS routing automatically.
|
|
115
|
-
|
|
116
|
-
19. **Check the response for DNS warnings.** If the domain isn't Active on Cloudflare, return to "Update nameservers." If DNS propagation is in progress, wait and re-check.
|
|
117
|
-
|
|
118
|
-
20. **Tell the user.** "Your tunnel is created and your domain is configured. One more step — setting a password for remote access."
|
|
119
|
-
|
|
120
|
-
## Enable the tunnel
|
|
121
|
-
|
|
122
|
-
20. **Set remote password.** The remote password gates external access to the admin interface — `tunnel-enable` refuses to start without it. The password is set by the user in their own browser, never in chat.
|
|
123
|
-
|
|
124
|
-
Call `remote-auth-status` (admin MCP tool). The response is deterministic: `configured` (boolean) and `setupUrl` (the browser URL for setting a password).
|
|
125
|
-
|
|
126
|
-
- If `configured: true`: proceed to enable.
|
|
127
|
-
- If `configured: false`: tell the user to open `setupUrl` in their own browser (not the VNC browser) and set a remote access password. This password protects admin access over the internet — separate from the local PIN.
|
|
128
|
-
|
|
129
|
-
**IMPORTANT — markdown escaping hazard:** The `setupUrl` contains double underscores (`/__remote-auth/setup`). Always wrap it in backticks (inline code) so markdown does not escape `__` to `\_\_`. A URL with backslash-escaped underscores will 404.
|
|
130
|
-
|
|
131
|
-
> No remote password set yet. You need to create one — it protects your admin interface when accessed over the internet.
|
|
132
|
-
>
|
|
133
|
-
> Open this URL in your own browser (not the one in the chat) and set a password:
|
|
134
|
-
> `{setupUrl from remote-auth-status}`
|
|
135
|
-
>
|
|
136
|
-
> Choose something strong — at least 8 characters with a number and a special character. Let me know when you've submitted it.
|
|
137
|
-
|
|
138
|
-
- **Verification gate:** After the user confirms, wait 3 seconds before the first check — scrypt hashing on ARM takes 2-5 seconds, so an immediate call always returns `false`. Then call `remote-auth-status`. If `configured: true`, confirm and proceed. If still `false`, retry every 3 seconds up to 4 more attempts (15 seconds total). If still `false` after all attempts, tell the user: "Still waiting — this can take a moment on slower devices. Please check the browser to make sure the form submitted, then let me know to try again."
|
|
139
|
-
|
|
140
|
-
- **The agent never collects, sees, or handles the password.** It only checks the tool response. No filesystem paths, no Bash commands.
|
|
43
|
+
## Prerequisites
|
|
141
44
|
|
|
142
|
-
|
|
45
|
+
Before starting, call `tunnel-status` to assess current state.
|
|
143
46
|
|
|
144
|
-
|
|
47
|
+
- **Tunnel already running with no DNS warnings:** Confirm to the user and stop.
|
|
48
|
+
- **Tunnel running but DNS NOT RESOLVING warning:** Call `cloudflare-setup` — it will re-route DNS idempotently.
|
|
49
|
+
- **cloudflared not installed:** `cloudflare-setup` installs it automatically.
|
|
50
|
+
- **`hasCert: false` and `hasToken: false`:** Full flow required. Call `cloudflare-setup` and follow the status table.
|
|
145
51
|
|
|
146
52
|
## Add alias domain
|
|
147
53
|
|
|
148
|
-
An alias domain (e.g. `maxy.chat`) serves the public chat directly — the URL stays as the alias domain in the browser bar.
|
|
54
|
+
An alias domain (e.g. `maxy.chat`) serves the public chat directly — the URL stays as the alias domain in the browser bar. Alias domains go through `tunnel-add-hostname`, which is a single-hop operation independent of `cloudflare-setup`.
|
|
149
55
|
|
|
150
56
|
### Prerequisites
|
|
151
57
|
|
|
152
|
-
- A working tunnel (the main setup flow
|
|
153
|
-
- The alias domain must be an Active zone on the Cloudflare account
|
|
58
|
+
- A working tunnel (the main setup flow must be complete)
|
|
59
|
+
- The alias domain must be an Active zone on the Cloudflare account
|
|
154
60
|
- The tunnel ID (from `tunnel-status`)
|
|
155
61
|
|
|
156
62
|
### Flow
|
|
157
63
|
|
|
158
|
-
1.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
4. **Add the alias hostname.** Call `tunnel-add-hostname` with the alias domain and tunnel ID. The tool handles everything: adds the hostname to the tunnel ingress, creates a CNAME in the alias domain's zone pointing to the tunnel, and registers the alias so the web server recognises it. The web server hot-reloads alias domains automatically — no restart needed.
|
|
165
|
-
|
|
166
|
-
5. **Verify the alias URL works.** Wait a few seconds for the web server to pick up the change, then use `dns-lookup` to confirm the CNAME resolves. Tell the user: "Your public chat is now live at https://{alias_domain}. The URL stays as {alias_domain} — no redirect." If DNS doesn't resolve yet, tell the user propagation takes 1-5 minutes.
|
|
167
|
-
|
|
168
|
-
### User-facing language
|
|
169
|
-
|
|
170
|
-
Same rules as the main flow — no technical terminology. Say "alias domain" or "custom domain" when talking to the user. Never say CNAME, ingress, or zone.
|
|
171
|
-
|
|
172
|
-
### Idempotency
|
|
173
|
-
|
|
174
|
-
`tunnel-add-hostname` is idempotent — safe to call multiple times with the same hostname. If the alias is already configured, it reports that and does nothing.
|
|
64
|
+
1. Confirm the alias domain with the user.
|
|
65
|
+
2. Call `cf-zone-status`. The alias domain must appear as Active. If not, guide the user through adding it (for activation, the main flow's `awaiting_zone_add_dashboard` / `awaiting_nameservers` handling applies).
|
|
66
|
+
3. Call `tunnel-status` for the tunnel ID.
|
|
67
|
+
4. Call `tunnel-add-hostname` with the alias domain and tunnel ID.
|
|
68
|
+
5. Verify with `dns-lookup`. Tell the user: "Your public chat is now live at https://{alias_domain}." DNS propagation takes 1-5 minutes.
|
|
175
69
|
|
|
176
70
|
## Reinstalling / upgrading the platform
|
|
177
71
|
|
|
178
|
-
When re-running the installer
|
|
179
|
-
|
|
180
|
-
1. Call `system-status` to get the current `hostname` and `port` values.
|
|
181
|
-
2. Derive the brand package name from the `brand` field in the response (e.g., `Maxy` → `@rubytech/create-maxy`, `Real Agent` → `@rubytech/create-realagent`).
|
|
182
|
-
3. Run the installer with both flags:
|
|
72
|
+
When re-running the installer, pass `--hostname` and `--port` to preserve the device's current identity:
|
|
183
73
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
74
|
+
1. Call `system-status` to get the current `hostname` and `port`.
|
|
75
|
+
2. Derive the brand package (e.g., `Maxy` → `@rubytech/create-maxy`, `Real Agent` → `@rubytech/create-realagent`).
|
|
76
|
+
3. Run: `npx -y @rubytech/create-realagent --hostname muvin --port 19400`
|
|
187
77
|
|
|
188
|
-
Without these flags, the installer falls back to detection
|
|
78
|
+
Without these flags, the installer falls back to detection which is unreliable when the OS hostname was previously reset to a brand default.
|
|
189
79
|
|
|
190
80
|
## Important
|
|
191
81
|
|
|
192
|
-
-
|
|
193
|
-
- **Never
|
|
194
|
-
- **Never suggest creating or pasting API tokens.** `tunnel-login` handles all authentication. If it fails after 3 attempts, tell the user and stop.
|
|
82
|
+
- **`cloudflare-setup` is the orchestrator.** Every branch decision is already encoded in its returned `status`. Do not call `tunnel-create`, `cf-add-zone`, or `tunnel-enable` from this flow — `cloudflare-setup` invokes them as needed.
|
|
83
|
+
- **Never interact with Cloudflare dashboard forms.** The only Cloudflare URL opened in the VNC browser is the auth URL from `awaiting_auth`. The dashboard is only shown to the user directly when `awaiting_zone_add_dashboard` fires.
|
|
195
84
|
- **The user signs in themselves.** Open the URL, tell the user what to do, wait. Do not evaluate the page.
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
- **All tunnel tools are idempotent** — `tunnel-login`, `tunnel-create`, `tunnel-add-hostname` — safe to call multiple times.
|
|
199
|
-
- **DNS propagation takes 1-5 minutes** after tunnel creation. Nameserver propagation takes minutes to 24 hours.
|
|
85
|
+
- **All tunnel MCP tools are idempotent.** `cloudflare-setup` is safe to call after any partial failure — it reads filesystem state top-to-bottom every call.
|
|
86
|
+
- **DNS propagation takes 1-5 minutes.** Nameserver propagation takes minutes to 24 hours.
|
|
@@ -37,7 +37,9 @@ If you need to restart the service manually (rare), ask Maxy to do it for you.
|
|
|
37
37
|
|
|
38
38
|
Maxy uses a Cloudflare tunnel to make your local Pi accessible from anywhere without opening router ports. The tunnel is configured during setup and runs as a background service.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Setting it up: say "Set up remote access." Maxy walks you through signing into Cloudflare, picking your domain (if you have more than one on your Cloudflare account), and then shows a form where you pick a short name that becomes your admin address. For example, entering `joel` gives you `https://joel.your-domain.com` for admin access. You can also pick a separate address for the public chat, or leave it blank to skip public access. The form only accepts valid address characters (lowercase letters, numbers, hyphens) — Maxy never asks you to type your full URL in chat.
|
|
41
|
+
|
|
42
|
+
Your admin URL looks like: `https://joel.maxy.chat` (the short name is whatever you picked in the form).
|
|
41
43
|
|
|
42
44
|
To check the tunnel status: ask Maxy "Check Cloudflare tunnel status."
|
|
43
45
|
|
|
@@ -1 +1,21 @@
|
|
|
1
1
|
# Soul
|
|
2
|
+
|
|
3
|
+
## Personality
|
|
4
|
+
|
|
5
|
+
The architectural sensibility of an individual contributor (IC). The operator whose output is a function of their own thinking, not their headcount. Pathologically averse to friction and noise in any process. Treats time, knowledge, and money as the three currencies of every decision and works to maximise all three for the owner.
|
|
6
|
+
|
|
7
|
+
Quantitative by instinct. Comfortable with derivatives, distributions, and rates of change; comfortable with markdown, file paths, and graph queries. The same precision applied to either.
|
|
8
|
+
|
|
9
|
+
Believes the IC archetype is the future of work, that the owner is one of them, and that the operations layer should make that archetype viable at the scale of a real business. Acts accordingly: removes coordination overhead, never adds it.
|
|
10
|
+
|
|
11
|
+
## Tone
|
|
12
|
+
|
|
13
|
+
Precise. British English. Plain hyphens, straight quotes, three periods. No emoji. No filler ("just", "simply", "I think", "let me", "I'll go ahead and"). No narration of internal process ("checking", "searching", "let me look"). No padding around an answer.
|
|
14
|
+
|
|
15
|
+
Direct without being curt. The brevity is in service of the owner's time, not at the expense of the conversation. When a longer answer earns its length (a strategic question, a trade-off, a recommendation), give it the space it needs.
|
|
16
|
+
|
|
17
|
+
State what is true. Caveat what is uncertain. Never confident wrong over honestly-checked. A flat "I'd need to check that" beats a confident guess.
|
|
18
|
+
|
|
19
|
+
## Greeting
|
|
20
|
+
|
|
21
|
+
Address the owner directly. Open with what matters now: what changed since last session, what needs attention, what was promised. Skip greetings that don't earn their place. The first message of every session is a status, not a salutation.
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Personality
|
|
4
4
|
|
|
5
|
+
Helpful, precise, warm without being effusive. Speaks for a real business to a real visitor. Not a marketing voice, not a chatbot, not a simulated friend. Treats the visitor's time as the most valuable thing in the conversation.
|
|
6
|
+
|
|
7
|
+
Comfortable saying "I don't know" when the answer isn't in the knowledge provided. Honest about what is on offer and what isn't. Never invents detail to fill a gap.
|
|
8
|
+
|
|
5
9
|
## Tone
|
|
6
10
|
|
|
11
|
+
Plain language. British English. Plain hyphens, straight quotes, three periods. No emoji. No filler ("just", "simply", "let me", "I'll check"). No narration of internal process ("searching", "looking that up").
|
|
12
|
+
|
|
13
|
+
Short answers when the question is short. Longer answers when the visitor genuinely needs the detail: a comparison, a process, a decision. Never padded.
|
|
14
|
+
|
|
15
|
+
Direct without being abrupt. The visitor asked for help; help them, and stop when help is delivered.
|
|
16
|
+
|
|
7
17
|
## Greeting
|
|
18
|
+
|
|
19
|
+
Open by naming the business and what is on offer. Make it clear in the same breath that the visitor is talking to AI. Natural, not bolted on. Invite the question the visitor came to ask.
|