@agentshouse/skills 0.1.0-c22b29c83d792 → 0.1.0-c262ec29db5e3

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.
@@ -44,7 +44,8 @@ Theme its own styles with CSS custom properties on the element or an ancestor:
44
44
  `--chat-accent`, `--chat-line`, `--chat-attention`, `--chat-danger`, `--chat-font`,
45
45
  `--chat-font-mono`, `--chat-font-size`, `--chat-radius` and `--chat-density` (a factor for
46
46
  spacing); an unset one keeps House's light or dark look. For the Chat button, which takes no
47
- element, set them on the document's root element. Its dot is House's and takes none of them.
47
+ element, set them on the document's root element. Its dot keeps House's colours and type, and
48
+ stays level with the sheet's input.
48
49
  It shows conversations only where the release declares them;
49
50
  otherwise it lists no conversation and no Agent. A secret
50
51
  question is never answered here; typed answers live in the Presentation State members named
@@ -10,5 +10,4 @@ What an App's page draws and how it behaves in the browser.
10
10
  - An empty list says what it will hold and invites the first document.
11
11
  - Long names truncate with an ellipsis and show in full on hover.
12
12
  - The element is the link: a row, card or name opens its item; no "Open" buttons.
13
- - Offer installation yourself: `bridge.install()` from a click starts the install or shows the browser's prompt, or answers `manual` where you show how.
14
13
  - Offer a way out where your User expects one: `bridge.ceremony('/sign-out')` signs them out of House and opens sign-in.
@@ -14,8 +14,8 @@ Build it as [Build an App](apps/build) says, with what follows. Anything private
14
14
  - To receive messages from visitors, name an Intake Room with `sites/intake-room/set` and send each with `runtime.call('sites/submissions/create', { content })`, online only. `content` is one Markdown document the Intake Room's `settings/schema.yaml` accepts, and House adds its `site` and `submitted` fields. The call answers `{ kind: 'action', result: { submitted: true } }` once House stored it. Anything else stored nothing: `{ kind: 'rejected', code }` says why, such as `bot_check_failed` for a browser that failed the bot check, as automated test browsers do, `site_intake_room_absent`, `invalid_documents` with the `path`, `rule` and `field` it broke, `submission_reserved_key`, `submission_too_large`, `limit_reached` or `cap_reached`. So thank the visitor only for `submitted`, and otherwise show that nothing was sent.
15
15
  - A Site loads House's servers when it is bound to a Room that changes often, or when it writes once per visitor, such as a Submission sent on every visit: send one only when a visitor asks to.
