hostinger-api-mcp 3.14.0 → 3.15.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/CHANGELOG.md +28 -0
- package/README.md +32 -3
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/skills/headless/steps/01-check-state/SKILL.md +3 -3
- package/src/core/runtime.js +51 -1
- package/src/core/runtime.ts +51 -1
- package/src/core/skills.js +3 -3
- package/src/core/skills.ts +3 -3
- package/src/core/tools/all.js +107 -2
- package/src/core/tools/all.ts +107 -2
- package/src/core/tools/hosting.js +107 -2
- package/src/core/tools/hosting.ts +107 -2
- package/src/servers/agency-hosting.js +1 -1
- package/src/servers/agency-hosting.ts +1 -1
- package/src/servers/agent-readiness.js +1 -1
- package/src/servers/agent-readiness.ts +1 -1
- package/src/servers/all.js +1 -1
- package/src/servers/all.ts +1 -1
- package/src/servers/billing.js +1 -1
- package/src/servers/billing.ts +1 -1
- package/src/servers/dns.js +1 -1
- package/src/servers/dns.ts +1 -1
- package/src/servers/domains.js +1 -1
- package/src/servers/domains.ts +1 -1
- package/src/servers/ecommerce.js +1 -1
- package/src/servers/ecommerce.ts +1 -1
- package/src/servers/horizons.js +1 -1
- package/src/servers/horizons.ts +1 -1
- package/src/servers/hosting.js +1 -1
- package/src/servers/hosting.ts +1 -1
- package/src/servers/mail.js +1 -1
- package/src/servers/mail.ts +1 -1
- package/src/servers/reach.js +1 -1
- package/src/servers/reach.ts +1 -1
- package/src/servers/vps.js +1 -1
- package/src/servers/vps.ts +1 -1
- package/src/servers/wordpress.js +1 -1
- package/src/servers/wordpress.ts +1 -1
- package/types.d.ts +54 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,34 @@ Generated at release time from the diff between the previous and current
|
|
|
4
4
|
build. Tool changes are listed individually; everything else is summarised
|
|
5
5
|
by area.
|
|
6
6
|
|
|
7
|
+
## v3.15.0 — 2026-10-27
|
|
8
|
+
|
|
9
|
+
### Operations
|
|
10
|
+
|
|
11
|
+
- Added `hosting_websites_trigger-event` — Trigger website event
|
|
12
|
+
|
|
13
|
+
### Also in this release
|
|
14
|
+
|
|
15
|
+
- Documentation: `README.md`
|
|
16
|
+
- Bundled agent skills: `skills/headless/steps/01-check-state/SKILL.md`
|
|
17
|
+
- Request handling and authentication: `src/core/runtime.js`, `src/core/runtime.ts`
|
|
18
|
+
- Other files: `src/core/skills.js`, `src/core/skills.ts`
|
|
19
|
+
- Build and packaging: `types.d.ts`
|
|
20
|
+
|
|
21
|
+
## v3.14.1 — 2026-10-27
|
|
22
|
+
|
|
23
|
+
### Operations
|
|
24
|
+
|
|
25
|
+
- Added `hosting_cache_status` — Get cache status
|
|
26
|
+
- Changed the description of `hosting_cache_toggle-cacheless`
|
|
27
|
+
- Changed the description of `hosting_cache_toggle-website`
|
|
28
|
+
|
|
29
|
+
### Also in this release
|
|
30
|
+
|
|
31
|
+
- Documentation: `README.md`
|
|
32
|
+
- Request handling and authentication: `src/core/runtime.js`, `src/core/runtime.ts`
|
|
33
|
+
- Build and packaging: `types.d.ts`
|
|
34
|
+
|
|
7
35
|
## v3.14.0 — 2026-10-27
|
|
8
36
|
|
|
9
37
|
### Also in this release
|
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ pnpm update -g @hostinger/mcp
|
|
|
69
69
|
|
|
70
70
|
This package installs the following MCP server commands:
|
|
71
71
|
|
|
72
|
-
- `hostinger-api-mcp` — unified server over every operation (
|
|
72
|
+
- `hostinger-api-mcp` — unified server over every operation (418 total)
|
|
73
73
|
- `hostinger-agency-hosting-mcp` — 42 operations for agency-hosting
|
|
74
74
|
- `hostinger-agent-readiness-mcp` — 3 operations for agent-readiness
|
|
75
75
|
- `hostinger-billing-mcp` — 9 operations for billing
|
|
@@ -77,7 +77,7 @@ This package installs the following MCP server commands:
|
|
|
77
77
|
- `hostinger-domains-mcp` — 42 operations for domains
|
|
78
78
|
- `hostinger-ecommerce-mcp` — 29 operations for ecommerce
|
|
79
79
|
- `hostinger-horizons-mcp` — 6 operations for horizons
|
|
80
|
-
- `hostinger-hosting-mcp` —
|
|
80
|
+
- `hostinger-hosting-mcp` — 68 operations for hosting
|
|
81
81
|
- `hostinger-mail-mcp` — 38 operations for mail
|
|
82
82
|
- `hostinger-reach-mcp` — 69 operations for reach
|
|
83
83
|
- `hostinger-vps-mcp` — 67 operations for vps
|
|
@@ -1828,6 +1828,13 @@ Check deployment status, build status, build logs and why a build failed (failur
|
|
|
1828
1828
|
- **Method**: `custom`
|
|
1829
1829
|
- **Path**: `custom`
|
|
1830
1830
|
|
|
1831
|
+
#### hosting_websites_trigger-event
|
|
1832
|
+
|
|
1833
|
+
Tell Hostinger that something happened on this website, so Hostinger services such as hPanel can react to it. `event.name` picks the event and decides which `event.params` it takes. The call changes nothing on the website.
|
|
1834
|
+
|
|
1835
|
+
- **Method**: `custom`
|
|
1836
|
+
- **Path**: `custom`
|
|
1837
|
+
|
|
1831
1838
|
#### hosting_cache_clear-website
|
|
1832
1839
|
|
|
1833
1840
|
Permanently clears all server-side cache for the website at once. Use it when content was
|
|
@@ -1840,6 +1847,24 @@ installation living in a subdirectory, pass the directory query parameter to cle
|
|
|
1840
1847
|
- **Method**: `DELETE`
|
|
1841
1848
|
- **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cache/clear`
|
|
1842
1849
|
|
|
1850
|
+
#### hosting_cache_status
|
|
1851
|
+
|
|
1852
|
+
Returns the caching state of the website: whether server-side caching is enabled and whether
|
|
1853
|
+
development (cacheless) mode is on. Works for the main domain, addon websites, parked domains
|
|
1854
|
+
and subdomains of the account; each reports its own settings and does not inherit them from
|
|
1855
|
+
its parent website.
|
|
1856
|
+
|
|
1857
|
+
`is_enabled` is the setting changed by `Toggle website cache` and reflects a toggle
|
|
1858
|
+
immediately. `is_cacheless_mode_enabled` is true while development mode is on; caching is then
|
|
1859
|
+
bypassed even when `is_enabled` is true. `Toggle cacheless mode` is applied in the background,
|
|
1860
|
+
so this flag can take a few minutes to follow it.
|
|
1861
|
+
|
|
1862
|
+
The domain must be the exact website name as listed on the account, without a `www.` prefix.
|
|
1863
|
+
Returns 404 when the domain is not a website on the account.
|
|
1864
|
+
|
|
1865
|
+
- **Method**: `GET`
|
|
1866
|
+
- **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cache/status`
|
|
1867
|
+
|
|
1843
1868
|
#### hosting_cache_toggle-cacheless
|
|
1844
1869
|
|
|
1845
1870
|
Turns development (cacheless) mode on or off, based on the enabled flag. When enabled, nothing
|
|
@@ -1847,6 +1872,9 @@ is cached, effectively turning off all caching for the website; use it while act
|
|
|
1847
1872
|
testing changes, debugging issues, or when real-time updates must be visible. Disable it after
|
|
1848
1873
|
finishing development work to restore the performance benefits of caching.
|
|
1849
1874
|
|
|
1875
|
+
The change is applied in the background and can take a few minutes. Use `Get cache status` to
|
|
1876
|
+
check the current state.
|
|
1877
|
+
|
|
1850
1878
|
- **Method**: `PATCH`
|
|
1851
1879
|
- **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cacheless-mode/toggle`
|
|
1852
1880
|
|
|
@@ -1857,7 +1885,8 @@ faster page loads, reduced server load, and improved user experience; recommende
|
|
|
1857
1885
|
websites. Disabling may impact performance; to temporarily bypass caching while developing or
|
|
1858
1886
|
debugging, prefer toggling cacheless mode instead.
|
|
1859
1887
|
|
|
1860
|
-
Does nothing if caching is already in the requested state.
|
|
1888
|
+
Does nothing if caching is already in the requested state. Use `Get cache status` to check the
|
|
1889
|
+
current state.
|
|
1861
1890
|
|
|
1862
1891
|
- **Method**: `PATCH`
|
|
1863
1892
|
- **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cache/toggle`
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/hostinger/api-mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "3.
|
|
9
|
+
"version": "3.15.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@hostinger/mcp",
|
|
14
|
-
"version": "3.
|
|
14
|
+
"version": "3.15.0",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|
|
@@ -12,7 +12,7 @@ account can build. Your job here is to
|
|
|
12
12
|
This step owns all resume/position logic — no other stage second-guesses it.
|
|
13
13
|
|
|
14
14
|
Nothing in this step creates, provisions, deploys, or deletes anything. It reads and guides. Its
|
|
15
|
-
only writes to Hostinger are
|
|
15
|
+
only writes to Hostinger are unsent build reports (Step 0) and the tool-connected event (Step 3).
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -113,11 +113,11 @@ Query the Hostinger connector — the local files are never trusted on their own
|
|
|
113
113
|
(case-insensitive) and ignore the rest. No exact row ⇒ the domain is free. An exact row ⇒ the site
|
|
114
114
|
exists; note its `website_type` (`headless`, `wordpress`, `nodejs`, …) and `username`.
|
|
115
115
|
- **Tell hPanel the tool connected.** As soon as you have the exact row, call
|
|
116
|
-
`
|
|
116
|
+
`hosting_websites_trigger-event { "username": "<row username>", "domain": "<domain>", "event": { "name": "headless_onboarding.tool.connected", "params": { "tool": "<slug>" } } }`
|
|
117
117
|
once, where `<slug>` is the onboarding slug (see *State and artifacts* in the top-level `SKILL.md`).
|
|
118
118
|
This flips hPanel's onboarding card to "connected". Don't ask first and don't mention it. Skip the
|
|
119
119
|
call when there's no exact row or your tool has no onboarding slug. If
|
|
120
|
-
`
|
|
120
|
+
`hosting_websites_trigger-event` isn't in your connector, or the call returns an error,
|
|
121
121
|
ignore it: no retry, nothing said to the user, and the run carries on unchanged.
|
|
122
122
|
- **How far did it get?** If the site exists, check its setup via
|
|
123
123
|
`hosting_websites_list-setups { "domain": "<domain>" }` (exact-match the row the same way):
|
package/src/core/runtime.js
CHANGED
|
@@ -66,7 +66,7 @@ const GetSkillRequestSchema = z.object({
|
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
* MCP Server for Hostinger API
|
|
69
|
-
* Generated from OpenAPI spec version 2.4.
|
|
69
|
+
* Generated from OpenAPI spec version 2.4.3
|
|
70
70
|
*/
|
|
71
71
|
class MCPServer {
|
|
72
72
|
constructor({ name, version, tools, instructions, skills = [] }) {
|
|
@@ -316,6 +316,8 @@ class MCPServer {
|
|
|
316
316
|
return await this.handleListJavascriptDeployments(params);
|
|
317
317
|
case 'hosting_show-js-deployment-logs':
|
|
318
318
|
return await this.handleShowJsDeploymentLogs(params);
|
|
319
|
+
case 'hosting_websites_trigger-event':
|
|
320
|
+
return await this.handleHostingTriggerWebsiteEvent(params);
|
|
319
321
|
case 'agency-hosting_deploy-node-static-website':
|
|
320
322
|
return await this.handleNodeStaticDeploy(params);
|
|
321
323
|
case 'agency-hosting_deploy-php-application':
|
|
@@ -2782,6 +2784,54 @@ class MCPServer {
|
|
|
2782
2784
|
};
|
|
2783
2785
|
}
|
|
2784
2786
|
|
|
2787
|
+
async handleHostingTriggerWebsiteEvent(params) {
|
|
2788
|
+
const { username, domain, event } = params;
|
|
2789
|
+
const baseUrl = this.baseUrl.endsWith("/") ? this.baseUrl : `${this.baseUrl}/`;
|
|
2790
|
+
const url = new URL(`api/hosting/v1/accounts/${encodeURIComponent(String(username))}/websites/${encodeURIComponent(String(domain))}/events/trigger`, baseUrl).toString();
|
|
2791
|
+
|
|
2792
|
+
try {
|
|
2793
|
+
const bearerToken = await this.getAuthToken();
|
|
2794
|
+
|
|
2795
|
+
const config = {
|
|
2796
|
+
method: 'post',
|
|
2797
|
+
url,
|
|
2798
|
+
headers: {
|
|
2799
|
+
...this.headers,
|
|
2800
|
+
'Authorization': `Bearer ${bearerToken}`,
|
|
2801
|
+
'Content-Type': 'application/json'
|
|
2802
|
+
},
|
|
2803
|
+
data: { event },
|
|
2804
|
+
timeout: 60000, // 60s
|
|
2805
|
+
validateStatus: function (status) {
|
|
2806
|
+
return status < 500;
|
|
2807
|
+
}
|
|
2808
|
+
};
|
|
2809
|
+
|
|
2810
|
+
const response = await axios(config);
|
|
2811
|
+
|
|
2812
|
+
if (response.status < 200 || response.status >= 300) {
|
|
2813
|
+
throw new ApiExecutionError(response.status, response.data);
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
return response.data;
|
|
2817
|
+
|
|
2818
|
+
} catch (error) {
|
|
2819
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2820
|
+
this.log('error', `Failed to trigger website event: ${errorMessage}`);
|
|
2821
|
+
|
|
2822
|
+
if (axios.isAxiosError(error)) {
|
|
2823
|
+
const responseData = error.response?.data;
|
|
2824
|
+
const responseStatus = error.response?.status;
|
|
2825
|
+
this.log('error', 'API Error Details:', {
|
|
2826
|
+
status: responseStatus,
|
|
2827
|
+
data: typeof responseData === 'object' ? JSON.stringify(responseData) : responseData
|
|
2828
|
+
});
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2831
|
+
throw error;
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2785
2835
|
agencyHosting_normalizePath(pathString) {
|
|
2786
2836
|
return pathString.replace(/\\/g, '/');
|
|
2787
2837
|
}
|
package/src/core/runtime.ts
CHANGED
|
@@ -97,7 +97,7 @@ interface Skill { uri: string; frontmatter: Record<string, unknown>; resources:
|
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* MCP Server for Hostinger API
|
|
100
|
-
* Generated from OpenAPI spec version 2.4.
|
|
100
|
+
* Generated from OpenAPI spec version 2.4.3
|
|
101
101
|
*/
|
|
102
102
|
class MCPServer {
|
|
103
103
|
private readonly name: string;
|
|
@@ -347,6 +347,8 @@ class MCPServer {
|
|
|
347
347
|
return await this.handleListJavascriptDeployments(params);
|
|
348
348
|
case 'hosting_show-js-deployment-logs':
|
|
349
349
|
return await this.handleShowJsDeploymentLogs(params);
|
|
350
|
+
case 'hosting_websites_trigger-event':
|
|
351
|
+
return await this.handleHostingTriggerWebsiteEvent(params);
|
|
350
352
|
case 'agency-hosting_deploy-node-static-website':
|
|
351
353
|
return await this.handleNodeStaticDeploy(params);
|
|
352
354
|
case 'agency-hosting_deploy-php-application':
|
|
@@ -2819,6 +2821,54 @@ class MCPServer {
|
|
|
2819
2821
|
};
|
|
2820
2822
|
}
|
|
2821
2823
|
|
|
2824
|
+
private async handleHostingTriggerWebsiteEvent(params: Record<string, unknown>): Promise<unknown> {
|
|
2825
|
+
const { username, domain, event } = params;
|
|
2826
|
+
const baseUrl = this.baseUrl.endsWith("/") ? this.baseUrl : `${this.baseUrl}/`;
|
|
2827
|
+
const url = new URL(`api/hosting/v1/accounts/${encodeURIComponent(String(username))}/websites/${encodeURIComponent(String(domain))}/events/trigger`, baseUrl).toString();
|
|
2828
|
+
|
|
2829
|
+
try {
|
|
2830
|
+
const bearerToken = await this.getAuthToken();
|
|
2831
|
+
|
|
2832
|
+
const config: AxiosRequestConfig = {
|
|
2833
|
+
method: 'post',
|
|
2834
|
+
url,
|
|
2835
|
+
headers: {
|
|
2836
|
+
...this.headers,
|
|
2837
|
+
'Authorization': `Bearer ${bearerToken}`,
|
|
2838
|
+
'Content-Type': 'application/json'
|
|
2839
|
+
},
|
|
2840
|
+
data: { event },
|
|
2841
|
+
timeout: 60000, // 60s
|
|
2842
|
+
validateStatus: function (status: number): boolean {
|
|
2843
|
+
return status < 500;
|
|
2844
|
+
}
|
|
2845
|
+
};
|
|
2846
|
+
|
|
2847
|
+
const response = await axios(config);
|
|
2848
|
+
|
|
2849
|
+
if (response.status < 200 || response.status >= 300) {
|
|
2850
|
+
throw new ApiExecutionError(response.status, response.data);
|
|
2851
|
+
}
|
|
2852
|
+
|
|
2853
|
+
return response.data;
|
|
2854
|
+
|
|
2855
|
+
} catch (error) {
|
|
2856
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2857
|
+
this.log('error', `Failed to trigger website event: ${errorMessage}`);
|
|
2858
|
+
|
|
2859
|
+
if (axios.isAxiosError(error)) {
|
|
2860
|
+
const responseData = error.response?.data;
|
|
2861
|
+
const responseStatus = error.response?.status;
|
|
2862
|
+
this.log('error', 'API Error Details:', {
|
|
2863
|
+
status: responseStatus,
|
|
2864
|
+
data: typeof responseData === 'object' ? JSON.stringify(responseData) : responseData
|
|
2865
|
+
});
|
|
2866
|
+
}
|
|
2867
|
+
|
|
2868
|
+
throw error;
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
|
|
2822
2872
|
private agencyHosting_normalizePath(pathString: string): string {
|
|
2823
2873
|
return pathString.replace(/\\/g, '/');
|
|
2824
2874
|
}
|
package/src/core/skills.js
CHANGED
|
@@ -134,10 +134,10 @@ export default [
|
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
136
|
"uri": "skill://hostinger-headless/steps/01-check-state/SKILL.md",
|
|
137
|
-
"digest": "sha256:
|
|
138
|
-
"size":
|
|
137
|
+
"digest": "sha256:043f25855abf92f43728b6e442bbd8d580fd2a6bb0270cfa7ed95dd41050ee60",
|
|
138
|
+
"size": 13227,
|
|
139
139
|
"mimeType": "text/markdown",
|
|
140
|
-
"text": "---\nname: headless-step-check-state\ndescription: \"First build step of the Hostinger Headless flow, run right after connect. Works out where a given domain's build stands — is a run already in progress, does the site already exist, how far did it get — by reconciling the global workspace state under ~/.hostinger/<domain>/ with what the Hostinger connector reports, then guides the user to continue, switch or buy a domain, or start over. Owns all resume/position logic for the flow.\"\n---\n\n# headless-step-check-state\n\nThe first build step of the Hostinger Headless flow (orchestrated by `hostinger.com/headless/skill.md`),\nrun right after connect. Connect has already connected the Hostinger connector and confirmed the\naccount can build. Your job here is to\n**figure out where this domain stands and agree the route with the user** before any new work begins.\nThis step owns all resume/position logic — no other stage second-guesses it.\n\nNothing in this step creates, provisions, deploys, or deletes anything. It reads and guides. Its\nonly writes to Hostinger are reports: unsent build reports (Step 0) and the connected tool (Step 3).\n\n---\n\n## Where state lives\n\nEverything for a domain lives under the global site workspace **`~/.hostinger/<domain>/`** — one\ndirectory per domain, under the user's home (`~` = `$HOME`), **not** the current working directory.\nThe directory name **is** the domain, so `state.json` inside does not store it. Because it's global,\nthis domain's build is resumable from any directory.\n\n`state.json` shape (`stage` is the *next* stage to run; `provision` is the background task's status,\npresent only once provision has fired):\n\n```json\n{ \"tool\": \"claude-code\", \"stage\": \"content_model\",\n \"provision\": { \"status\": \"in_progress\", \"domain\": \"<domain>\", \"started_at\": \"…\" },\n \"updated_at\": \"…\" }\n```\n\n`provision.status` is `in_progress` or `completed` — but it is a **hint**: always re-verify it against\n`hosting_websites_list-setups` (Step 1) before trusting it to gate an instance-barrier step.\n\n---\n\n## Step 0 — Start the run log\n\nBefore anything else, start a run and the stage (see *Run log and build report* in the top-level\n`SKILL.md`):\n\n```bash\nnode <skill>/run-log.mjs <domain> run-start --tool <tool> --model <model> --skill <skill version>\nnode <skill>/run-log.mjs <domain> stage-start check_state\n```\n\nIf an earlier run on this domain never wrote its report, `run-start` closes it as `abandoned` first.\n\nThen send any build reports that haven't reached Hostinger yet (that abandoned run, or a send that\nfailed last time):\n\n```bash\nnode <skill>/run-log.mjs <domain> unsent\n```\n\nEach line is `<run> <path>`. For each, send the file through `hosting_headless_submit-build-report`\nand record the result, as described in *Run log and build report* in the top-level `SKILL.md`. One\ntry each. Don't ask first; if any went out, say so in one line (e.g. \"Sent 1 earlier build report to\nHostinger.\"). Don't let a failure hold up this step.\nCheck-state runs once per session. A follow-up after the final report, in the same session, doesn't\ncome back here: it calls `run-resume` (see *Run log and build report* in the top-level `SKILL.md`).\n\n## Step 1 — Is a build actively running right now? (check this before anything else)\n\nKeep two things separate, and **never guess from a timestamp.**\n\n- **A platform build actively in progress** — the only *reliable* \"running now\" signal. Check\n `hosting_websites_list-setups { \"domain\": \"<domain>\" }` and exact-match the domain row:\n - `status: running` → provisioning is underway **right now** (a background provision from an earlier\n turn). Don't start a second one — reconcile `state.json`'s `provision` to `in_progress`, and\n either resume prepare work while it finishes or poll it to `completed` at the barrier.\n - `status: failed` → not running; route to provision to self-heal (Step 3).\n - `completed` → provision is done; set `provision.status` to `completed`. Instance-barrier steps\n (content push, frontend data, deploy) are now unblocked.\n - no row → not provisioned yet; carry on.\n\n This check **is** the source of truth for `provision.status`: a stored `in_progress`/`completed` in\n `state.json` is only a hint until this reconciles it.\n\n- **A `.lock`** — `~/.hostinger/<domain>/.lock`. It only tells you *a previous run\n touched this domain*. **Do not judge it by age** — a 2-minute-old lock and a 3-year-old lock get the\n same treatment, and a lock on its own is **not** a reason to interrupt the user. Carry it into Step 5:\n if there's nothing to resume (new build), silently take it over; only if there's real state to resume\n do you also ask *is another Claude window building this domain right now?* (yes → stop; no → take\n over).\n\nOnce you're actively working this domain, **acquire/refresh the lock** (write the current timestamp),\nand **release it on a clean stop** (Step 6). The lock marks an active session, nothing more.\n\n---\n\n## Step 2 — Read the workspace directory\n\nCheck `~/.hostinger/<domain>/` by its exact path (for example `test -d ~/.hostinger/<domain>`), not\nby listing `~/.hostinger/`:\n\n- **Absent** → no history for this domain in the workspace.\n- **Present** → read `state.json` (its `stage`) and whatever artifacts exist (`brief.md`,\n `site.json`, …). Treat these as a hint, not the truth.\n\n---\n\n## Step 3 — Verify against reality (reality wins)\n\nQuery the Hostinger connector — the local files are never trusted on their own:\n\n- **Does the site exist?** `hosting_websites_list { \"domain\": \"<domain>\" }`. ⚠️ This filter is a\n **case-insensitive substring match**, not exact — so `test.com` would also return\n `shop.test.com`. **Compare each returned row's `domain` to your target for an *exact* match**\n (case-insensitive) and ignore the rest. No exact row ⇒ the domain is free. An exact row ⇒ the site\n exists; note its `website_type` (`headless`, `wordpress`, `nodejs`, …) and `username`.\n- **Tell hPanel the tool connected.** As soon as you have the exact row, call\n `hosting_headless_report-tool-connected { \"username\": \"<row username>\", \"domain\": \"<domain>\", \"tool\": \"<slug>\" }`\n once, where `<slug>` is the onboarding slug (see *State and artifacts* in the top-level `SKILL.md`).\n This flips hPanel's onboarding card to \"connected\". Don't ask first and don't mention it. Skip the\n call when there's no exact row or your tool has no onboarding slug. If\n `hosting_headless_report-tool-connected` isn't in your connector, or the call returns an error,\n ignore it: no retry, nothing said to the user, and the run carries on unchanged.\n- **How far did it get?** If the site exists, check its setup via\n `hosting_websites_list-setups { \"domain\": \"<domain>\" }` (exact-match the row the same way):\n - `status: completed` → provisioned; then, depending on backend, check whether a build has succeeded.\n - `status: running` → still provisioning (see Step 1).\n - `status: failed` → provisioning stopped before finishing → route to **provision** to self-heal.\n- **Is it an empty headless shell from onboarding?** A `headless` site whose setup is `completed` is\n **not necessarily finished** — onboarding now creates the website *before* the build runs, as an\n **empty headless shell** (`hosting_websites_start-setup { type: \"headless_empty\" }`): `website_type`\n is `headless` but **no backend is installed** (no WordPress at `/cms`, no store). Tell a shell from a\n real backend the same way provision does: within 24 h the setup `type` is `headless_empty`; otherwise\n `wordpress_installations_list { username, domain, ownership: \"all\" }` returns **no** `/cms` row and\n there is no `site.json` recording a backend. An empty shell means **provision has not chosen or\n installed a backend yet** — this is a **new build** that happens to already own its website, not a\n finished or resumable one. Route it to **refine** (choose the backend), then **provision** adopts the\n shell and swaps it to that backend (see the provision router's *Onboarding handoff*). Never create a\n second site, and never skip provision for it.\n\nReconcile with the local state. **When they disagree, reality wins** and the local `stage` is\ncorrected.\n\n---\n\n## Step 4 — Determine the position\n\nConnect always writes `state.json` (with `stage: check_state`) before this step runs, so local\nstate is never truly empty. **\"Local state: none\" here means only connect artifacts exist** —\n`connect.json` + a `state.json` still pointing at `check_state`/`refine`, and **no build artifacts\nyet** (`brief.md`, `site.json`, …).\n\n| Local state | Reality (domain) | Position |\n|---|---|---|\n| none (connect only) | free | **new build** — start from refine |\n| none (connect only) | empty headless shell (onboarding) | **new build on an existing shell** — start from refine; provision adopts the shell and swaps it to the chosen backend. Never create a second site, never skip provision |\n| none (connect only) | site exists with a real backend | **adopt / resume** — never create a second site; route to the first unfinished stage |\n| build artifacts present, incomplete | matches | **resume** at `state.json`'s `stage` |\n| build artifacts present | disagrees | **reality wins** — recompute the stage from what actually exists |\n| build artifacts present, all done | live site exists | **finished** — this is now an *iterate* request, not a build |\n\n---\n\n## Step 5 — Guide the user\n\nThe question to ask depends on whether there is actually **something to resume** — i.e. **build\nartifacts** (`brief.md`, `site.json`, …) or a **live site** for this domain. A stray `.lock` or\nconnect-only files are *not* something to resume.\n\n- **New build** (no build artifacts and either the domain is free **or** it holds only an empty\n headless shell from onboarding) → just proceed to refine. **Don't ask resume vs start over** —\n there's nothing to resume; both would land in the same place. An empty headless shell is not\n \"something to resume\": it has no backend and no content yet, so it's a fresh build that already owns\n its website — provision will adopt and swap it. Mention it in one line (\"Using the headless site\n onboarding already created for this domain.\"). If a leftover `.lock` is lying around, silently take\n it over and continue (optionally mention it in one line).\n- **Something to resume** (build artifacts exist, or a site exists for the domain **with a real backend\n installed** — WordPress at `/cms`, a store, or a deployed app) → tell the user plainly what's there\n and **ask them to choose**, regardless of how old it is (don't guess from timestamps):\n\n- **Resume** — pick up at the computed stage. (If a `.lock` is present in this case, also confirm no\n other window is actively building this domain right now.)\n- **Start over / redo a step** — only safe **before anything is provisioned**. If the site is already\n provisioned or live, you **cannot** re-create it: that is forward-only *iterate* (change content or\n design and redeploy), not a fresh build. Never re-provision or overwrite a live site; if the user\n insists on a clean slate for a live domain, explain the limitation and point them at hPanel.\n- **Switch domain** — they want a different domain. A new domain is a **new workspace**\n (`~/.hostinger/<other-domain>/`, with its own `src/`). Hand off to start that domain's run.\n- **Buy a domain** — they want a custom domain instead of the temporary one. Route to the domain\n purchase / `connect-domain` flow, then continue with the chosen domain.\n\nWhen the intent is ambiguous, **ask** — don't guess. A skipped tool result is ambiguous; see\n*When you ask the user* in the top-level `SKILL.md`.\n\n---\n\n## Step 6 — Record and route\n\nWrite `~/.hostinger/<domain>/state.json` with the agreed next `stage` and a fresh timestamp. If the\nroute isn't a new build, record it with `run-log.mjs <domain> run-update --kind resume` (or\n`redesign` / `iterate`), then end the stage with `stage-end check_state ok --note \"<the route>\"`.\nThen:\n\n- **Handing straight to the next stage in this same session?** Keep the `.lock` (you are still\n actively running) and continue.\n- **Stopping and returning control to the user?** (e.g. the next stage isn't built yet, or you are\n waiting on them.) **Delete the `.lock`** — the session is no longer active, and a leftover lock just\n forces an unnecessary \"is another window running?\" question on the next run. Always release the lock\n on a clean stop; it exists only to mark an actively-running session. A stop is still the end of a\n run: give the final report and save the build report (`09-done`).\n\n---\n\n## Invariants\n\n- **One directory per domain.** The domain is the key; state files never repeat it.\n- **Only this domain's workspace.** Never list `~/.hostinger/` or open another site's workspace (see\n *State and artifacts* in the top-level `SKILL.md`).\n- **Never create a second site** on a domain that already has one.\n- **Never re-provision or overwrite a live site.** Recovery is forward-only.\n- **Reality beats local state**, always.\n- **When ambiguous, ask.**\n"
|
|
140
|
+
"text": "---\nname: headless-step-check-state\ndescription: \"First build step of the Hostinger Headless flow, run right after connect. Works out where a given domain's build stands — is a run already in progress, does the site already exist, how far did it get — by reconciling the global workspace state under ~/.hostinger/<domain>/ with what the Hostinger connector reports, then guides the user to continue, switch or buy a domain, or start over. Owns all resume/position logic for the flow.\"\n---\n\n# headless-step-check-state\n\nThe first build step of the Hostinger Headless flow (orchestrated by `hostinger.com/headless/skill.md`),\nrun right after connect. Connect has already connected the Hostinger connector and confirmed the\naccount can build. Your job here is to\n**figure out where this domain stands and agree the route with the user** before any new work begins.\nThis step owns all resume/position logic — no other stage second-guesses it.\n\nNothing in this step creates, provisions, deploys, or deletes anything. It reads and guides. Its\nonly writes to Hostinger are unsent build reports (Step 0) and the tool-connected event (Step 3).\n\n---\n\n## Where state lives\n\nEverything for a domain lives under the global site workspace **`~/.hostinger/<domain>/`** — one\ndirectory per domain, under the user's home (`~` = `$HOME`), **not** the current working directory.\nThe directory name **is** the domain, so `state.json` inside does not store it. Because it's global,\nthis domain's build is resumable from any directory.\n\n`state.json` shape (`stage` is the *next* stage to run; `provision` is the background task's status,\npresent only once provision has fired):\n\n```json\n{ \"tool\": \"claude-code\", \"stage\": \"content_model\",\n \"provision\": { \"status\": \"in_progress\", \"domain\": \"<domain>\", \"started_at\": \"…\" },\n \"updated_at\": \"…\" }\n```\n\n`provision.status` is `in_progress` or `completed` — but it is a **hint**: always re-verify it against\n`hosting_websites_list-setups` (Step 1) before trusting it to gate an instance-barrier step.\n\n---\n\n## Step 0 — Start the run log\n\nBefore anything else, start a run and the stage (see *Run log and build report* in the top-level\n`SKILL.md`):\n\n```bash\nnode <skill>/run-log.mjs <domain> run-start --tool <tool> --model <model> --skill <skill version>\nnode <skill>/run-log.mjs <domain> stage-start check_state\n```\n\nIf an earlier run on this domain never wrote its report, `run-start` closes it as `abandoned` first.\n\nThen send any build reports that haven't reached Hostinger yet (that abandoned run, or a send that\nfailed last time):\n\n```bash\nnode <skill>/run-log.mjs <domain> unsent\n```\n\nEach line is `<run> <path>`. For each, send the file through `hosting_headless_submit-build-report`\nand record the result, as described in *Run log and build report* in the top-level `SKILL.md`. One\ntry each. Don't ask first; if any went out, say so in one line (e.g. \"Sent 1 earlier build report to\nHostinger.\"). Don't let a failure hold up this step.\nCheck-state runs once per session. A follow-up after the final report, in the same session, doesn't\ncome back here: it calls `run-resume` (see *Run log and build report* in the top-level `SKILL.md`).\n\n## Step 1 — Is a build actively running right now? (check this before anything else)\n\nKeep two things separate, and **never guess from a timestamp.**\n\n- **A platform build actively in progress** — the only *reliable* \"running now\" signal. Check\n `hosting_websites_list-setups { \"domain\": \"<domain>\" }` and exact-match the domain row:\n - `status: running` → provisioning is underway **right now** (a background provision from an earlier\n turn). Don't start a second one — reconcile `state.json`'s `provision` to `in_progress`, and\n either resume prepare work while it finishes or poll it to `completed` at the barrier.\n - `status: failed` → not running; route to provision to self-heal (Step 3).\n - `completed` → provision is done; set `provision.status` to `completed`. Instance-barrier steps\n (content push, frontend data, deploy) are now unblocked.\n - no row → not provisioned yet; carry on.\n\n This check **is** the source of truth for `provision.status`: a stored `in_progress`/`completed` in\n `state.json` is only a hint until this reconciles it.\n\n- **A `.lock`** — `~/.hostinger/<domain>/.lock`. It only tells you *a previous run\n touched this domain*. **Do not judge it by age** — a 2-minute-old lock and a 3-year-old lock get the\n same treatment, and a lock on its own is **not** a reason to interrupt the user. Carry it into Step 5:\n if there's nothing to resume (new build), silently take it over; only if there's real state to resume\n do you also ask *is another Claude window building this domain right now?* (yes → stop; no → take\n over).\n\nOnce you're actively working this domain, **acquire/refresh the lock** (write the current timestamp),\nand **release it on a clean stop** (Step 6). The lock marks an active session, nothing more.\n\n---\n\n## Step 2 — Read the workspace directory\n\nCheck `~/.hostinger/<domain>/` by its exact path (for example `test -d ~/.hostinger/<domain>`), not\nby listing `~/.hostinger/`:\n\n- **Absent** → no history for this domain in the workspace.\n- **Present** → read `state.json` (its `stage`) and whatever artifacts exist (`brief.md`,\n `site.json`, …). Treat these as a hint, not the truth.\n\n---\n\n## Step 3 — Verify against reality (reality wins)\n\nQuery the Hostinger connector — the local files are never trusted on their own:\n\n- **Does the site exist?** `hosting_websites_list { \"domain\": \"<domain>\" }`. ⚠️ This filter is a\n **case-insensitive substring match**, not exact — so `test.com` would also return\n `shop.test.com`. **Compare each returned row's `domain` to your target for an *exact* match**\n (case-insensitive) and ignore the rest. No exact row ⇒ the domain is free. An exact row ⇒ the site\n exists; note its `website_type` (`headless`, `wordpress`, `nodejs`, …) and `username`.\n- **Tell hPanel the tool connected.** As soon as you have the exact row, call\n `hosting_websites_trigger-event { \"username\": \"<row username>\", \"domain\": \"<domain>\", \"event\": { \"name\": \"headless_onboarding.tool.connected\", \"params\": { \"tool\": \"<slug>\" } } }`\n once, where `<slug>` is the onboarding slug (see *State and artifacts* in the top-level `SKILL.md`).\n This flips hPanel's onboarding card to \"connected\". Don't ask first and don't mention it. Skip the\n call when there's no exact row or your tool has no onboarding slug. If\n `hosting_websites_trigger-event` isn't in your connector, or the call returns an error,\n ignore it: no retry, nothing said to the user, and the run carries on unchanged.\n- **How far did it get?** If the site exists, check its setup via\n `hosting_websites_list-setups { \"domain\": \"<domain>\" }` (exact-match the row the same way):\n - `status: completed` → provisioned; then, depending on backend, check whether a build has succeeded.\n - `status: running` → still provisioning (see Step 1).\n - `status: failed` → provisioning stopped before finishing → route to **provision** to self-heal.\n- **Is it an empty headless shell from onboarding?** A `headless` site whose setup is `completed` is\n **not necessarily finished** — onboarding now creates the website *before* the build runs, as an\n **empty headless shell** (`hosting_websites_start-setup { type: \"headless_empty\" }`): `website_type`\n is `headless` but **no backend is installed** (no WordPress at `/cms`, no store). Tell a shell from a\n real backend the same way provision does: within 24 h the setup `type` is `headless_empty`; otherwise\n `wordpress_installations_list { username, domain, ownership: \"all\" }` returns **no** `/cms` row and\n there is no `site.json` recording a backend. An empty shell means **provision has not chosen or\n installed a backend yet** — this is a **new build** that happens to already own its website, not a\n finished or resumable one. Route it to **refine** (choose the backend), then **provision** adopts the\n shell and swaps it to that backend (see the provision router's *Onboarding handoff*). Never create a\n second site, and never skip provision for it.\n\nReconcile with the local state. **When they disagree, reality wins** and the local `stage` is\ncorrected.\n\n---\n\n## Step 4 — Determine the position\n\nConnect always writes `state.json` (with `stage: check_state`) before this step runs, so local\nstate is never truly empty. **\"Local state: none\" here means only connect artifacts exist** —\n`connect.json` + a `state.json` still pointing at `check_state`/`refine`, and **no build artifacts\nyet** (`brief.md`, `site.json`, …).\n\n| Local state | Reality (domain) | Position |\n|---|---|---|\n| none (connect only) | free | **new build** — start from refine |\n| none (connect only) | empty headless shell (onboarding) | **new build on an existing shell** — start from refine; provision adopts the shell and swaps it to the chosen backend. Never create a second site, never skip provision |\n| none (connect only) | site exists with a real backend | **adopt / resume** — never create a second site; route to the first unfinished stage |\n| build artifacts present, incomplete | matches | **resume** at `state.json`'s `stage` |\n| build artifacts present | disagrees | **reality wins** — recompute the stage from what actually exists |\n| build artifacts present, all done | live site exists | **finished** — this is now an *iterate* request, not a build |\n\n---\n\n## Step 5 — Guide the user\n\nThe question to ask depends on whether there is actually **something to resume** — i.e. **build\nartifacts** (`brief.md`, `site.json`, …) or a **live site** for this domain. A stray `.lock` or\nconnect-only files are *not* something to resume.\n\n- **New build** (no build artifacts and either the domain is free **or** it holds only an empty\n headless shell from onboarding) → just proceed to refine. **Don't ask resume vs start over** —\n there's nothing to resume; both would land in the same place. An empty headless shell is not\n \"something to resume\": it has no backend and no content yet, so it's a fresh build that already owns\n its website — provision will adopt and swap it. Mention it in one line (\"Using the headless site\n onboarding already created for this domain.\"). If a leftover `.lock` is lying around, silently take\n it over and continue (optionally mention it in one line).\n- **Something to resume** (build artifacts exist, or a site exists for the domain **with a real backend\n installed** — WordPress at `/cms`, a store, or a deployed app) → tell the user plainly what's there\n and **ask them to choose**, regardless of how old it is (don't guess from timestamps):\n\n- **Resume** — pick up at the computed stage. (If a `.lock` is present in this case, also confirm no\n other window is actively building this domain right now.)\n- **Start over / redo a step** — only safe **before anything is provisioned**. If the site is already\n provisioned or live, you **cannot** re-create it: that is forward-only *iterate* (change content or\n design and redeploy), not a fresh build. Never re-provision or overwrite a live site; if the user\n insists on a clean slate for a live domain, explain the limitation and point them at hPanel.\n- **Switch domain** — they want a different domain. A new domain is a **new workspace**\n (`~/.hostinger/<other-domain>/`, with its own `src/`). Hand off to start that domain's run.\n- **Buy a domain** — they want a custom domain instead of the temporary one. Route to the domain\n purchase / `connect-domain` flow, then continue with the chosen domain.\n\nWhen the intent is ambiguous, **ask** — don't guess. A skipped tool result is ambiguous; see\n*When you ask the user* in the top-level `SKILL.md`.\n\n---\n\n## Step 6 — Record and route\n\nWrite `~/.hostinger/<domain>/state.json` with the agreed next `stage` and a fresh timestamp. If the\nroute isn't a new build, record it with `run-log.mjs <domain> run-update --kind resume` (or\n`redesign` / `iterate`), then end the stage with `stage-end check_state ok --note \"<the route>\"`.\nThen:\n\n- **Handing straight to the next stage in this same session?** Keep the `.lock` (you are still\n actively running) and continue.\n- **Stopping and returning control to the user?** (e.g. the next stage isn't built yet, or you are\n waiting on them.) **Delete the `.lock`** — the session is no longer active, and a leftover lock just\n forces an unnecessary \"is another window running?\" question on the next run. Always release the lock\n on a clean stop; it exists only to mark an actively-running session. A stop is still the end of a\n run: give the final report and save the build report (`09-done`).\n\n---\n\n## Invariants\n\n- **One directory per domain.** The domain is the key; state files never repeat it.\n- **Only this domain's workspace.** Never list `~/.hostinger/` or open another site's workspace (see\n *State and artifacts* in the top-level `SKILL.md`).\n- **Never create a second site** on a domain that already has one.\n- **Never re-provision or overwrite a live site.** Recovery is forward-only.\n- **Reality beats local state**, always.\n- **When ambiguous, ask.**\n"
|
|
141
141
|
},
|
|
142
142
|
{
|
|
143
143
|
"uri": "skill://hostinger-headless/steps/02-refine/SKILL.md",
|
package/src/core/skills.ts
CHANGED
|
@@ -148,10 +148,10 @@ const skills: Skill[] = [
|
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
150
|
"uri": "skill://hostinger-headless/steps/01-check-state/SKILL.md",
|
|
151
|
-
"digest": "sha256:
|
|
152
|
-
"size":
|
|
151
|
+
"digest": "sha256:043f25855abf92f43728b6e442bbd8d580fd2a6bb0270cfa7ed95dd41050ee60",
|
|
152
|
+
"size": 13227,
|
|
153
153
|
"mimeType": "text/markdown",
|
|
154
|
-
"text": "---\nname: headless-step-check-state\ndescription: \"First build step of the Hostinger Headless flow, run right after connect. Works out where a given domain's build stands — is a run already in progress, does the site already exist, how far did it get — by reconciling the global workspace state under ~/.hostinger/<domain>/ with what the Hostinger connector reports, then guides the user to continue, switch or buy a domain, or start over. Owns all resume/position logic for the flow.\"\n---\n\n# headless-step-check-state\n\nThe first build step of the Hostinger Headless flow (orchestrated by `hostinger.com/headless/skill.md`),\nrun right after connect. Connect has already connected the Hostinger connector and confirmed the\naccount can build. Your job here is to\n**figure out where this domain stands and agree the route with the user** before any new work begins.\nThis step owns all resume/position logic — no other stage second-guesses it.\n\nNothing in this step creates, provisions, deploys, or deletes anything. It reads and guides. Its\nonly writes to Hostinger are reports: unsent build reports (Step 0) and the connected tool (Step 3).\n\n---\n\n## Where state lives\n\nEverything for a domain lives under the global site workspace **`~/.hostinger/<domain>/`** — one\ndirectory per domain, under the user's home (`~` = `$HOME`), **not** the current working directory.\nThe directory name **is** the domain, so `state.json` inside does not store it. Because it's global,\nthis domain's build is resumable from any directory.\n\n`state.json` shape (`stage` is the *next* stage to run; `provision` is the background task's status,\npresent only once provision has fired):\n\n```json\n{ \"tool\": \"claude-code\", \"stage\": \"content_model\",\n \"provision\": { \"status\": \"in_progress\", \"domain\": \"<domain>\", \"started_at\": \"…\" },\n \"updated_at\": \"…\" }\n```\n\n`provision.status` is `in_progress` or `completed` — but it is a **hint**: always re-verify it against\n`hosting_websites_list-setups` (Step 1) before trusting it to gate an instance-barrier step.\n\n---\n\n## Step 0 — Start the run log\n\nBefore anything else, start a run and the stage (see *Run log and build report* in the top-level\n`SKILL.md`):\n\n```bash\nnode <skill>/run-log.mjs <domain> run-start --tool <tool> --model <model> --skill <skill version>\nnode <skill>/run-log.mjs <domain> stage-start check_state\n```\n\nIf an earlier run on this domain never wrote its report, `run-start` closes it as `abandoned` first.\n\nThen send any build reports that haven't reached Hostinger yet (that abandoned run, or a send that\nfailed last time):\n\n```bash\nnode <skill>/run-log.mjs <domain> unsent\n```\n\nEach line is `<run> <path>`. For each, send the file through `hosting_headless_submit-build-report`\nand record the result, as described in *Run log and build report* in the top-level `SKILL.md`. One\ntry each. Don't ask first; if any went out, say so in one line (e.g. \"Sent 1 earlier build report to\nHostinger.\"). Don't let a failure hold up this step.\nCheck-state runs once per session. A follow-up after the final report, in the same session, doesn't\ncome back here: it calls `run-resume` (see *Run log and build report* in the top-level `SKILL.md`).\n\n## Step 1 — Is a build actively running right now? (check this before anything else)\n\nKeep two things separate, and **never guess from a timestamp.**\n\n- **A platform build actively in progress** — the only *reliable* \"running now\" signal. Check\n `hosting_websites_list-setups { \"domain\": \"<domain>\" }` and exact-match the domain row:\n - `status: running` → provisioning is underway **right now** (a background provision from an earlier\n turn). Don't start a second one — reconcile `state.json`'s `provision` to `in_progress`, and\n either resume prepare work while it finishes or poll it to `completed` at the barrier.\n - `status: failed` → not running; route to provision to self-heal (Step 3).\n - `completed` → provision is done; set `provision.status` to `completed`. Instance-barrier steps\n (content push, frontend data, deploy) are now unblocked.\n - no row → not provisioned yet; carry on.\n\n This check **is** the source of truth for `provision.status`: a stored `in_progress`/`completed` in\n `state.json` is only a hint until this reconciles it.\n\n- **A `.lock`** — `~/.hostinger/<domain>/.lock`. It only tells you *a previous run\n touched this domain*. **Do not judge it by age** — a 2-minute-old lock and a 3-year-old lock get the\n same treatment, and a lock on its own is **not** a reason to interrupt the user. Carry it into Step 5:\n if there's nothing to resume (new build), silently take it over; only if there's real state to resume\n do you also ask *is another Claude window building this domain right now?* (yes → stop; no → take\n over).\n\nOnce you're actively working this domain, **acquire/refresh the lock** (write the current timestamp),\nand **release it on a clean stop** (Step 6). The lock marks an active session, nothing more.\n\n---\n\n## Step 2 — Read the workspace directory\n\nCheck `~/.hostinger/<domain>/` by its exact path (for example `test -d ~/.hostinger/<domain>`), not\nby listing `~/.hostinger/`:\n\n- **Absent** → no history for this domain in the workspace.\n- **Present** → read `state.json` (its `stage`) and whatever artifacts exist (`brief.md`,\n `site.json`, …). Treat these as a hint, not the truth.\n\n---\n\n## Step 3 — Verify against reality (reality wins)\n\nQuery the Hostinger connector — the local files are never trusted on their own:\n\n- **Does the site exist?** `hosting_websites_list { \"domain\": \"<domain>\" }`. ⚠️ This filter is a\n **case-insensitive substring match**, not exact — so `test.com` would also return\n `shop.test.com`. **Compare each returned row's `domain` to your target for an *exact* match**\n (case-insensitive) and ignore the rest. No exact row ⇒ the domain is free. An exact row ⇒ the site\n exists; note its `website_type` (`headless`, `wordpress`, `nodejs`, …) and `username`.\n- **Tell hPanel the tool connected.** As soon as you have the exact row, call\n `hosting_headless_report-tool-connected { \"username\": \"<row username>\", \"domain\": \"<domain>\", \"tool\": \"<slug>\" }`\n once, where `<slug>` is the onboarding slug (see *State and artifacts* in the top-level `SKILL.md`).\n This flips hPanel's onboarding card to \"connected\". Don't ask first and don't mention it. Skip the\n call when there's no exact row or your tool has no onboarding slug. If\n `hosting_headless_report-tool-connected` isn't in your connector, or the call returns an error,\n ignore it: no retry, nothing said to the user, and the run carries on unchanged.\n- **How far did it get?** If the site exists, check its setup via\n `hosting_websites_list-setups { \"domain\": \"<domain>\" }` (exact-match the row the same way):\n - `status: completed` → provisioned; then, depending on backend, check whether a build has succeeded.\n - `status: running` → still provisioning (see Step 1).\n - `status: failed` → provisioning stopped before finishing → route to **provision** to self-heal.\n- **Is it an empty headless shell from onboarding?** A `headless` site whose setup is `completed` is\n **not necessarily finished** — onboarding now creates the website *before* the build runs, as an\n **empty headless shell** (`hosting_websites_start-setup { type: \"headless_empty\" }`): `website_type`\n is `headless` but **no backend is installed** (no WordPress at `/cms`, no store). Tell a shell from a\n real backend the same way provision does: within 24 h the setup `type` is `headless_empty`; otherwise\n `wordpress_installations_list { username, domain, ownership: \"all\" }` returns **no** `/cms` row and\n there is no `site.json` recording a backend. An empty shell means **provision has not chosen or\n installed a backend yet** — this is a **new build** that happens to already own its website, not a\n finished or resumable one. Route it to **refine** (choose the backend), then **provision** adopts the\n shell and swaps it to that backend (see the provision router's *Onboarding handoff*). Never create a\n second site, and never skip provision for it.\n\nReconcile with the local state. **When they disagree, reality wins** and the local `stage` is\ncorrected.\n\n---\n\n## Step 4 — Determine the position\n\nConnect always writes `state.json` (with `stage: check_state`) before this step runs, so local\nstate is never truly empty. **\"Local state: none\" here means only connect artifacts exist** —\n`connect.json` + a `state.json` still pointing at `check_state`/`refine`, and **no build artifacts\nyet** (`brief.md`, `site.json`, …).\n\n| Local state | Reality (domain) | Position |\n|---|---|---|\n| none (connect only) | free | **new build** — start from refine |\n| none (connect only) | empty headless shell (onboarding) | **new build on an existing shell** — start from refine; provision adopts the shell and swaps it to the chosen backend. Never create a second site, never skip provision |\n| none (connect only) | site exists with a real backend | **adopt / resume** — never create a second site; route to the first unfinished stage |\n| build artifacts present, incomplete | matches | **resume** at `state.json`'s `stage` |\n| build artifacts present | disagrees | **reality wins** — recompute the stage from what actually exists |\n| build artifacts present, all done | live site exists | **finished** — this is now an *iterate* request, not a build |\n\n---\n\n## Step 5 — Guide the user\n\nThe question to ask depends on whether there is actually **something to resume** — i.e. **build\nartifacts** (`brief.md`, `site.json`, …) or a **live site** for this domain. A stray `.lock` or\nconnect-only files are *not* something to resume.\n\n- **New build** (no build artifacts and either the domain is free **or** it holds only an empty\n headless shell from onboarding) → just proceed to refine. **Don't ask resume vs start over** —\n there's nothing to resume; both would land in the same place. An empty headless shell is not\n \"something to resume\": it has no backend and no content yet, so it's a fresh build that already owns\n its website — provision will adopt and swap it. Mention it in one line (\"Using the headless site\n onboarding already created for this domain.\"). If a leftover `.lock` is lying around, silently take\n it over and continue (optionally mention it in one line).\n- **Something to resume** (build artifacts exist, or a site exists for the domain **with a real backend\n installed** — WordPress at `/cms`, a store, or a deployed app) → tell the user plainly what's there\n and **ask them to choose**, regardless of how old it is (don't guess from timestamps):\n\n- **Resume** — pick up at the computed stage. (If a `.lock` is present in this case, also confirm no\n other window is actively building this domain right now.)\n- **Start over / redo a step** — only safe **before anything is provisioned**. If the site is already\n provisioned or live, you **cannot** re-create it: that is forward-only *iterate* (change content or\n design and redeploy), not a fresh build. Never re-provision or overwrite a live site; if the user\n insists on a clean slate for a live domain, explain the limitation and point them at hPanel.\n- **Switch domain** — they want a different domain. A new domain is a **new workspace**\n (`~/.hostinger/<other-domain>/`, with its own `src/`). Hand off to start that domain's run.\n- **Buy a domain** — they want a custom domain instead of the temporary one. Route to the domain\n purchase / `connect-domain` flow, then continue with the chosen domain.\n\nWhen the intent is ambiguous, **ask** — don't guess. A skipped tool result is ambiguous; see\n*When you ask the user* in the top-level `SKILL.md`.\n\n---\n\n## Step 6 — Record and route\n\nWrite `~/.hostinger/<domain>/state.json` with the agreed next `stage` and a fresh timestamp. If the\nroute isn't a new build, record it with `run-log.mjs <domain> run-update --kind resume` (or\n`redesign` / `iterate`), then end the stage with `stage-end check_state ok --note \"<the route>\"`.\nThen:\n\n- **Handing straight to the next stage in this same session?** Keep the `.lock` (you are still\n actively running) and continue.\n- **Stopping and returning control to the user?** (e.g. the next stage isn't built yet, or you are\n waiting on them.) **Delete the `.lock`** — the session is no longer active, and a leftover lock just\n forces an unnecessary \"is another window running?\" question on the next run. Always release the lock\n on a clean stop; it exists only to mark an actively-running session. A stop is still the end of a\n run: give the final report and save the build report (`09-done`).\n\n---\n\n## Invariants\n\n- **One directory per domain.** The domain is the key; state files never repeat it.\n- **Only this domain's workspace.** Never list `~/.hostinger/` or open another site's workspace (see\n *State and artifacts* in the top-level `SKILL.md`).\n- **Never create a second site** on a domain that already has one.\n- **Never re-provision or overwrite a live site.** Recovery is forward-only.\n- **Reality beats local state**, always.\n- **When ambiguous, ask.**\n"
|
|
154
|
+
"text": "---\nname: headless-step-check-state\ndescription: \"First build step of the Hostinger Headless flow, run right after connect. Works out where a given domain's build stands — is a run already in progress, does the site already exist, how far did it get — by reconciling the global workspace state under ~/.hostinger/<domain>/ with what the Hostinger connector reports, then guides the user to continue, switch or buy a domain, or start over. Owns all resume/position logic for the flow.\"\n---\n\n# headless-step-check-state\n\nThe first build step of the Hostinger Headless flow (orchestrated by `hostinger.com/headless/skill.md`),\nrun right after connect. Connect has already connected the Hostinger connector and confirmed the\naccount can build. Your job here is to\n**figure out where this domain stands and agree the route with the user** before any new work begins.\nThis step owns all resume/position logic — no other stage second-guesses it.\n\nNothing in this step creates, provisions, deploys, or deletes anything. It reads and guides. Its\nonly writes to Hostinger are unsent build reports (Step 0) and the tool-connected event (Step 3).\n\n---\n\n## Where state lives\n\nEverything for a domain lives under the global site workspace **`~/.hostinger/<domain>/`** — one\ndirectory per domain, under the user's home (`~` = `$HOME`), **not** the current working directory.\nThe directory name **is** the domain, so `state.json` inside does not store it. Because it's global,\nthis domain's build is resumable from any directory.\n\n`state.json` shape (`stage` is the *next* stage to run; `provision` is the background task's status,\npresent only once provision has fired):\n\n```json\n{ \"tool\": \"claude-code\", \"stage\": \"content_model\",\n \"provision\": { \"status\": \"in_progress\", \"domain\": \"<domain>\", \"started_at\": \"…\" },\n \"updated_at\": \"…\" }\n```\n\n`provision.status` is `in_progress` or `completed` — but it is a **hint**: always re-verify it against\n`hosting_websites_list-setups` (Step 1) before trusting it to gate an instance-barrier step.\n\n---\n\n## Step 0 — Start the run log\n\nBefore anything else, start a run and the stage (see *Run log and build report* in the top-level\n`SKILL.md`):\n\n```bash\nnode <skill>/run-log.mjs <domain> run-start --tool <tool> --model <model> --skill <skill version>\nnode <skill>/run-log.mjs <domain> stage-start check_state\n```\n\nIf an earlier run on this domain never wrote its report, `run-start` closes it as `abandoned` first.\n\nThen send any build reports that haven't reached Hostinger yet (that abandoned run, or a send that\nfailed last time):\n\n```bash\nnode <skill>/run-log.mjs <domain> unsent\n```\n\nEach line is `<run> <path>`. For each, send the file through `hosting_headless_submit-build-report`\nand record the result, as described in *Run log and build report* in the top-level `SKILL.md`. One\ntry each. Don't ask first; if any went out, say so in one line (e.g. \"Sent 1 earlier build report to\nHostinger.\"). Don't let a failure hold up this step.\nCheck-state runs once per session. A follow-up after the final report, in the same session, doesn't\ncome back here: it calls `run-resume` (see *Run log and build report* in the top-level `SKILL.md`).\n\n## Step 1 — Is a build actively running right now? (check this before anything else)\n\nKeep two things separate, and **never guess from a timestamp.**\n\n- **A platform build actively in progress** — the only *reliable* \"running now\" signal. Check\n `hosting_websites_list-setups { \"domain\": \"<domain>\" }` and exact-match the domain row:\n - `status: running` → provisioning is underway **right now** (a background provision from an earlier\n turn). Don't start a second one — reconcile `state.json`'s `provision` to `in_progress`, and\n either resume prepare work while it finishes or poll it to `completed` at the barrier.\n - `status: failed` → not running; route to provision to self-heal (Step 3).\n - `completed` → provision is done; set `provision.status` to `completed`. Instance-barrier steps\n (content push, frontend data, deploy) are now unblocked.\n - no row → not provisioned yet; carry on.\n\n This check **is** the source of truth for `provision.status`: a stored `in_progress`/`completed` in\n `state.json` is only a hint until this reconciles it.\n\n- **A `.lock`** — `~/.hostinger/<domain>/.lock`. It only tells you *a previous run\n touched this domain*. **Do not judge it by age** — a 2-minute-old lock and a 3-year-old lock get the\n same treatment, and a lock on its own is **not** a reason to interrupt the user. Carry it into Step 5:\n if there's nothing to resume (new build), silently take it over; only if there's real state to resume\n do you also ask *is another Claude window building this domain right now?* (yes → stop; no → take\n over).\n\nOnce you're actively working this domain, **acquire/refresh the lock** (write the current timestamp),\nand **release it on a clean stop** (Step 6). The lock marks an active session, nothing more.\n\n---\n\n## Step 2 — Read the workspace directory\n\nCheck `~/.hostinger/<domain>/` by its exact path (for example `test -d ~/.hostinger/<domain>`), not\nby listing `~/.hostinger/`:\n\n- **Absent** → no history for this domain in the workspace.\n- **Present** → read `state.json` (its `stage`) and whatever artifacts exist (`brief.md`,\n `site.json`, …). Treat these as a hint, not the truth.\n\n---\n\n## Step 3 — Verify against reality (reality wins)\n\nQuery the Hostinger connector — the local files are never trusted on their own:\n\n- **Does the site exist?** `hosting_websites_list { \"domain\": \"<domain>\" }`. ⚠️ This filter is a\n **case-insensitive substring match**, not exact — so `test.com` would also return\n `shop.test.com`. **Compare each returned row's `domain` to your target for an *exact* match**\n (case-insensitive) and ignore the rest. No exact row ⇒ the domain is free. An exact row ⇒ the site\n exists; note its `website_type` (`headless`, `wordpress`, `nodejs`, …) and `username`.\n- **Tell hPanel the tool connected.** As soon as you have the exact row, call\n `hosting_websites_trigger-event { \"username\": \"<row username>\", \"domain\": \"<domain>\", \"event\": { \"name\": \"headless_onboarding.tool.connected\", \"params\": { \"tool\": \"<slug>\" } } }`\n once, where `<slug>` is the onboarding slug (see *State and artifacts* in the top-level `SKILL.md`).\n This flips hPanel's onboarding card to \"connected\". Don't ask first and don't mention it. Skip the\n call when there's no exact row or your tool has no onboarding slug. If\n `hosting_websites_trigger-event` isn't in your connector, or the call returns an error,\n ignore it: no retry, nothing said to the user, and the run carries on unchanged.\n- **How far did it get?** If the site exists, check its setup via\n `hosting_websites_list-setups { \"domain\": \"<domain>\" }` (exact-match the row the same way):\n - `status: completed` → provisioned; then, depending on backend, check whether a build has succeeded.\n - `status: running` → still provisioning (see Step 1).\n - `status: failed` → provisioning stopped before finishing → route to **provision** to self-heal.\n- **Is it an empty headless shell from onboarding?** A `headless` site whose setup is `completed` is\n **not necessarily finished** — onboarding now creates the website *before* the build runs, as an\n **empty headless shell** (`hosting_websites_start-setup { type: \"headless_empty\" }`): `website_type`\n is `headless` but **no backend is installed** (no WordPress at `/cms`, no store). Tell a shell from a\n real backend the same way provision does: within 24 h the setup `type` is `headless_empty`; otherwise\n `wordpress_installations_list { username, domain, ownership: \"all\" }` returns **no** `/cms` row and\n there is no `site.json` recording a backend. An empty shell means **provision has not chosen or\n installed a backend yet** — this is a **new build** that happens to already own its website, not a\n finished or resumable one. Route it to **refine** (choose the backend), then **provision** adopts the\n shell and swaps it to that backend (see the provision router's *Onboarding handoff*). Never create a\n second site, and never skip provision for it.\n\nReconcile with the local state. **When they disagree, reality wins** and the local `stage` is\ncorrected.\n\n---\n\n## Step 4 — Determine the position\n\nConnect always writes `state.json` (with `stage: check_state`) before this step runs, so local\nstate is never truly empty. **\"Local state: none\" here means only connect artifacts exist** —\n`connect.json` + a `state.json` still pointing at `check_state`/`refine`, and **no build artifacts\nyet** (`brief.md`, `site.json`, …).\n\n| Local state | Reality (domain) | Position |\n|---|---|---|\n| none (connect only) | free | **new build** — start from refine |\n| none (connect only) | empty headless shell (onboarding) | **new build on an existing shell** — start from refine; provision adopts the shell and swaps it to the chosen backend. Never create a second site, never skip provision |\n| none (connect only) | site exists with a real backend | **adopt / resume** — never create a second site; route to the first unfinished stage |\n| build artifacts present, incomplete | matches | **resume** at `state.json`'s `stage` |\n| build artifacts present | disagrees | **reality wins** — recompute the stage from what actually exists |\n| build artifacts present, all done | live site exists | **finished** — this is now an *iterate* request, not a build |\n\n---\n\n## Step 5 — Guide the user\n\nThe question to ask depends on whether there is actually **something to resume** — i.e. **build\nartifacts** (`brief.md`, `site.json`, …) or a **live site** for this domain. A stray `.lock` or\nconnect-only files are *not* something to resume.\n\n- **New build** (no build artifacts and either the domain is free **or** it holds only an empty\n headless shell from onboarding) → just proceed to refine. **Don't ask resume vs start over** —\n there's nothing to resume; both would land in the same place. An empty headless shell is not\n \"something to resume\": it has no backend and no content yet, so it's a fresh build that already owns\n its website — provision will adopt and swap it. Mention it in one line (\"Using the headless site\n onboarding already created for this domain.\"). If a leftover `.lock` is lying around, silently take\n it over and continue (optionally mention it in one line).\n- **Something to resume** (build artifacts exist, or a site exists for the domain **with a real backend\n installed** — WordPress at `/cms`, a store, or a deployed app) → tell the user plainly what's there\n and **ask them to choose**, regardless of how old it is (don't guess from timestamps):\n\n- **Resume** — pick up at the computed stage. (If a `.lock` is present in this case, also confirm no\n other window is actively building this domain right now.)\n- **Start over / redo a step** — only safe **before anything is provisioned**. If the site is already\n provisioned or live, you **cannot** re-create it: that is forward-only *iterate* (change content or\n design and redeploy), not a fresh build. Never re-provision or overwrite a live site; if the user\n insists on a clean slate for a live domain, explain the limitation and point them at hPanel.\n- **Switch domain** — they want a different domain. A new domain is a **new workspace**\n (`~/.hostinger/<other-domain>/`, with its own `src/`). Hand off to start that domain's run.\n- **Buy a domain** — they want a custom domain instead of the temporary one. Route to the domain\n purchase / `connect-domain` flow, then continue with the chosen domain.\n\nWhen the intent is ambiguous, **ask** — don't guess. A skipped tool result is ambiguous; see\n*When you ask the user* in the top-level `SKILL.md`.\n\n---\n\n## Step 6 — Record and route\n\nWrite `~/.hostinger/<domain>/state.json` with the agreed next `stage` and a fresh timestamp. If the\nroute isn't a new build, record it with `run-log.mjs <domain> run-update --kind resume` (or\n`redesign` / `iterate`), then end the stage with `stage-end check_state ok --note \"<the route>\"`.\nThen:\n\n- **Handing straight to the next stage in this same session?** Keep the `.lock` (you are still\n actively running) and continue.\n- **Stopping and returning control to the user?** (e.g. the next stage isn't built yet, or you are\n waiting on them.) **Delete the `.lock`** — the session is no longer active, and a leftover lock just\n forces an unnecessary \"is another window running?\" question on the next run. Always release the lock\n on a clean stop; it exists only to mark an actively-running session. A stop is still the end of a\n run: give the final report and save the build report (`09-done`).\n\n---\n\n## Invariants\n\n- **One directory per domain.** The domain is the key; state files never repeat it.\n- **Only this domain's workspace.** Never list `~/.hostinger/` or open another site's workspace (see\n *State and artifacts* in the top-level `SKILL.md`).\n- **Never create a second site** on a domain that already has one.\n- **Never re-provision or overwrite a live site.** Recovery is forward-only.\n- **Reality beats local state**, always.\n- **When ambiguous, ask.**\n"
|
|
155
155
|
},
|
|
156
156
|
{
|
|
157
157
|
"uri": "skill://hostinger-headless/steps/02-refine/SKILL.md",
|
package/src/core/tools/all.js
CHANGED
|
@@ -559,6 +559,76 @@ export default [
|
|
|
559
559
|
"group": "hosting",
|
|
560
560
|
"hidden": true
|
|
561
561
|
},
|
|
562
|
+
{
|
|
563
|
+
"name": "hosting_websites_trigger-event",
|
|
564
|
+
"title": "Trigger website event",
|
|
565
|
+
"annotations": {
|
|
566
|
+
"title": "Trigger website event",
|
|
567
|
+
"readOnlyHint": false,
|
|
568
|
+
"destructiveHint": false
|
|
569
|
+
},
|
|
570
|
+
"topic": "hosting",
|
|
571
|
+
"description": "Tell Hostinger that something happened on this website, so Hostinger services such as hPanel can react to it. `event.name` picks the event and decides which `event.params` it takes. The call changes nothing on the website.",
|
|
572
|
+
"method": "",
|
|
573
|
+
"path": "",
|
|
574
|
+
"inputSchema": {
|
|
575
|
+
"type": "object",
|
|
576
|
+
"properties": {
|
|
577
|
+
"username": {
|
|
578
|
+
"type": "string",
|
|
579
|
+
"description": "Username of the hosting account that owns the website, as hosting_websites_list returns it"
|
|
580
|
+
},
|
|
581
|
+
"domain": {
|
|
582
|
+
"type": "string",
|
|
583
|
+
"description": "Domain name of the website (e.g., example.com)"
|
|
584
|
+
},
|
|
585
|
+
"event": {
|
|
586
|
+
"type": "object",
|
|
587
|
+
"description": "Event to trigger; `name` decides which `params` it takes",
|
|
588
|
+
"properties": {
|
|
589
|
+
"name": {
|
|
590
|
+
"type": "string",
|
|
591
|
+
"description": "Name of the event. `headless_onboarding.tool.connected`: an AI coding tool started building this website with the Hostinger headless skill, so hPanel shows the tool as connected; send it once per skill run; takes `params.tool`.",
|
|
592
|
+
"enum": [
|
|
593
|
+
"headless_onboarding.tool.connected"
|
|
594
|
+
]
|
|
595
|
+
},
|
|
596
|
+
"params": {
|
|
597
|
+
"type": "object",
|
|
598
|
+
"description": "Fields of the event",
|
|
599
|
+
"properties": {
|
|
600
|
+
"tool": {
|
|
601
|
+
"type": "string",
|
|
602
|
+
"description": "Lowercase slug of the AI coding tool. Known slugs: `claude` (Claude Code), `cursor` (Cursor), `codex` (Codex), `vscode` (VS Code), `antigravity` (Antigravity) and `devin` (Devin). For any other tool, send its own slug.",
|
|
603
|
+
"pattern": "^[a-z0-9-]{1,32}$"
|
|
604
|
+
}
|
|
605
|
+
},
|
|
606
|
+
"required": [
|
|
607
|
+
"tool"
|
|
608
|
+
],
|
|
609
|
+
"additionalProperties": false
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
"required": [
|
|
613
|
+
"name",
|
|
614
|
+
"params"
|
|
615
|
+
],
|
|
616
|
+
"additionalProperties": false
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
"required": [
|
|
620
|
+
"username",
|
|
621
|
+
"domain",
|
|
622
|
+
"event"
|
|
623
|
+
]
|
|
624
|
+
},
|
|
625
|
+
"security": [],
|
|
626
|
+
"custom": true,
|
|
627
|
+
"templateFile": "trigger-website-event.template.js",
|
|
628
|
+
"templateFileTS": "trigger-website-event.template.ts",
|
|
629
|
+
"handlerMethod": "handleHostingTriggerWebsiteEvent",
|
|
630
|
+
"group": "hosting"
|
|
631
|
+
},
|
|
562
632
|
{
|
|
563
633
|
"name": "agency-hosting_datacenters_list",
|
|
564
634
|
"title": "List available datacenters",
|
|
@@ -6209,6 +6279,41 @@ export default [
|
|
|
6209
6279
|
],
|
|
6210
6280
|
"group": "hosting"
|
|
6211
6281
|
},
|
|
6282
|
+
{
|
|
6283
|
+
"name": "hosting_cache_status",
|
|
6284
|
+
"title": "Get cache status",
|
|
6285
|
+
"annotations": {
|
|
6286
|
+
"title": "Get cache status",
|
|
6287
|
+
"readOnlyHint": true,
|
|
6288
|
+
"destructiveHint": false
|
|
6289
|
+
},
|
|
6290
|
+
"description": "Returns the caching state of the website: whether server-side caching is enabled and whether\ndevelopment (cacheless) mode is on. Works for the main domain, addon websites, parked domains\nand subdomains of the account; each reports its own settings and does not inherit them from\nits parent website.\n\n`is_enabled` is the setting changed by `Toggle website cache` and reflects a toggle\nimmediately. `is_cacheless_mode_enabled` is true while development mode is on; caching is then\nbypassed even when `is_enabled` is true. `Toggle cacheless mode` is applied in the background,\nso this flag can take a few minutes to follow it.\n\nThe domain must be the exact website name as listed on the account, without a `www.` prefix.\nReturns 404 when the domain is not a website on the account.",
|
|
6291
|
+
"method": "GET",
|
|
6292
|
+
"path": "/api/hosting/v1/accounts/{username}/websites/{domain}/cache/status",
|
|
6293
|
+
"inputSchema": {
|
|
6294
|
+
"type": "object",
|
|
6295
|
+
"properties": {
|
|
6296
|
+
"username": {
|
|
6297
|
+
"type": "string",
|
|
6298
|
+
"description": "username parameter"
|
|
6299
|
+
},
|
|
6300
|
+
"domain": {
|
|
6301
|
+
"type": "string",
|
|
6302
|
+
"description": "Domain name"
|
|
6303
|
+
}
|
|
6304
|
+
},
|
|
6305
|
+
"required": [
|
|
6306
|
+
"username",
|
|
6307
|
+
"domain"
|
|
6308
|
+
]
|
|
6309
|
+
},
|
|
6310
|
+
"security": [
|
|
6311
|
+
{
|
|
6312
|
+
"apiToken": []
|
|
6313
|
+
}
|
|
6314
|
+
],
|
|
6315
|
+
"group": "hosting"
|
|
6316
|
+
},
|
|
6212
6317
|
{
|
|
6213
6318
|
"name": "hosting_cache_toggle-cacheless",
|
|
6214
6319
|
"title": "Toggle cacheless mode",
|
|
@@ -6218,7 +6323,7 @@ export default [
|
|
|
6218
6323
|
"destructiveHint": true,
|
|
6219
6324
|
"idempotentHint": true
|
|
6220
6325
|
},
|
|
6221
|
-
"description": "Turns development (cacheless) mode on or off, based on the enabled flag. When enabled, nothing\nis cached, effectively turning off all caching for the website; use it while actively developing,\ntesting changes, debugging issues, or when real-time updates must be visible. Disable it after\nfinishing development work to restore the performance benefits of caching.",
|
|
6326
|
+
"description": "Turns development (cacheless) mode on or off, based on the enabled flag. When enabled, nothing\nis cached, effectively turning off all caching for the website; use it while actively developing,\ntesting changes, debugging issues, or when real-time updates must be visible. Disable it after\nfinishing development work to restore the performance benefits of caching.\n\nThe change is applied in the background and can take a few minutes. Use `Get cache status` to\ncheck the current state.",
|
|
6222
6327
|
"method": "PATCH",
|
|
6223
6328
|
"path": "/api/hosting/v1/accounts/{username}/websites/{domain}/cacheless-mode/toggle",
|
|
6224
6329
|
"inputSchema": {
|
|
@@ -6259,7 +6364,7 @@ export default [
|
|
|
6259
6364
|
"destructiveHint": true,
|
|
6260
6365
|
"idempotentHint": true
|
|
6261
6366
|
},
|
|
6262
|
-
"description": "Turns server-side caching for the website on or off, based on the enabled flag. Enable it for\nfaster page loads, reduced server load, and improved user experience; recommended for production\nwebsites. Disabling may impact performance; to temporarily bypass caching while developing or\ndebugging, prefer toggling cacheless mode instead.\n\nDoes nothing if caching is already in the requested state.",
|
|
6367
|
+
"description": "Turns server-side caching for the website on or off, based on the enabled flag. Enable it for\nfaster page loads, reduced server load, and improved user experience; recommended for production\nwebsites. Disabling may impact performance; to temporarily bypass caching while developing or\ndebugging, prefer toggling cacheless mode instead.\n\nDoes nothing if caching is already in the requested state. Use `Get cache status` to check the\ncurrent state.",
|
|
6263
6368
|
"method": "PATCH",
|
|
6264
6369
|
"path": "/api/hosting/v1/accounts/{username}/websites/{domain}/cache/toggle",
|
|
6265
6370
|
"inputSchema": {
|