@rubytech/taskmaster 1.7.1 → 1.8.0
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/dist/build-info.json +3 -3
- package/dist/control-ui/assets/{index-F91adp4g.js → index-D3tbqnfY.js} +814 -699
- package/dist/control-ui/assets/index-D3tbqnfY.js.map +1 -0
- package/dist/control-ui/index.html +1 -1
- package/dist/gateway/config-reload.js +1 -0
- package/dist/gateway/server-methods/network.js +165 -0
- package/dist/gateway/server-methods-list.js +2 -0
- package/dist/gateway/server-methods.js +2 -0
- package/package.json +1 -1
- package/skills/taskmaster/SKILL.md +34 -0
- package/skills/taskmaster/references/docs-guide.md +74 -0
- package/taskmaster-docs/USER-GUIDE.md +29 -111
- package/templates/taskmaster/skills/taskmaster/SKILL.md +29 -47
- package/dist/control-ui/assets/index-F91adp4g.js.map +0 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>Taskmaster Control</title>
|
|
7
7
|
<meta name="color-scheme" content="dark light" />
|
|
8
8
|
<link rel="icon" type="image/png" href="./favicon.png" />
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-D3tbqnfY.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="./assets/index-CHIqq3Nn.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
@@ -47,6 +47,7 @@ const BASE_RELOAD_RULES_TAIL = [
|
|
|
47
47
|
{ prefix: "plugins", kind: "restart" },
|
|
48
48
|
{ prefix: "ui", kind: "none" },
|
|
49
49
|
{ prefix: "workspaces", kind: "none" },
|
|
50
|
+
{ prefix: "gateway.tailscale", kind: "none" },
|
|
50
51
|
{ prefix: "gateway", kind: "restart" },
|
|
51
52
|
{ prefix: "discovery", kind: "restart" },
|
|
52
53
|
{ prefix: "canvasHost", kind: "restart" },
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC handlers for network configuration (port + hostname).
|
|
3
|
+
*
|
|
4
|
+
* - network.status: Returns current gateway port (from config) and system hostname.
|
|
5
|
+
* - network.setHostname: Sets the system hostname so mDNS advertises the new .local name.
|
|
6
|
+
* - macOS: `scutil --set LocalHostName` (Bonjour picks it up immediately)
|
|
7
|
+
* - Linux: `hostnamectl set-hostname` + restart avahi-daemon
|
|
8
|
+
*
|
|
9
|
+
* Port changes are handled by the UI via config.patch to gateway.port —
|
|
10
|
+
* the existing reload rule triggers a gateway restart automatically.
|
|
11
|
+
*/
|
|
12
|
+
import os from "node:os";
|
|
13
|
+
import { readConfigFileSnapshot } from "../../config/io.js";
|
|
14
|
+
import { resolveGatewayPort, DEFAULT_GATEWAY_PORT } from "../../config/paths.js";
|
|
15
|
+
import { runExec } from "../../process/exec.js";
|
|
16
|
+
import { ErrorCodes, errorShape } from "../protocol/index.js";
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Hostname helpers
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
/**
|
|
21
|
+
* Validate a hostname per RFC 1123: letters, digits, hyphens, 1–63 chars,
|
|
22
|
+
* cannot start or end with a hyphen.
|
|
23
|
+
*/
|
|
24
|
+
function isValidHostname(name) {
|
|
25
|
+
return /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/.test(name);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Read the mDNS local hostname (the name before `.local`).
|
|
29
|
+
*
|
|
30
|
+
* - macOS: `scutil --get LocalHostName` returns the Bonjour name directly.
|
|
31
|
+
* - Linux: `hostname` (which is also what avahi-daemon advertises).
|
|
32
|
+
* - Fallback: `os.hostname()` (may include `.local` suffix on some systems).
|
|
33
|
+
*/
|
|
34
|
+
async function readLocalHostname() {
|
|
35
|
+
const platform = os.platform();
|
|
36
|
+
try {
|
|
37
|
+
if (platform === "darwin") {
|
|
38
|
+
const { stdout } = await runExec("/usr/sbin/scutil", ["--get", "LocalHostName"], {
|
|
39
|
+
timeoutMs: 5_000,
|
|
40
|
+
});
|
|
41
|
+
const name = stdout.trim();
|
|
42
|
+
if (name)
|
|
43
|
+
return name;
|
|
44
|
+
}
|
|
45
|
+
else if (platform === "linux") {
|
|
46
|
+
const { stdout } = await runExec("hostname", [], { timeoutMs: 5_000 });
|
|
47
|
+
const name = stdout.trim();
|
|
48
|
+
if (name)
|
|
49
|
+
return name;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Fall through to os.hostname()
|
|
54
|
+
}
|
|
55
|
+
// Strip any trailing .local that os.hostname() might include
|
|
56
|
+
return os.hostname().replace(/\.local$/, "");
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Set the mDNS local hostname on the current platform.
|
|
60
|
+
*
|
|
61
|
+
* - macOS: `scutil --set LocalHostName <name>` — Bonjour picks it up immediately.
|
|
62
|
+
* - Linux: `hostnamectl set-hostname <name>` then restart avahi-daemon.
|
|
63
|
+
*
|
|
64
|
+
* Returns null on success, or an error message string on failure.
|
|
65
|
+
*/
|
|
66
|
+
async function setLocalHostname(hostname, log) {
|
|
67
|
+
const platform = os.platform();
|
|
68
|
+
if (platform === "darwin") {
|
|
69
|
+
try {
|
|
70
|
+
await runExec("/usr/sbin/scutil", ["--set", "LocalHostName", hostname], {
|
|
71
|
+
timeoutMs: 10_000,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
76
|
+
log.warn(`network.setHostname: scutil failed: ${detail}`);
|
|
77
|
+
return `Failed to set hostname: ${detail}`;
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (platform === "linux") {
|
|
82
|
+
try {
|
|
83
|
+
await runExec("hostnamectl", ["set-hostname", hostname], { timeoutMs: 10_000 });
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
87
|
+
log.warn(`network.setHostname: hostnamectl failed: ${detail}`);
|
|
88
|
+
return `Failed to set hostname: ${detail}`;
|
|
89
|
+
}
|
|
90
|
+
// Restart avahi-daemon so mDNS advertises the new hostname.
|
|
91
|
+
try {
|
|
92
|
+
await runExec("systemctl", ["restart", "avahi-daemon"], { timeoutMs: 10_000 });
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
// Non-fatal — hostname was set, but mDNS may take time to propagate.
|
|
96
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
97
|
+
log.warn(`network.setHostname: avahi-daemon restart failed: ${detail}`);
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
return `Hostname management is not supported on ${platform}`;
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Handlers
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
export const networkHandlers = {
|
|
107
|
+
/**
|
|
108
|
+
* Return current gateway port and effective mDNS hostname.
|
|
109
|
+
* The hostname comes from discovery.bonjourHostname in config if set
|
|
110
|
+
* (this is what the gateway advertises via mDNS), otherwise the system hostname.
|
|
111
|
+
*/
|
|
112
|
+
"network.status": async ({ respond }) => {
|
|
113
|
+
try {
|
|
114
|
+
const snapshot = await readConfigFileSnapshot();
|
|
115
|
+
const port = snapshot.valid ? resolveGatewayPort(snapshot.config) : DEFAULT_GATEWAY_PORT;
|
|
116
|
+
// Effective mDNS hostname: config override takes priority over system hostname
|
|
117
|
+
const configHostname = snapshot.valid
|
|
118
|
+
? snapshot.config.discovery
|
|
119
|
+
? snapshot.config.discovery
|
|
120
|
+
?.bonjourHostname
|
|
121
|
+
: undefined
|
|
122
|
+
: undefined;
|
|
123
|
+
const hostname = typeof configHostname === "string" && configHostname
|
|
124
|
+
? configHostname
|
|
125
|
+
: await readLocalHostname();
|
|
126
|
+
respond(true, { port, hostname });
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, `Failed to read network status: ${err instanceof Error ? err.message : String(err)}`));
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
/**
|
|
133
|
+
* Set the system hostname (macOS + Linux).
|
|
134
|
+
*
|
|
135
|
+
* - macOS: scutil --set LocalHostName (Bonjour picks it up immediately)
|
|
136
|
+
* - Linux: hostnamectl set-hostname + restart avahi-daemon
|
|
137
|
+
*
|
|
138
|
+
* Params: { hostname: string }
|
|
139
|
+
*
|
|
140
|
+
* The caller should also config.patch discovery.bonjourHostname to keep
|
|
141
|
+
* the gateway's Bonjour advertisement in sync.
|
|
142
|
+
*/
|
|
143
|
+
"network.setHostname": async ({ params, respond, context }) => {
|
|
144
|
+
const platform = os.platform();
|
|
145
|
+
if (platform !== "darwin" && platform !== "linux") {
|
|
146
|
+
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, `Hostname management is not supported on ${platform}`));
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const hostname = typeof params.hostname === "string" ? params.hostname.trim() : "";
|
|
150
|
+
if (!hostname) {
|
|
151
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "Missing required parameter: hostname"));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (!isValidHostname(hostname)) {
|
|
155
|
+
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "Invalid hostname — use letters, digits, and hyphens only (1–63 characters, cannot start or end with a hyphen)"));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const error = await setLocalHostname(hostname, context.logGateway);
|
|
159
|
+
if (error) {
|
|
160
|
+
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, error));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
respond(true, { hostname });
|
|
164
|
+
},
|
|
165
|
+
};
|
|
@@ -34,6 +34,7 @@ import { webHandlers } from "./server-methods/web.js";
|
|
|
34
34
|
import { wizardHandlers } from "./server-methods/wizard.js";
|
|
35
35
|
import { publicChatHandlers } from "./server-methods/public-chat.js";
|
|
36
36
|
import { tailscaleHandlers } from "./server-methods/tailscale.js";
|
|
37
|
+
import { networkHandlers } from "./server-methods/network.js";
|
|
37
38
|
import { wifiHandlers } from "./server-methods/wifi.js";
|
|
38
39
|
import { workspacesHandlers } from "./server-methods/workspaces.js";
|
|
39
40
|
import { brandHandlers } from "./server-methods/brand.js";
|
|
@@ -239,6 +240,7 @@ export const coreGatewayHandlers = {
|
|
|
239
240
|
...workspacesHandlers,
|
|
240
241
|
...brandHandlers,
|
|
241
242
|
...publicChatHandlers,
|
|
243
|
+
...networkHandlers,
|
|
242
244
|
...tailscaleHandlers,
|
|
243
245
|
...wifiHandlers,
|
|
244
246
|
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: taskmaster
|
|
3
|
+
description: "Product knowledge for Taskmaster — answers questions about features, setup, channels, tools, skills, troubleshooting, and what's new by fetching live documentation."
|
|
4
|
+
metadata: {"taskmaster":{"always":true,"emoji":"📚","skillKey":"taskmaster"}}
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Taskmaster Product Knowledge
|
|
8
|
+
|
|
9
|
+
You can answer questions about Taskmaster itself — the platform your assistant runs on. Product documentation is available live at `docs.taskmaster.bot`.
|
|
10
|
+
|
|
11
|
+
## When This Applies
|
|
12
|
+
|
|
13
|
+
Activate when the user asks about Taskmaster features, setup, configuration, channels, tools, skills, troubleshooting, updates, or anything about the platform itself — not their business.
|
|
14
|
+
|
|
15
|
+
## How to Answer
|
|
16
|
+
|
|
17
|
+
Use `web_fetch` to pull documentation from `docs.taskmaster.bot`. Load `references/docs-guide.md` for the full strategy on discovering and fetching the right page.
|
|
18
|
+
|
|
19
|
+
**Quick path:**
|
|
20
|
+
1. Fetch `https://docs.taskmaster.bot/sitemap` to see all available pages
|
|
21
|
+
2. Identify the most relevant page for the question
|
|
22
|
+
3. Fetch that page and answer from its content
|
|
23
|
+
|
|
24
|
+
For "what's new" or version questions, fetch `https://docs.taskmaster.bot/changelog`.
|
|
25
|
+
|
|
26
|
+
## Boundaries
|
|
27
|
+
|
|
28
|
+
- Answer only from fetched documentation — never fabricate features or capabilities
|
|
29
|
+
- If the docs don't answer the question, say so honestly and escalate
|
|
30
|
+
- This skill covers product knowledge only — not the user's business operations
|
|
31
|
+
|
|
32
|
+
## Escalation
|
|
33
|
+
|
|
34
|
+
When you cannot resolve a question from the documentation, direct the user to contact Taskmaster support by messaging the Taskmaster WhatsApp number. Frame it helpfully: "I couldn't find that in the docs — you can message the Taskmaster team on WhatsApp for help."
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Documentation Fetching Guide
|
|
2
|
+
|
|
3
|
+
## Base URL
|
|
4
|
+
|
|
5
|
+
All documentation lives at `https://docs.taskmaster.bot`. Every page can be fetched with `web_fetch`.
|
|
6
|
+
|
|
7
|
+
## Discovery Strategy
|
|
8
|
+
|
|
9
|
+
**Start with the sitemap.** Before guessing at page paths, fetch:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
https://docs.taskmaster.bot/sitemap
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This returns a structured index of every documentation page, organized by section (Getting Started, Channels, Tools, etc.) with brief descriptions. Scan it to find the right page for the user's question.
|
|
16
|
+
|
|
17
|
+
**You only need the sitemap once per session.** After the first fetch, you'll know the available pages and can go directly to specific ones.
|
|
18
|
+
|
|
19
|
+
## Fetching Pages
|
|
20
|
+
|
|
21
|
+
Once you know the right page path from the sitemap, fetch it directly:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
https://docs.taskmaster.bot/channels/whatsapp
|
|
25
|
+
https://docs.taskmaster.bot/tools/skills
|
|
26
|
+
https://docs.taskmaster.bot/gateway/configuration
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The fetched content is the full documentation page in readable format. Answer the user's question from this content.
|
|
30
|
+
|
|
31
|
+
## Common Query Patterns
|
|
32
|
+
|
|
33
|
+
| User asks about... | Fetch |
|
|
34
|
+
|---|---|
|
|
35
|
+
| Setting up a channel (WhatsApp, Telegram, etc.) | `/channels/{channel-name}` |
|
|
36
|
+
| A specific tool or capability | `/tools/{tool-name}` |
|
|
37
|
+
| Skills — creating, editing, managing | `/tools/skills` and `/tools/skills-config` |
|
|
38
|
+
| Gateway configuration or troubleshooting | `/gateway/configuration` or `/gateway/troubleshooting` |
|
|
39
|
+
| Installation or updating | `/install/installer` or `/install/updating` |
|
|
40
|
+
| What's new, recent changes, version info | `/changelog` |
|
|
41
|
+
| General help or getting unstuck | `/help` or `/help/troubleshooting` |
|
|
42
|
+
| How something works conceptually | `/concepts/{concept}` |
|
|
43
|
+
| CLI command usage | `/cli/{command}` |
|
|
44
|
+
| A specific AI provider | `/providers/{provider}` |
|
|
45
|
+
| Multi-agent setup | `/concepts/multi-agent` |
|
|
46
|
+
| Memory system | `/concepts/memory` |
|
|
47
|
+
| Cron jobs / scheduled tasks | `/automation/cron-jobs` |
|
|
48
|
+
| Webhooks | `/automation/webhook` |
|
|
49
|
+
| Remote access | `/gateway/remote` or `/gateway/tailscale` |
|
|
50
|
+
|
|
51
|
+
## Response Guidelines
|
|
52
|
+
|
|
53
|
+
- **Keep answers concise.** The user asked a question — answer it. Don't dump the entire page.
|
|
54
|
+
- **Quote relevant sections** when precision matters (configuration keys, command syntax).
|
|
55
|
+
- **Link to the docs page** so the user can read more: "You can read more at docs.taskmaster.bot/tools/skills"
|
|
56
|
+
- **If the page doesn't fully answer the question**, say what you found and what's missing, then escalate.
|
|
57
|
+
|
|
58
|
+
## What's New
|
|
59
|
+
|
|
60
|
+
For questions about recent changes, new features, or version history:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
https://docs.taskmaster.bot/changelog
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The changelog is organized by version with dates and categorized changes (features, fixes). Use this for "what's new?", "what changed in the latest update?", or version-specific questions.
|
|
67
|
+
|
|
68
|
+
## Escalation
|
|
69
|
+
|
|
70
|
+
If the documentation doesn't answer the question:
|
|
71
|
+
|
|
72
|
+
1. Tell the user what you searched and what you found (or didn't find)
|
|
73
|
+
2. Direct them to contact Taskmaster support on WhatsApp for further help
|
|
74
|
+
3. Don't guess or speculate — honesty builds trust
|
|
@@ -805,6 +805,8 @@ You can also create events by asking the assistant in chat ("remind me every Mon
|
|
|
805
805
|
|
|
806
806
|
Skills are specialised abilities your assistant has — handling customer enquiries, creating quotes, checking the weather, generating images, and more. The Skills tab shows every skill that is installed, whether it is active, and flags anything that is missing (such as an API key a skill needs).
|
|
807
807
|
|
|
808
|
+
One of the preloaded skills is **Taskmaster Product Knowledge**. This lets your assistant answer questions about Taskmaster itself — features, setup, channels, tools, troubleshooting, and what's new. It pulls answers from the live documentation at [docs.taskmaster.bot](https://docs.taskmaster.bot). If it can't find an answer, it will direct you to contact Taskmaster support on WhatsApp.
|
|
809
|
+
|
|
808
810
|
Each skill has a label:
|
|
809
811
|
|
|
810
812
|
| Label | Meaning |
|
|
@@ -868,28 +870,27 @@ If your Pi is connected by Ethernet cable, you can switch to WiFi directly from
|
|
|
868
870
|
|
|
869
871
|
1. Go to the **Setup** page
|
|
870
872
|
2. Find the **WiFi** row in the status dashboard (only appears on Raspberry Pi)
|
|
871
|
-
3. Tap **
|
|
872
|
-
4. Tap the
|
|
873
|
-
5.
|
|
874
|
-
6.
|
|
873
|
+
3. Tap **Edit** — a modal opens with WiFi management controls
|
|
874
|
+
4. Tap **Scan** inside the modal — a list of nearby WiFi networks appears, sorted by signal strength
|
|
875
|
+
5. Tap the network you want to connect to
|
|
876
|
+
6. If the network is password-protected, enter the password and tap **Connect** (or press Enter)
|
|
877
|
+
7. The WiFi row updates to show the connected network name, signal strength, and IP address
|
|
875
878
|
|
|
876
879
|
**Signal bars** next to each network name show the signal strength — more lit bars means a stronger signal.
|
|
877
880
|
|
|
878
881
|
**Auto-reconnect:** Once connected, your Pi remembers the WiFi network and password. If the connection drops (e.g. router reboot, temporary signal loss), the Pi automatically reconnects without any action needed. The WiFi row shows "Saved: (network name)" when a saved network exists but the connection is temporarily down.
|
|
879
882
|
|
|
880
|
-
**Reconnecting:** If WiFi was manually disconnected and you want to reconnect to the saved network, tap **Reconnect** — no need to re-enter the password.
|
|
881
|
-
|
|
882
|
-
**Disconnecting:** Tap **Disconnect** to intentionally drop the current WiFi connection. This prevents auto-reconnect until you tap **Reconnect** or connect to a new network.
|
|
883
|
+
**Reconnecting:** If WiFi was manually disconnected and you want to reconnect to the saved network, tap **Reconnect** inside the WiFi modal — no need to re-enter the password.
|
|
883
884
|
|
|
884
|
-
**
|
|
885
|
+
**Disconnecting:** Tap **Disconnect** inside the modal to intentionally drop the current WiFi connection. This prevents auto-reconnect until you tap **Reconnect** or connect to a new network.
|
|
885
886
|
|
|
886
|
-
**
|
|
887
|
+
**Forgetting a network:** Tap **Forget** inside the modal to remove the saved WiFi password entirely. After forgetting, you'll need to scan and enter the password again to reconnect.
|
|
887
888
|
|
|
888
889
|
> **Tip:** Connect an Ethernet cable first, open the Control Panel, then use the WiFi row to connect. Once WiFi is working, you can remove the Ethernet cable.
|
|
889
890
|
|
|
890
891
|
### Changing Network Settings
|
|
891
892
|
|
|
892
|
-
You
|
|
893
|
+
You can change the port and hostname from the Setup page — no terminal access needed.
|
|
893
894
|
|
|
894
895
|
- **Port** — The number at the end of your control panel URL (e.g., `http://taskmaster.local:18789`)
|
|
895
896
|
- **mDNS hostname** — The friendly name before `.local` (e.g., `taskmaster` in `taskmaster.local`)
|
|
@@ -907,7 +908,7 @@ The port is like an apartment number for your Taskmaster server. The default is
|
|
|
907
908
|
|
|
908
909
|
#### What is the mDNS hostname and why would I change it?
|
|
909
910
|
|
|
910
|
-
The mDNS hostname is the friendly name you use to access your
|
|
911
|
+
The mDNS hostname is the friendly name you use to access your device on your local network. The default is `taskmaster`, so your control panel is at `taskmaster.local`.
|
|
911
912
|
|
|
912
913
|
**When to change it:**
|
|
913
914
|
- You're running multiple Taskmaster instances on the same network (they'll conflict if they all use `taskmaster.local`)
|
|
@@ -915,128 +916,45 @@ The mDNS hostname is the friendly name you use to access your Pi on your local n
|
|
|
915
916
|
|
|
916
917
|
**What happens when you change it:** Your control panel URL changes. If you set the hostname to `dave`, you'll access Taskmaster at `http://dave.local:18789`.
|
|
917
918
|
|
|
918
|
-
#### How to
|
|
919
|
+
#### How to change port and hostname (from the Control Panel)
|
|
919
920
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
**
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
921
|
+
1. Go to the **Setup** page
|
|
922
|
+
2. Find the **Network** row in the status dashboard — it shows your current hostname and port
|
|
923
|
+
3. Tap **Edit** — a modal opens with two fields: **Hostname** and **Port**
|
|
924
|
+
4. Change whichever values you need (hostname must be letters, digits, and hyphens only, 1–63 characters; port must be between 1024 and 65535)
|
|
925
|
+
5. Tap **Save**
|
|
926
|
+
6. The gateway restarts automatically and your browser redirects to the new URL
|
|
926
927
|
|
|
927
|
-
**
|
|
928
|
-
1. Open Terminal (Mac/Linux) or PowerShell (Windows)
|
|
929
|
-
2. Connect to your Pi: `ssh admin@taskmaster.local`
|
|
930
|
-
3. Enter the password when prompted (default: `password`)
|
|
931
|
-
4. Follow the instructions below
|
|
928
|
+
> **Note:** After saving, there is a brief pause while the gateway restarts. Your browser will redirect to the new address automatically. If the page doesn't load within a few seconds, navigate to the new URL manually (e.g. `http://dave.local:19000`).
|
|
932
929
|
|
|
933
|
-
####
|
|
930
|
+
#### Fallback: CLI method
|
|
934
931
|
|
|
935
|
-
|
|
932
|
+
If you can't reach the Control Panel (e.g. the gateway is down), you can make the same changes from the terminal.
|
|
936
933
|
|
|
937
|
-
**
|
|
934
|
+
**Changing the port:**
|
|
938
935
|
|
|
939
936
|
```bash
|
|
940
937
|
taskmaster config set gateway.port 19000
|
|
941
|
-
```
|
|
942
|
-
|
|
943
|
-
(Replace `19000` with whatever port you want)
|
|
944
|
-
|
|
945
|
-
**Step 2:** Reinstall the daemon service (this rewrites the service file with the new port)
|
|
946
|
-
|
|
947
|
-
```bash
|
|
948
938
|
taskmaster daemon install --force
|
|
949
939
|
```
|
|
950
940
|
|
|
951
|
-
> **Important:**
|
|
952
|
-
|
|
953
|
-
**Step 3:** Access the control panel at the new URL: `http://taskmaster.local:19000` (use your new port number)
|
|
941
|
+
> **Important:** Use `taskmaster daemon install --force` (not `taskmaster daemon restart`) to pick up the new port.
|
|
954
942
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
Once you're logged in (either method):
|
|
958
|
-
|
|
959
|
-
**Step 1:** Set the new hostname
|
|
943
|
+
**Changing the hostname (Linux / Raspberry Pi):**
|
|
960
944
|
|
|
961
945
|
```bash
|
|
962
946
|
sudo hostnamectl set-hostname dave
|
|
963
|
-
```
|
|
964
|
-
|
|
965
|
-
(Replace `dave` with whatever name you want — letters and hyphens only, no spaces)
|
|
966
|
-
|
|
967
|
-
> You will see a warning on every `sudo` command until Step 2 completes: `sudo: unable to resolve host dave: Name or service not known`. This is normal — the hostname was changed but the system hasn't been told where to find it yet. Every command still succeeds despite the warning.
|
|
968
|
-
|
|
969
|
-
**Step 2:** Update `/etc/hosts` to match
|
|
970
|
-
|
|
971
|
-
```bash
|
|
972
947
|
sudo sed -i "s/127\.0\.1\.1.*/127.0.1.1\tdave/" /etc/hosts
|
|
973
|
-
```
|
|
974
|
-
|
|
975
|
-
(Replace `dave` with the same name you used in Step 1. You'll see the same warning one last time — after this command, it's gone.)
|
|
976
|
-
|
|
977
|
-
**Step 3:** Restart the mDNS service
|
|
978
|
-
|
|
979
|
-
```bash
|
|
980
948
|
sudo systemctl restart avahi-daemon
|
|
981
949
|
```
|
|
982
950
|
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
**Step 4:** Access the control panel at the new URL: `http://dave.local:18789` (use your new hostname)
|
|
986
|
-
|
|
987
|
-
> **Note:** This changes the hostname for the entire Pi, not just Taskmaster.
|
|
988
|
-
|
|
989
|
-
#### Changing Both
|
|
990
|
-
|
|
991
|
-
If you need to change both the port and hostname:
|
|
992
|
-
|
|
993
|
-
1. Change the port first (Steps 1–2 under "Changing the Port")
|
|
994
|
-
2. Change the hostname (Steps 1–2 under "Changing the mDNS Hostname")
|
|
995
|
-
3. Access the control panel at the new combined URL: `http://dave.local:19000` (use your new hostname + new port)
|
|
996
|
-
|
|
997
|
-
#### Verifying Your Changes
|
|
998
|
-
|
|
999
|
-
After completing the steps above, run these checks **on the Pi** to confirm everything is correct.
|
|
1000
|
-
|
|
1001
|
-
**Check the hostname is set:**
|
|
1002
|
-
|
|
1003
|
-
```bash
|
|
1004
|
-
hostname
|
|
1005
|
-
```
|
|
1006
|
-
|
|
1007
|
-
This should print your new hostname (e.g. `dave`).
|
|
1008
|
-
|
|
1009
|
-
**Check `/etc/hosts` matches:**
|
|
1010
|
-
|
|
1011
|
-
```bash
|
|
1012
|
-
grep 127.0.1.1 /etc/hosts
|
|
1013
|
-
```
|
|
1014
|
-
|
|
1015
|
-
This should show `127.0.1.1` followed by your new hostname (e.g. `127.0.1.1 dave`).
|
|
1016
|
-
|
|
1017
|
-
**Check avahi is broadcasting the new hostname:**
|
|
1018
|
-
|
|
1019
|
-
```bash
|
|
1020
|
-
avahi-resolve -n dave.local
|
|
1021
|
-
```
|
|
1022
|
-
|
|
1023
|
-
(Replace `dave` with your hostname.) This should print your Pi's IP address. If it says "Failed to resolve", restart avahi: `sudo systemctl restart avahi-daemon` and try again.
|
|
1024
|
-
|
|
1025
|
-
**Check the gateway is running on the correct port:**
|
|
1026
|
-
|
|
1027
|
-
```bash
|
|
1028
|
-
taskmaster daemon status
|
|
1029
|
-
```
|
|
1030
|
-
|
|
1031
|
-
This shows the port the gateway is listening on. Confirm it matches what you set.
|
|
1032
|
-
|
|
1033
|
-
**Test locally on the Pi:**
|
|
951
|
+
**Changing the hostname (macOS):**
|
|
1034
952
|
|
|
1035
953
|
```bash
|
|
1036
|
-
|
|
954
|
+
sudo scutil --set LocalHostName dave
|
|
1037
955
|
```
|
|
1038
956
|
|
|
1039
|
-
|
|
957
|
+
After either method, access the control panel at the new URL (e.g. `http://dave.local:19000`).
|
|
1040
958
|
|
|
1041
959
|
#### Flushing DNS Cache on Other Devices
|
|
1042
960
|
|
|
@@ -1711,7 +1629,7 @@ Taskmaster includes a command-line tool called `taskmaster` that you can run in
|
|
|
1711
1629
|
|
|
1712
1630
|
- **Can't reach the Control Panel** — If the web UI is down, SSH into the device and use CLI commands to restart or update
|
|
1713
1631
|
- **Updating from a specific version** — `taskmaster update` works even when the Control Panel can't load
|
|
1714
|
-
- **Changing network settings** — Port and hostname
|
|
1632
|
+
- **Changing network settings when the UI is unreachable** — Port and hostname are normally changed from the Setup page, but the CLI works as a fallback (see "Changing Network Settings" above)
|
|
1715
1633
|
- **Diagnosing problems** — `taskmaster doctor` runs automated health checks that can detect and fix issues the UI can't show
|
|
1716
1634
|
- **Scripting and automation** — CLI commands can be combined in scripts for advanced setups
|
|
1717
1635
|
|
|
@@ -1,58 +1,35 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: taskmaster
|
|
3
|
-
description: "Handle enquiries about Taskmaster — the AI business assistant for small businesses. Product info, pricing, signup, licensing, and support."
|
|
3
|
+
description: "Handle enquiries about Taskmaster — the AI business assistant for small businesses. Product info, pricing, signup, licensing, and support. Fetches live documentation and uses memory for commercial data."
|
|
4
|
+
metadata: {"taskmaster":{"always":true,"emoji":"📚","skillKey":"taskmaster"}}
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
# Taskmaster Product Skill
|
|
7
|
+
# Taskmaster Product & Sales Skill
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
You handle enquiries about Taskmaster itself — product info, features, pricing, signup, licensing, and support. You combine live documentation with commercial data from memory.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
## When This Applies
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
1. Receive message
|
|
14
|
-
2. Search memory for relevant context (FAQ, product info, lessons)
|
|
15
|
-
3. Formulate response using what you found
|
|
16
|
-
4. Send response
|
|
17
|
-
```
|
|
13
|
+
Activate when someone asks about Taskmaster: what it does, how it works, pricing, how to sign up, licensing, or needs support with the product.
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
## Knowledge Sources
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
## What Lives in Memory (Not Here)
|
|
24
|
-
|
|
25
|
-
The following are stored in memory and will change over time. **Never hardcode these:**
|
|
26
|
-
|
|
27
|
-
- Pricing and plans
|
|
28
|
-
- Features and capabilities
|
|
29
|
-
- Setup process
|
|
30
|
-
- Trial/guarantee terms
|
|
31
|
-
- Programme details (founding members, etc.)
|
|
32
|
-
- Specific objection responses
|
|
33
|
-
- Brand positioning and tone guidelines
|
|
34
|
-
|
|
35
|
-
Search `memory/public/` for product info and FAQs.
|
|
36
|
-
Search `memory/shared/` for internal lessons and guidelines.
|
|
17
|
+
**Product knowledge → live docs.** Use `web_fetch` to pull from `docs.taskmaster.bot`. Fetch `/sitemap` first to discover pages, then fetch specific pages to answer feature/setup/troubleshooting questions. For "what's new", fetch `/changelog`.
|
|
37
18
|
|
|
38
|
-
|
|
19
|
+
**Commercial data → memory.** Pricing, plans, trial terms, programme details, objection responses, and prospect pipeline all live in memory. Search `memory/public/` for product info and FAQs. Search `memory/shared/` for internal guidelines and lessons.
|
|
39
20
|
|
|
40
|
-
|
|
21
|
+
**Always check both sources.** Docs for product facts, memory for commercial context. A couple extra seconds for search is fine — this is async messaging.
|
|
41
22
|
|
|
42
|
-
|
|
43
|
-
- Friendly, direct, no waffle
|
|
44
|
-
- WhatsApp-short messages (not walls of text)
|
|
45
|
-
- Confident but not pushy
|
|
46
|
-
- Honest about limitations
|
|
23
|
+
## Conversation Flow
|
|
47
24
|
|
|
48
|
-
### Conversation Flow
|
|
49
25
|
1. **Greet** — warm, ask what they'd like to know
|
|
50
|
-
2. **Search** —
|
|
51
|
-
3. **Answer** —
|
|
26
|
+
2. **Search** — fetch relevant docs page AND search memory
|
|
27
|
+
3. **Answer** — combine documentation with commercial context, keep it concise
|
|
52
28
|
4. **Guide** — if interested, explain next steps (from memory)
|
|
53
|
-
5. **Capture** — if ready, collect
|
|
29
|
+
5. **Capture** — if ready, collect prospect details
|
|
30
|
+
|
|
31
|
+
## When Prospects Are Interested
|
|
54
32
|
|
|
55
|
-
### When Prospects Are Interested
|
|
56
33
|
Collect:
|
|
57
34
|
- Name
|
|
58
35
|
- Industry or business type
|
|
@@ -61,7 +38,15 @@ Collect:
|
|
|
61
38
|
|
|
62
39
|
Store in memory for follow-up.
|
|
63
40
|
|
|
64
|
-
|
|
41
|
+
## Tone
|
|
42
|
+
|
|
43
|
+
- Friendly, direct, no waffle
|
|
44
|
+
- WhatsApp-short messages (not walls of text)
|
|
45
|
+
- Confident but not pushy
|
|
46
|
+
- Honest about limitations
|
|
47
|
+
|
|
48
|
+
## Escalation
|
|
49
|
+
|
|
65
50
|
Hand off to admin when:
|
|
66
51
|
- Billing, refunds, or payment issues
|
|
67
52
|
- Complaints or unhappy customers
|
|
@@ -69,20 +54,17 @@ Hand off to admin when:
|
|
|
69
54
|
- Custom requests outside standard offering
|
|
70
55
|
- Anything you're uncertain about
|
|
71
56
|
|
|
72
|
-
---
|
|
73
|
-
|
|
74
57
|
## Hard Boundaries
|
|
75
58
|
|
|
76
59
|
**NEVER:**
|
|
77
60
|
- Give industry-specific professional advice
|
|
78
|
-
- Quote prices for their services (only product pricing from memory)
|
|
79
|
-
- Make up features or capabilities — if not in memory, don't claim it
|
|
61
|
+
- Quote prices for their services (only Taskmaster product pricing from memory)
|
|
62
|
+
- Make up features or capabilities — if not in docs or memory, don't claim it
|
|
80
63
|
- Make custom pricing promises without admin approval
|
|
81
|
-
- Pretend to be the customer's assistant (you're the company assistant)
|
|
82
|
-
- Answer product questions without checking memory first
|
|
64
|
+
- Pretend to be the customer's assistant (you're the Taskmaster company assistant)
|
|
83
65
|
|
|
84
66
|
**ALWAYS:**
|
|
85
|
-
-
|
|
67
|
+
- Fetch docs for product questions, search memory for commercial questions
|
|
86
68
|
- Be honest about limitations
|
|
87
69
|
- Escalate what you can't handle
|
|
88
70
|
- Keep messages short and scannable
|