16
16
  - Code that holds a key, such as one opening a checkout, runs in one of the App's functions, which the page calls: [A Site's function calls](sites/functions). [A Site's payments](sites/payments) takes payments with them.
17
- - `sites/describe` sets the title and description search engines show.
18
- - With `google_analytics_id` set by `sites/describe`, House measures a visitor only after they accept. While `bridge.onStatus` reports `analytics.measures`, ask them on the Site unless `analytics.choice` holds their answer, report it with `bridge.analyticsConsent('accept')` or `bridge.analyticsConsent('decline')`, and keep a way on every page to decline later, which reloads the page unmeasured.
17
+ - `sites/describe` sets `google_analytics_id` and the title and description search engines show. With an ID, House measures a visitor only after they accept. While `bridge.onStatus` reports `analytics.measures`, ask them on the Site unless `analytics.choice` holds their answer, report it with `bridge.analyticsConsent('accept')` or `'decline'`, and keep a way on every page to decline later, which reloads the page unmeasured. A counter of its own: [A Site's own counter](sites/counter).
18
+ - A Site moved from another builder keeps its old links with `redirects` in `app.json`, `[{ "from": "/old", "to": "/new" }]`: each old path, as a browser asks for it, answers a permanent redirect to its new path, query included. No old path is under `/_house/`, a root file such as `/robots.txt` or an entry route's; none repeats or is a new path. A document published at an old path takes it over.
19
19
  - See it yourself: open its url, which needs no sign-in.
20
20
 
21
21
  Build its first screen as [A Site's first load](sites/first-load) says. House serves a route as HTML only where the [Entry Data Contract](sites/entry-data-contract) declares it, and [The App runtime on a Site](sites/runtime) says what the runtime does differently there.
@@ -0,0 +1,26 @@
1
+ # A Site's own counter
2
+
3
+ How a Site counts its visitors in a counter of its own, such as a web analytics counter or an ad pixel, beside `google_analytics_id` or instead of it.
4
+
5
+ - **Its script in the release.** A page runs only its release's scripts, so copy the counter's script into your source and bundle it, rather than load it from the counter's server as its snippet does. A script the counter loads from there later is refused too.
6
+ - **Its origins.** List every https origin the counter sends to in `app.json`'s `external_origins`. The browser console names each origin the page refused.
7
+ - **The page's address and referrer.** Your page runs in a frame of the Site's page at the Site's own origin, so the counter sees the frame's address and no referrer of the visitor's. Turn off its own page view and send each through `countPages` below, which gives the page's address and where the visitor came from: first the Site page's referrer, then the page they left.
8
+ - **Consent, as for `google_analytics_id`.** Start the counter only after the visitor accepts, never after Decline. Ask on the Site unless their answer is kept. While `bridge.onStatus` reports `analytics.measures`, the answer is `analytics.choice`, kept with `bridge.analyticsConsent`, so one banner asks once for both; otherwise keep it in local storage, and a browser that keeps none is never counted. Keep a way on every page to decline later, which reloads the page without the counter: `bridge.analyticsConsent('decline')` does that while `analytics.measures` holds, `parent.location.reload()` otherwise.
9
+ - **Hits arrive.** Publish, open the Site's url in a browser, accept and open a second page: the network log shows a request to the counter for each page, answered, and the counter's real-time report, which your User reads, shows both pages at the Site's address, the second with the first as its referrer.
10
+
11
+ `src/counter.ts`, which your entry script calls once the visitor accepted, with the counter's call that sends one page view:
12
+
13
+ ```ts
14
+ import { houseBridge } from '@agentshouse/app-bridge';
15
+
16
+ export function countPages(pageView: (page: string, referrer: string) => void): void {
17
+ let referrer = parent.document.referrer;
18
+ let counted = '';
19
+ houseBridge().onAddress((address) => {
20
+ const page = location.origin + address;
21
+ if (page === counted) return;
22
+ pageView(page, referrer);
23
+ referrer = counted = page;
24
+ });
25
+ }
26
+ ```
@@ -2,6 +2,13 @@
2
2
 
3
3
  What the App runtime does differently on a Site's page. Everything else is as in an App, [Local first](apps/local-first) included, so a Site's page draws no loading state either. A route has an Entry Page, House's HTML of it before the App starts, only where the release declares one in its [Entry Data Contract](sites/entry-data-contract).
4
4
 
5
+ A Room the Site binds for queries only never reaches a visitor's browser: `rooms` lists it
6
+ with `queriesOnly: true` and nothing held, and its rows come a page at a time through
7
+ `queryHouse`, as [House query rules](apps/query-house) say, except that a query of more than
8
+ about 9,000 bytes, too long for the Site's address, answers `query_too_large` with no `cap`
9
+ before it is sent. Every visitor asking the same query gets the same page, which the edge keeps
10
+ for a few minutes, so a change to the Room shows within them.
11
+
5
12
  A History revision or a Document's `change` written by a Site gives its `author` as `{ kind: 'site', id, name }`. `observe('member')` answers `null` on a Site, and a Document's `change` is `null` there, since the Provider delivers no time.
6
13
 
7
14
  On a Site, every Save stays in the visitor's browser: write grants and revisions do not refuse it,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/skills",
3
- "version": "0.1.0-c22b29c83d792",
3
+ "version": "0.1.0-c262ec29db5e3",
4
4
  "description": "The upstream Skills agents.house serves its agents, verbatim, and the texts it writes for them: the Guide, its own Skills among the pages, and the Agent instructions",
5
5
  "license": "MIT",
6
6
  "type": "module",