pomerado 0.2.0 → 0.2.1-canary.10
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 +21 -0
- package/README.md +130 -188
- package/dist/typescript/authoring/auth/SKILL.md +17 -6
- package/dist/typescript/authoring/caller-input/SKILL.md +3 -1
- package/dist/typescript/authoring/core/SKILL.md +5 -3
- package/dist/typescript/authoring/pagination/SKILL.md +12 -0
- package/dist/typescript/authoring/workspace/AGENTS.md +7 -5
- package/dist/typescript/src/destinations/autofill-fill.d.ts +3 -1
- package/dist/typescript/src/destinations/autofill-fill.js +66 -17
- package/dist/typescript/src/destinations/autofill-locate-code.js +10 -4
- package/dist/typescript/src/destinations/autofill-page-code.d.ts +4 -2
- package/dist/typescript/src/destinations/autofill-page-code.js +18 -7
- package/dist/typescript/src/destinations/autofill-refusal.d.ts +43 -0
- package/dist/typescript/src/destinations/autofill-refusal.js +41 -0
- package/dist/typescript/src/destinations/autofill-step.d.ts +20 -3
- package/dist/typescript/src/destinations/autofill-step.js +3 -1
- package/dist/typescript/src/destinations/credential-keyboard.d.ts +8 -3
- package/dist/typescript/src/destinations/credential-keyboard.js +46 -15
- package/dist/typescript/src/destinations/page-controls.d.ts +71 -0
- package/dist/typescript/src/destinations/page-controls.js +163 -0
- package/dist/typescript/src/execution/local-operation-stage.js +31 -10
- package/dist/typescript/src/execution/local-workspace.js +37 -16
- package/dist/typescript/src/execution/playwright-execute.d.ts +1 -1
- package/dist/typescript/src/execution/playwright-execute.js +2 -1
- package/dist/typescript/src/execution/sign-in-diagnostics.d.ts +10 -1
- package/dist/typescript/src/guardian/execution-policy.js +2 -2
- package/dist/typescript/src/guardian/openai-input.d.ts +8 -2
- package/dist/typescript/src/guardian/openai-input.js +29 -1
- package/dist/typescript/src/guardian/openai.d.ts +9 -5
- package/dist/typescript/src/guardian/openai.js +145 -43
- package/dist/typescript/src/guardian/review-layout.d.ts +66 -0
- package/dist/typescript/src/guardian/review-layout.js +292 -0
- package/dist/typescript/src/guardian/review.d.ts +99 -3
- package/dist/typescript/src/guardian/review.js +214 -100
- package/dist/typescript/src/guardian/session.d.ts +14 -1
- package/dist/typescript/src/guardian/session.js +35 -6
- package/dist/typescript/src/mint/contracts.d.ts +4 -3
- package/dist/typescript/src/mint/harness.js +32 -5
- package/dist/typescript/src/mint/idle-compaction.d.ts +41 -0
- package/dist/typescript/src/mint/idle-compaction.js +99 -0
- package/dist/typescript/src/mint/openai.js +42 -7
- package/dist/typescript/src/mint/sign-in-failure.d.ts +16 -1
- package/dist/typescript/src/mint/sign-in-failure.js +77 -1
- package/dist/typescript/src/mint/workspace.js +5 -4
- package/dist/typescript/src/models/model-usage.d.ts +10 -0
- package/dist/typescript/src/models/model-usage.js +15 -0
- package/dist/typescript/src/models/reasoning-settings.d.ts +4 -0
- package/dist/typescript/src/models/reasoning-settings.js +10 -0
- package/dist/typescript/src/standalone/after-submit.d.ts +101 -0
- package/dist/typescript/src/standalone/after-submit.js +29 -0
- package/dist/typescript/src/standalone/authentication.d.ts +4 -1
- package/dist/typescript/src/standalone/authentication.js +13 -1
- package/dist/typescript/src/standalone/cli.js +20 -10
- package/dist/typescript/src/standalone/contracts.d.ts +5 -0
- package/dist/typescript/src/standalone/mcp-cli.js +2 -1
- package/dist/typescript/src/standalone/mcp-jobs.d.ts +4 -2
- package/dist/typescript/src/standalone/mcp-jobs.js +8 -6
- package/dist/typescript/src/standalone/mcp-package.js +18 -19
- package/dist/typescript/src/standalone/mcp-server.js +14 -14
- package/dist/typescript/src/standalone/mint-execution.js +2 -2
- package/dist/typescript/src/standalone/mint-host.js +1 -1
- package/dist/typescript/src/standalone/mint-state.d.ts +98 -1
- package/dist/typescript/src/standalone/mint-state.js +3 -0
- package/dist/typescript/src/standalone/pomerado.js +1 -4
- package/dist/typescript/src/standalone/request-context.d.ts +21 -1
- package/dist/typescript/src/standalone/request-context.js +38 -8
- package/dist/typescript/src/standalone/run-operation.d.ts +5 -2
- package/dist/typescript/src/standalone/run-operation.js +10 -7
- package/dist/typescript/tests/browser/autofill-host-page.d.ts +2 -1
- package/dist/typescript/tests/browser/autofill-host-page.js +4 -1
- package/dist/typescript/tests/browser/shop-fixture.d.ts +4 -0
- package/dist/typescript/tests/browser/shop-fixture.js +24 -2
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- Runs of a built integration, through `run` or a served integration MCP, no longer call Guardian and need no model key. Guardian still reviews minting. A run no longer checks its `intent`, `effect` or `authenticationOrigins`.
|
|
6
|
+
- Integrations generated by earlier versions still have README text that asks for `OPENAI_API_KEY`. They no longer need it.
|
|
7
|
+
- `pomerado run` no longer requires `--intent`, and it ignores `--intent` and `--effect`.
|
|
8
|
+
- A failed run that has no more specific message now reads "Operation failed. Check the local browser and integration configuration." Minting keeps its message.
|
|
9
|
+
- Every merge to `main` publishes a canary, `X.Y.Z-canary.N`, under the `canary` dist-tag: `npm install pomerado@canary`. `latest` moves to the canary that Pomerado's hosted service promotes to production, so `npm install pomerado` gets the build production runs. The range it saves, such as `^0.2.1-canary.57`, also matches later canaries, so install with `--save-exact` or keep a lockfile. See [Releasing](docs/RELEASING.md).
|
|
10
|
+
- A host sign-in step fills a form whose submit is disabled, `aria-disabled` or in a disabled fieldset until the fields hold input. The host waits up to 5 seconds for the page to enable the submit, then clicks it, and never clicks it while it is disabled. It reads whether the submit is disabled the way Playwright's click does, which page scripts can't change. An `aria-disabled` wrapper keeps a submit waiting only when the submit itself has an ARIA role, as Playwright judges it. A page that changes the form's controls three times during the wait is refused. A submit in an `inert` region is still refused before anything is typed.
|
|
11
|
+
- Guardian's review of a host sign-in step shows the origin of the frame the step's controls are in, as the browser reports it, and no longer requires the submit to be enabled. The auth skill likewise lets the minter record a submit the page has not enabled yet.
|
|
12
|
+
|
|
13
|
+
### Breaking changes
|
|
14
|
+
|
|
15
|
+
- In `pomerado/core/destinations/autofill-step`, `AutofillInspection.screen` adds a required `origin`, which `inspectAutofillStep` sets. A filled `AutofillStepReport`'s `submit` adds `"stayed_disabled"`: the fields were filled, but the submit stayed disabled through the wait, so the host never clicked it.
|
|
16
|
+
- Migrate by setting `origin` on any inspection you build yourself, and by handling `"stayed_disabled"` in any exhaustive check on `submit`.
|
|
17
|
+
|
|
18
|
+
### Fixes
|
|
19
|
+
|
|
20
|
+
- A local edit the minter can't apply now says the edit was not applied and why. That covers a patch that doesn't match, a file that already exists or is missing, and a file past the size or file-count limit. The file is unchanged, and no new folder is left behind. These edits no longer report "Workspace edit outcome unknown".
|
|
21
|
+
- The minter's `read_source` now reads local workspace files. Through 0.2.0 every local read failed as unavailable, because the local workspace refused the one extra byte the minter asks for to detect an oversized file. A file past 8 MiB is still refused.
|
|
22
|
+
- Local runs stage authored source a level below the SDK, as the workspace guide describes. The documented `../../runtime/index.js` import from `src/` and the skill references' imports now load. Integrations saved with `../runtime/index.js` still run unchanged.
|
|
23
|
+
|
|
3
24
|
## 0.2.0
|
|
4
25
|
|
|
5
26
|
This release changes how a host embeds the minting core's authoring and which MCP entry a generated integration writes. Other standalone use through `pomerado`, `pomerado/mcp` and the CLI needs no change.
|
package/README.md
CHANGED
|
@@ -1,263 +1,205 @@
|
|
|
1
1
|
<h1 align="center"><a href="https://pomerado.ai">Pomerado</a></h1>
|
|
2
2
|
|
|
3
|
-
<p align="center">Turn websites into MCP integrations.</p>
|
|
4
|
-
<p align="center">Describe what you want to do on a website. Pomerado builds an integration your agent can use.</p>
|
|
3
|
+
<p align="center">Turn websites into MCP integrations your agent can rely on.</p>
|
|
5
4
|
|
|
6
5
|
<p align="center">
|
|
7
6
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=for-the-badge" alt="License MIT"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/pomerado"><img src="https://img.shields.io/npm/v/pomerado?style=for-the-badge&logo=npm" alt="npm version"></a>
|
|
8
8
|
<img src="https://img.shields.io/badge/node-24.21%2B%20%3C25-339933?style=for-the-badge&logo=nodedotjs&logoColor=white" alt="Node 24.21 or later in Node 24">
|
|
9
|
-
<img src="https://img.shields.io/badge/pnpm-10.34.5-F69220?style=for-the-badge&logo=pnpm&logoColor=white" alt="pnpm 10.34.5">
|
|
10
9
|
</p>
|
|
11
10
|
|
|
12
11
|
<p align="center">
|
|
13
|
-
<a href="#
|
|
12
|
+
<a href="#how-it-works">How it works</a> ·
|
|
13
|
+
<a href="#get-started">Get started</a> ·
|
|
14
14
|
<a href="#create-an-integration">Create an integration</a> ·
|
|
15
15
|
<a href="#use-your-integration">Use your integration</a> ·
|
|
16
|
-
<a href="#
|
|
16
|
+
<a href="#open-source-and-pomerado-cloud">Open source and Cloud</a> ·
|
|
17
|
+
<a href="#documentation-for-humans-and-agents">Docs</a> ·
|
|
17
18
|
<a href="#contributing">Contributing</a>
|
|
18
19
|
</p>
|
|
19
20
|
|
|
20
21
|
---
|
|
21
22
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
Pomerado helps agents use websites, including ones without APIs. Connect it to Codex, describe a task, and get a reusable MCP integration. Both Pomerado and the integrations you create run on your computer.
|
|
23
|
+
## What Pomerado does
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
┌────────────────────────────────────────────────────────────┐
|
|
28
|
-
│ website task → Pomerado MCP → integration MCP → Playwright │
|
|
29
|
-
└────────────────────────────────────────────────────────────┘
|
|
30
|
-
```
|
|
25
|
+
Pomerado builds MCP integrations for websites, including sites without an API.
|
|
31
26
|
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
- Use your own browser and model API key.
|
|
27
|
+
- Our tool builds integrations with only a natural language description of the task. No HAR file or recording is needed
|
|
28
|
+
- Integrations are deterministic, making them much faster and more reliable than computer use
|
|
29
|
+
- Pomerado works on sites behind a login and two-factor authentication
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
## Quickstart
|
|
40
|
-
|
|
41
|
-
Use macOS or Linux, Node 24.21 or a later Node 24 release, and pnpm 10.34.5.
|
|
31
|
+
## How it works
|
|
42
32
|
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
export OPENAI_API_KEY='your-model-api-key'
|
|
33
|
+
```mermaid
|
|
34
|
+
flowchart LR
|
|
35
|
+
try["<b>1. Explore the site</b><br/>Pomerado generates<br/>a script that explores<br/>the site in Chromium"]
|
|
36
|
+
complete["<b>2. Complete the example</b><br/>Pomerado generates<br/>code that completes<br/>your example"]
|
|
37
|
+
publish["<b>3. Generalize and publish</b><br/>Pomerado turns that code<br/>into a general integration<br/>that takes new inputs"]
|
|
38
|
+
use["<b>4. Your agent calls it</b><br/>Your agent calls<br/>the integration and<br/>gets validated output"]
|
|
39
|
+
try --> complete --> publish --> use
|
|
51
40
|
```
|
|
52
41
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
The shared model configuration uses `gpt-6-sol` for minting and `gpt-6-luna` for Guardian. Your model account must have access to both. Local hosting still sends model requests to your configured provider. Library callers can inject Agents SDK `ModelProvider` implementations through `minterProvider` and `guardianProvider`.
|
|
42
|
+
For more details, see [How it works](docs/how-it-works.md).
|
|
56
43
|
|
|
57
|
-
|
|
44
|
+
## Get started
|
|
58
45
|
|
|
59
|
-
|
|
46
|
+
Prerequisites
|
|
60
47
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
48
|
+
- macOS or Linux
|
|
49
|
+
- Node 24.21 or a later Node 24 release, which you can check with `node --version`
|
|
50
|
+
- An OpenAI API key, since Pomerado uses OpenAI models to build and review integrations. Your agent can run on any model
|
|
51
|
+
- An MCP client that runs local servers, such as Claude Code, Codex, Cursor, VS Code, Claude Desktop or Gemini CLI
|
|
65
52
|
|
|
66
|
-
|
|
53
|
+
Install Pomerado and the Chromium build it drives.
|
|
67
54
|
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
args = ["/absolute/path/to/pomerado/dist/typescript/src/standalone/mcp-cli.js", "mint", "--root", "/absolute/path/to/integrations"]
|
|
72
|
-
env_vars = ["OPENAI_API_KEY"]
|
|
55
|
+
```sh
|
|
56
|
+
npx -y -p pomerado pomerado-mcp --help
|
|
57
|
+
npx -y -p pomerado playwright install chromium
|
|
73
58
|
```
|
|
74
59
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
The configured root is where minted integrations are saved. Starting the MCP and listing tools do not launch Chromium or invoke a model.
|
|
60
|
+
On Linux, add `--with-deps` after `install` if Chromium's system libraries are missing.
|
|
78
61
|
|
|
79
|
-
|
|
62
|
+
Pomerado runs as a standard MCP stdio server. Clients that read an `mcpServers` file use this entry.
|
|
80
63
|
|
|
81
|
-
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"mcpServers": {
|
|
67
|
+
"pomerado": {
|
|
68
|
+
"command": "npx",
|
|
69
|
+
"args": ["-y", "-p", "pomerado", "pomerado-mcp", "mint", "--root", "/absolute/path/to/pomerado-integrations"]
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
82
74
|
|
|
83
|
-
|
|
75
|
+
- `--root` sets the folder where Pomerado saves your integrations. Use an absolute path, because each client starts servers from its own working folder
|
|
76
|
+
- The server reads `OPENAI_API_KEY` from its environment, so the key never needs to appear in chat
|
|
77
|
+
- Starting the server and listing its tools costs nothing. It launches no browser and calls no model until you start a mint
|
|
84
78
|
|
|
85
|
-
|
|
86
|
-
- `get_job` checks progress and waits for a question or completion. Minting starts once and returns a job ID.
|
|
87
|
-
- `provide_input` sends your answer to a question in the same chat. Pomerado checks that the answer matches the requested format.
|
|
88
|
-
- `cancel_job` stops the job and cleans up its browser and child process. An action already sent to a website may have taken effect.
|
|
79
|
+
Add Pomerado to your client with the command or file below.
|
|
89
80
|
|
|
90
|
-
|
|
81
|
+
| Client | Add Pomerado |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| Claude Code | `claude mcp add --scope user pomerado -- npx -y -p pomerado pomerado-mcp mint --root ~/pomerado-integrations` |
|
|
84
|
+
| Codex | `codex mcp add pomerado -- npx -y -p pomerado pomerado-mcp mint --root ~/pomerado-integrations`, then add `env_vars` |
|
|
85
|
+
| Gemini CLI | `gemini mcp add -s user -e 'OPENAI_API_KEY=$OPENAI_API_KEY' pomerado npx -y -p pomerado pomerado-mcp mint --root ~/pomerado-integrations` |
|
|
86
|
+
| Cursor | Add the entry to `~/.cursor/mcp.json` |
|
|
87
|
+
| VS Code | `code --add-mcp '{"name":"pomerado","command":"npx","args":["-y","-p","pomerado","pomerado-mcp","mint","--root","/absolute/path/to/pomerado-integrations"]}'`, or add the entry to `.mcp.json` in your workspace |
|
|
88
|
+
| Claude Desktop | Add the entry to `claude_desktop_config.json` |
|
|
91
89
|
|
|
92
|
-
|
|
90
|
+
Each client passes environment variables its own way. [Client settings](docs/getting-started.md#client-settings) covers the key and the timeouts for every client above.
|
|
93
91
|
|
|
94
|
-
|
|
92
|
+
To confirm the setup, ask your agent which Pomerado tools it has. It should list `mint`, `get_job`, `provide_input` and `cancel_job`.
|
|
95
93
|
|
|
96
|
-
##
|
|
94
|
+
## Let your agent set it up
|
|
97
95
|
|
|
98
|
-
|
|
96
|
+
If you'd rather not run these steps yourself, paste this into your agent.
|
|
99
97
|
|
|
100
98
|
```text
|
|
101
|
-
|
|
102
|
-
├── src/ Generated operation modules
|
|
103
|
-
├── pomerado.json Entrypoint and input/output schemas
|
|
104
|
-
├── deployment.json Tool name, description, URL, intent and authority
|
|
105
|
-
├── mcp.mjs Fixed launcher for the shared Pomerado runtime
|
|
106
|
-
├── mcp.json Standard MCP server entry, with no key
|
|
107
|
-
└── README.md Commands and usage for this integration
|
|
99
|
+
Set up Pomerado for me by following https://raw.githubusercontent.com/Pomerado/pomerado/main/docs/agent-setup.md
|
|
108
100
|
```
|
|
109
101
|
|
|
110
|
-
|
|
111
|
-
2. Add the server to your client, or copy the entry in `mcp.json` into a client that reads an `mcpServers` file.
|
|
112
|
-
3. Make sure the server gets `OPENAI_API_KEY` from its environment. Generated integrations still use Guardian.
|
|
113
|
-
4. Reload the MCP configuration in your client and ask it to use the integration.
|
|
114
|
-
|
|
115
|
-
> Use example_reader to read the page heading.
|
|
116
|
-
|
|
117
|
-
The integration MCP exposes a tool named after your integration, with its arguments nested under `input`. It also provides `get_job`, `provide_input` and `cancel_job` for calls that need an answer or more time.
|
|
118
|
-
|
|
119
|
-
Ordinary calls return the validated operation output. A pending call returns a job ID to continue. Calling the business tool again starts a new execution, including another website write when the integration has write authority.
|
|
120
|
-
|
|
121
|
-
The generated launcher imports your installed Pomerado runtime. Keep that installation available. The launcher source is portable, but its local configuration contains installation paths. Update those paths if you move the integration, Node or Pomerado.
|
|
122
|
-
|
|
123
|
-
## Questions and authentication
|
|
124
|
-
|
|
125
|
-
When a task needs a login, Pomerado can inspect the sign-in form, ask for credentials in chat, and fill them into the browser. It uses the same sign-in and autofill helpers as the Pomerado application.
|
|
102
|
+
Your agent checks your Node version, installs Chromium and adds Pomerado to the client it runs in. It asks before changing anything you didn't mention, and it never asks for your API key in chat.
|
|
126
103
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
Each MCP job owns a fresh browser context and closes it when the job ends. A minted integration does not inherit the mint's signed-in browser. Authenticated runs need their own declared sign-in inputs and implementation. Automatic login replay is not included. The library can keep a signed-in session open across mint and run calls.
|
|
104
|
+
## Create an integration
|
|
130
105
|
|
|
131
|
-
|
|
106
|
+
Ask your agent to create an integration with Pomerado. We call this minting. A good request names the site, describes the task in plain language and says whether the integration should only read or also make changes.
|
|
132
107
|
|
|
133
|
-
|
|
108
|
+
> Use Pomerado to create an integration named example_reader that reads the main heading from https://example.com. Keep it read-only.
|
|
134
109
|
|
|
135
|
-
|
|
136
|
-
<summary>Attach an existing Playwright browser</summary>
|
|
110
|
+
Your agent runs the mint with four tools.
|
|
137
111
|
|
|
138
|
-
|
|
112
|
+
- `mint` starts a job from a name, a URL, a task, an optional example input and `read` or `write` authority. It returns a job ID right away
|
|
113
|
+
- `get_job` waits up to 30 seconds for progress, a question or the result. Checking a job never restarts the work
|
|
114
|
+
- `provide_input` sends your answer when Pomerado asks a question. Pomerado checks the answer against the question's format
|
|
115
|
+
- `cancel_job` stops the job and closes its browser. An action already sent to a website may still have taken effect
|
|
139
116
|
|
|
140
|
-
|
|
141
|
-
args = ["/absolute/path/to/pomerado/dist/typescript/src/standalone/mcp-cli.js", "mint", "--root", "/absolute/path/to/integrations", "--endpoint", "ws://your-browser-host/playwright-endpoint"]
|
|
142
|
-
```
|
|
117
|
+
Authority decides what an integration is allowed to do, so choose it deliberately. Your agent picks one when it calls `mint`, and the tool tells it to ask you before choosing `write`.
|
|
143
118
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
119
|
+
- Use `read` when the task only looks at a website
|
|
120
|
+
- Use `write` only when the task changes something, such as submitting a form or making a booking
|
|
121
|
+
- A write mint performs the action once while it builds, then reviews the final source without repeating it
|
|
122
|
+
- A read mint that finds the task needs a change asks to switch to write, and your agent's answer decides
|
|
123
|
+
- A run doesn't check authority, intent or sign-in origins, and edits to `src/` or `deployment.json` aren't reviewed
|
|
149
124
|
|
|
150
|
-
|
|
125
|
+
Names start with a lowercase letter and use only lowercase letters, digits and underscores. The integration's folder must not exist yet. Each mint gets 20 minutes of active work, and time spent waiting for your answers doesn't count against it.
|
|
151
126
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
---
|
|
127
|
+
## Use your integration
|
|
155
128
|
|
|
156
|
-
|
|
129
|
+
When minting finishes, Pomerado saves the integration as a folder of source code and returns its paths.
|
|
157
130
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
| `typescript/src/destinations/` | Shared sign-in inspection, autofill and trusted credential entry |
|
|
167
|
-
| `typescript/src/inputs/` | Input validation, terminal collection and per-session secrets |
|
|
168
|
-
| `typescript/src/execution/` | Local workspaces, child processes and native Playwright adapter |
|
|
169
|
-
| `typescript/src/standalone/` | Local library, terminal and MCP composition |
|
|
170
|
-
| `typescript/src/mcp/schema.ts` | Pure schema adapter shared with the production MCP |
|
|
171
|
-
| `typescript/authoring/` | Shared prompts and examples, with sections a host can replace |
|
|
172
|
-
|
|
173
|
-
<details>
|
|
174
|
-
<summary>Runtime boundaries and browser compatibility</summary>
|
|
175
|
-
|
|
176
|
-
Generated code keeps the application's browser call shape.
|
|
177
|
-
|
|
178
|
-
```js
|
|
179
|
-
const response = await kernel.browsers.playwright.execute(sessionId, {
|
|
180
|
-
code: "return await page.title();",
|
|
181
|
-
timeout_sec: 30,
|
|
182
|
-
});
|
|
131
|
+
```text
|
|
132
|
+
pomerado-integrations/example_reader/
|
|
133
|
+
├── src/ Generated operation modules
|
|
134
|
+
├── pomerado.json Entrypoint and input and output schemas
|
|
135
|
+
├── deployment.json Tool name, description, URL, task and authority
|
|
136
|
+
├── mcp.mjs Launcher for the shared Pomerado runtime
|
|
137
|
+
├── mcp.json Standard MCP server entry, with no key
|
|
138
|
+
└── README.md Add commands for each MCP client
|
|
183
139
|
```
|
|
184
140
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
141
|
+
1. Open the integration's `README.md`. It has the add command for each major client with your paths already filled in
|
|
142
|
+
2. Add the server with that command. Skip the key setup. Running an integration makes no model request, so only minting needs `OPENAI_API_KEY`
|
|
143
|
+
3. Reload your client and ask your agent to use the integration
|
|
188
144
|
|
|
189
|
-
|
|
145
|
+
> Use example_reader to read the page heading.
|
|
190
146
|
|
|
191
|
-
|
|
147
|
+
Each integration appears to your agent as its own MCP server.
|
|
192
148
|
|
|
193
|
-
|
|
149
|
+
- It has one tool named after the integration, with its arguments under `input`
|
|
150
|
+
- It also has `get_job`, `provide_input` and `cancel_job` for calls that need an answer or more time
|
|
151
|
+
- A call returns output that matches the schema in `pomerado.json`, or a job ID to follow up on
|
|
152
|
+
- Each call is a new run. With write authority, calling again performs the write again
|
|
153
|
+
- The integration runs on the Pomerado installation that minted it. For a stable path, install globally with `npm install -g pomerado` and use `pomerado-mcp` in place of `npx -y -p pomerado pomerado-mcp`
|
|
194
154
|
|
|
195
|
-
|
|
155
|
+
## Open source and Pomerado Cloud
|
|
196
156
|
|
|
197
|
-
|
|
198
|
-
<summary>Library and terminal use</summary>
|
|
157
|
+
This repository is the complete Pomerado core, released under the MIT license. Everything you need to mint integrations and run them yourself is here, with no Pomerado account required.
|
|
199
158
|
|
|
200
|
-
The
|
|
159
|
+
- The minter, which builds integrations in a real Chromium browser
|
|
160
|
+
- The minting harness and prompts that Pomerado Cloud also builds on
|
|
161
|
+
- Guardian, which reviews each browser action and the finished source while minting, not when an integration runs
|
|
162
|
+
- The standalone host, which serves each integration as an MCP server on your own machine
|
|
163
|
+
- The integrations themselves, saved as source code in your folder that you own
|
|
201
164
|
|
|
202
|
-
|
|
203
|
-
import { Effect } from "effect";
|
|
204
|
-
import { createPomerado, makeTerminalAsker } from "pomerado";
|
|
165
|
+
[Pomerado Cloud](https://pomerado.ai) runs this same core as a managed service. It adds the operations that production use needs.
|
|
205
166
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
url: "https://example.com",
|
|
212
|
-
intent: "Read the main heading",
|
|
213
|
-
input: {},
|
|
214
|
-
effect: "read",
|
|
215
|
-
};
|
|
216
|
-
const result = yield* session.mint(request);
|
|
217
|
-
if (result.artifact === undefined) throw new Error(result.summary);
|
|
218
|
-
console.log(yield* session.run(result.artifact, request));
|
|
219
|
-
}),
|
|
220
|
-
),
|
|
221
|
-
);
|
|
222
|
-
```
|
|
167
|
+
- Hosting for your integrations and their jobs
|
|
168
|
+
- OAuth brokerage and saved logins
|
|
169
|
+
- Access control over who can use each integration
|
|
170
|
+
- A managed browser fleet that handles bot protection
|
|
171
|
+
- Breakage detection that notices when a site changes and repairs the integration automatically
|
|
223
172
|
|
|
224
|
-
|
|
173
|
+
## Documentation for humans and agents
|
|
225
174
|
|
|
226
|
-
|
|
175
|
+
- [Getting started](docs/getting-started.md) covers install, client settings, a first integration and troubleshooting.
|
|
176
|
+
- [Agent setup](docs/agent-setup.md) gives an AI agent the steps to install Pomerado for you.
|
|
177
|
+
- [How it works](docs/how-it-works.md) covers the minter, Guardian, the runtime, jobs and the library.
|
|
178
|
+
- [AGENTS.md](AGENTS.md) tells coding agents how to change this repository.
|
|
179
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) covers building from source and how changes land.
|
|
180
|
+
- [RELEASING.md](docs/RELEASING.md) covers how npm releases are built and verified.
|
|
227
181
|
|
|
228
|
-
|
|
229
|
-
- Use explicit `pomerado/core/*` subpaths such as `pomerado/core/mint/harness`, `pomerado/core/guardian/review` and `pomerado/core/runtime/host-execute` for hosted library composition. The export map lists supported modules.
|
|
230
|
-
- Use `pomerado/testing/*` for reusable test helpers and fixtures. Vitest is an optional peer for helpers that need it.
|
|
231
|
-
- Use `getAuthoringDirectory` and `getGuardianPolicyPath` from `pomerado/assets` for installed prompt and policy paths. These paths resolve relative to the package.
|
|
232
|
-
- `loadAuthoringSkills` and `loadWorkspaceGuide` from `pomerado/core/mint/skills` render each named authoring section's standalone text by default. A host that supplies its own text for those sections composes the directory first, then loads it in `"hosted"` mode, which refuses any section left uncomposed.
|
|
182
|
+
## Repository guide
|
|
233
183
|
|
|
234
|
-
|
|
184
|
+
| Path | Contents |
|
|
185
|
+
| --- | --- |
|
|
186
|
+
| `typescript/src/` | Minter, Guardian, runtime, browser helpers and the local MCP host |
|
|
187
|
+
| `typescript/authoring/` | Shared prompts and examples, with sections a host can replace |
|
|
188
|
+
| `typescript/tests/` | Unit tests and browser tests with local fixture sites |
|
|
189
|
+
| `tools/` | Build helpers and the CI scans |
|
|
190
|
+
| `docs/` | Guides for users, agents and maintainers |
|
|
191
|
+
| `third-party/` | Licenses for adapted third-party code |
|
|
235
192
|
|
|
236
|
-
|
|
193
|
+
[How it works](docs/how-it-works.md#source-layout) lists each module under `typescript/src/`.
|
|
237
194
|
|
|
238
195
|
## Contributing
|
|
239
196
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
corepack pnpm exec playwright install chromium
|
|
245
|
-
corepack pnpm test:browser
|
|
246
|
-
```
|
|
197
|
+
- Issues are welcome.
|
|
198
|
+
- Outside pull requests open once the review and approval gate in [CONTRIBUTING.md](CONTRIBUTING.md) is live.
|
|
199
|
+
- Security problems go privately through **Report a vulnerability** on the [Security tab](https://github.com/Pomerado/pomerado/security).
|
|
200
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) has the clone, build and test steps.
|
|
247
201
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
Outside pull requests are not accepted yet. They open once the review and approval gate described in [CONTRIBUTING.md](CONTRIBUTING.md) is live. Issues are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for how changes land and how to report a vulnerability privately.
|
|
251
|
-
|
|
252
|
-
Public tests use synthetic sites and data. Keep customer-specific incidents, private credentials and internal issue references out of public contributions. CI enforces this with a gitleaks secret scan and a public content scan. Run `node tools/check-public-content.ts` before you push. Link a public issue by its full URL.
|
|
253
|
-
|
|
254
|
-
- Build and test the package before publishing an explicit versioned release. The release workflow validates the packed artifact before npm publication.
|
|
255
|
-
- Adopt a tested release in Cloud through an exact dependency pin and locked integrity. Update the controller and sandbox images together.
|
|
256
|
-
- Roll Cloud back by restoring its previous package pin and matching image versions. Public commits do not update Cloud automatically.
|
|
257
|
-
|
|
258
|
-
The clone and build quickstart works independently of npm releases. Contributors can test Cloud against a locally built package before publishing a new version.
|
|
259
|
-
|
|
260
|
-
---
|
|
202
|
+
## License
|
|
261
203
|
|
|
262
204
|
Copyright (c) 2026 Pomerado AI, Inc. Licensed under the MIT License (`MIT`). See [LICENSE](LICENSE).
|
|
263
205
|
|
|
@@ -10,6 +10,12 @@ screen's fields and its submit control, and the host fills them from the private
|
|
|
10
10
|
the submit. You never see, type, request or read back a credential. Start with a `signInStep` for
|
|
11
11
|
the first screen. If a step fails, inspect the site and correct the steps in this browser.
|
|
12
12
|
|
|
13
|
+
A code the site sends as part of signing in, by text message, email or an authenticator app, is
|
|
14
|
+
part of the sign-in: map its screen as a `signInStep` with a `code` field and let `authenticate`
|
|
15
|
+
get the code. Never ask for it separately with `request_input`. A `request_input` secret question
|
|
16
|
+
for a code is only for a later protected action after sign-in, when the site asks for another code
|
|
17
|
+
to confirm it.
|
|
18
|
+
|
|
13
19
|
Sign in only when the task needs it (the request asks, the task is about the caller's own account,
|
|
14
20
|
or the data sits behind a login wall). Try a public task signed out first.
|
|
15
21
|
|
|
@@ -59,10 +65,11 @@ ask with `request_input` right away. A preselected option says nothing about the
|
|
|
59
65
|
|
|
60
66
|
<!-- pomerado:section auth.signed-out-flow -->
|
|
61
67
|
|
|
62
|
-
Record a field
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
Record a field only after observing its unique visible enabled match in the intended frame and
|
|
69
|
+
form, and a submit after observing its unique visible match there, even one the page enables only
|
|
70
|
+
once the fields hold input. Validate the complete live login and a fresh signed-out replay from
|
|
71
|
+
the stable login URL. A saved DOM supports locator matching and extraction; it cannot prove live
|
|
72
|
+
controls are actionable, their event handlers work or authentication succeeds.
|
|
66
73
|
|
|
67
74
|
<!-- pomerado:section auth.partial-flow -->
|
|
68
75
|
|
|
@@ -142,6 +149,10 @@ browser. A failed host check leaves this browser available for another evidenced
|
|
|
142
149
|
that sign-in could not be verified when the site or the remaining allowance prevents recovery.
|
|
143
150
|
Never send a visibly rejected value again. There is no provider-login fallback.
|
|
144
151
|
|
|
152
|
+
When the host refuses to type into a field (`AutofillRefused`), its answer names the field, the
|
|
153
|
+
check that refused it and why. Fix that cause before sending the step again: the same refusal of
|
|
154
|
+
the same field on the same screen three times in a row ends sign-in in this build.
|
|
155
|
+
|
|
145
156
|
<!-- pomerado:section auth.after-recovery -->
|
|
146
157
|
|
|
147
158
|
# Every sign-in ends with its check
|
|
@@ -166,10 +177,10 @@ A direct sign-in request signs in with one host-filled HTTP request instead of a
|
|
|
166
177
|
|
|
167
178
|
## Standalone live authentication
|
|
168
179
|
|
|
169
|
-
Observe the current login screen with a reviewed read-only probe: its URL, frames, visible field labels/types/names/autocomplete, form destination and
|
|
180
|
+
Observe the current login screen with a reviewed read-only probe: its URL, frames, visible field labels/types/names/autocomplete, form destination and submit. Never read control values or enter credentials in source. Pass `signInStep` to execute purpose `authenticate`, target `liveBrowser`, with the evidenced reusable `loginUrl`.
|
|
170
181
|
|
|
171
182
|
Fields use the same slots and format declarations. `username` lists every accepted identifier kind; password/code/recovery-code/date-of-birth/ZIP match that observed field's purpose. The host obtains the needed value through the caller's protected input callback or masked terminal, checks the original field/document/origin/focus binding and inserts privately. No saved credential, seed, SMS automation or recipe is used. No value enters your model context or files.
|
|
172
183
|
|
|
173
|
-
Inspect each subsequent screen and send its observed step. A method or account choice needs caller input before selection. Wait for and verify an observed signed-in marker; disappearance of the login form is insufficient. Rejection requires caller correction and never authorizes replay of a private submission. Popup/frame sign-in uses the observed host target and configured sign-in origins, with the same destination guard.
|
|
184
|
+
Inspect each subsequent screen and send its observed step. After a step whose submit the host clicked, its result names `captures/after-submit/<step>.json`, where the host saved the next screen's controls: role, name or label, input type, and whether each is required, visible and enabled, never a value. Read it first to see what the screen asks for, then probe read-only only for what it lacks, such as a selector or form destination. A failed step's result shows the last saved controls inline, at most 30, and the file holds the rest. A method or account choice needs caller input before selection. Wait for and verify an observed signed-in marker; disappearance of the login form is insufficient. Rejection requires caller correction and never authorizes replay of a private submission. Popup/frame sign-in uses the observed host target and configured sign-in origins, with the same destination guard.
|
|
174
185
|
|
|
175
186
|
pomerado:section auth.direct-request:end -->
|
|
@@ -10,7 +10,9 @@ Try first. Ask only for what the page or the caller uniquely knows at that point
|
|
|
10
10
|
- a choice whose options exist only once the run reaches them: the open seats of the
|
|
11
11
|
flight the caller just chose, the delivery slots for the cart the run just filled, or
|
|
12
12
|
which of the account's saved travelers or addresses to use;
|
|
13
|
-
- a code the site sends
|
|
13
|
+
- a code the site sends to confirm a protected action after sign-in, such as a confirmation code
|
|
14
|
+
by text or email. A code that is part of signing in is the host's: a `code` field of the
|
|
15
|
+
`authenticate` step, never a question;
|
|
14
16
|
- a fact only the caller has that the site now asks for.
|
|
15
17
|
|
|
16
18
|
<!-- pomerado:section caller-input.published-input -->
|
|
@@ -166,9 +166,11 @@ is bounded; never describe a truncated list as complete.
|
|
|
166
166
|
|
|
167
167
|
Supported login challenges during `authenticate` belong to the host's sign-in
|
|
168
168
|
(autofill or an explicit direct HTTP step) and its protected input requests. Generated `operation.run` and `explore` code
|
|
169
|
-
never request or enter a sign-in code, or sign in themselves
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
never request or enter a sign-in code, or sign in themselves: an SMS, email or authenticator code
|
|
170
|
+
that is part of signing in is a `code` field of the `authenticate` step (auth skill), never asked
|
|
171
|
+
separately. A code the site sends later, to confirm a protected action after sign-in, is different:
|
|
172
|
+
declare it as a `secret` question and ask it with `ask`, as the caller-input skill's
|
|
173
|
+
`caller-code.ts` shows. A missing ordinary page
|
|
172
174
|
control alone does not establish a human-verification challenge. Observe the
|
|
173
175
|
current page state within the existing deadline. When a few distinct attempts have
|
|
174
176
|
not found the way, ask the caller for directions with `request_input` before
|
|
@@ -13,6 +13,18 @@ or an agent's remembered Page is not a cursor authenticity check.
|
|
|
13
13
|
|
|
14
14
|
<!-- pomerado:section pagination.no-recreated-writes -->
|
|
15
15
|
|
|
16
|
+
## Append pagination ("load more")
|
|
17
|
+
|
|
18
|
+
Some pages page by appending: a "Load more" or "Show more" control, or scrolling to the
|
|
19
|
+
bottom, adds rows to the same list instead of navigating. Detect it when activating the
|
|
20
|
+
control leaves the URL and page number unchanged while the row count grows, or when a
|
|
21
|
+
scroll adds rows. Then page by repeating that one action and reading only the rows it
|
|
22
|
+
added, identified by stable ID, until the control disappears or disables, a step adds no
|
|
23
|
+
new rows, or the requested count is met. Bound the loop: a fixed step cap and a time
|
|
24
|
+
budget, with a short wait for rows after each step. On hitting a bound, return the rows
|
|
25
|
+
read with an explicit reason and no pretend next cursor. Never treat a repeated click as
|
|
26
|
+
safe if it could submit or change anything.
|
|
27
|
+
|
|
16
28
|
Use and test both warm and fresh paths, including expired state, changed live data,
|
|
17
29
|
wrong query/account and unsupported reconstruction. `references/pagination.ts`
|
|
18
30
|
provides a compiling authoring pattern; its hooks are site logic, not platform
|
|
@@ -132,9 +132,11 @@ add-on toggle, a pre-selected checkbox or a lone saved payment method is still a
|
|
|
132
132
|
to ask about. Read the path's options with read-only exploration where you can and settle them before
|
|
133
133
|
the first act step where possible; a question during the session waits in place. Take a site default only for a choice that is not a
|
|
134
134
|
credential, not a write and easy to reverse, and list it in `finish_build` `assumptions`. A full
|
|
135
|
-
new login goes through execute purpose `authenticate
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
new login goes through execute purpose `authenticate`: an SMS, email or authenticator code that
|
|
136
|
+
is part of signing in is a `code` field of its `signInStep`, which the host fills or asks the
|
|
137
|
+
caller for, so never ask for it with `request_input`. The standalone code path, a
|
|
138
|
+
`request_input` secret question, is only for a later protected action after sign-in, when the
|
|
139
|
+
site asks for another code to confirm it; `authenticate` is never started just for such a code. You may ask after live
|
|
138
140
|
execution has closed or while a write's outcome is uncertain; after the answer, verify the
|
|
139
141
|
current state before writing again.
|
|
140
142
|
|
|
@@ -247,9 +249,9 @@ Use the same canonical operation SDK and Kernel-shaped browser execute syntax. T
|
|
|
247
249
|
|
|
248
250
|
`read_source` reads source, installed skills and references in bounded ranges. `apply_patch` edits only authored directories. `execute` supports `liveBrowser` and `pureFiles`; every command or live execution receives fresh Guardian review. `exec_command` runs a local process over caller-owned files with an explicit environment; it is not an operating-system or network sandbox. Never use a command, Node fetch or socket to access the website; browser work stays in reviewed Playwright calls. `request_input`, `report_blocked` and `finish_build` use their existing request shapes.
|
|
249
251
|
|
|
250
|
-
Inspect the current page with bounded read-only probes. Use only caller-supplied input, answers and observed page choices. Keep observations focused; there are no recorder captures to
|
|
252
|
+
Inspect the current page with bounded read-only probes. Use only caller-supplied input, answers and observed page choices. Keep observations focused; there are no recorder captures to retain. A timeout or browser loss leaves effects uncertain: read back current state before repeating an action and never replay an uncertain write.
|
|
251
253
|
|
|
252
|
-
For sign-in, inspect the actual current fields without reading their values, then submit an observed `signInStep` through execute purpose `authenticate`. The host collects credentials through protected callback or masked terminal input and inserts them through the guarded credential channel. Model text, files and ordinary output never contain passwords or codes. A secret answer is an opaque handle; apply the core skill's whole-value restrictions.
|
|
254
|
+
For sign-in, inspect the actual current fields without reading their values, then submit an observed `signInStep` through execute purpose `authenticate`. The host collects credentials through protected callback or masked terminal input and inserts them through the guarded credential channel. After each step whose submit it clicked, the host saves the next screen's controls (role, name or label, input type, required, visible, enabled; never a value) to `captures/after-submit/<step>.json` and its result names that file: read it with `read_source` or `exec_command` like any other file. A step that fails also shows the last saved controls inline, at most 30. Model text, files and ordinary output never contain passwords or codes. A secret answer is an opaque handle; apply the core skill's whole-value restrictions.
|
|
253
255
|
|
|
254
256
|
A write performs the caller's task once as live act steps, reads back a supported confirmation, then composes the operation from those steps. Do not execute the composed write again. Finish with honest coverage and the confirming execution ID; returning integration files does not justify a second website write.
|
|
255
257
|
|
|
@@ -22,7 +22,9 @@ interface FillInput {
|
|
|
22
22
|
* nothing reached the site: a lost answer is `uncertain`, a control refused before a field's typing
|
|
23
23
|
* fails that field, and one refused before the click, or a submission refused as it fires, refuses
|
|
24
24
|
* the submit. That click ran, though, so the report says so (`clicked`): the page's own handlers
|
|
25
|
-
* ran on it, and what the step filled may have gone out.
|
|
25
|
+
* ran on it, and what the step filled may have gone out. A submit the page keeps disabled is never
|
|
26
|
+
* clicked: the host waits for the page to enable it once the fields are filled, and when it stays
|
|
27
|
+
* disabled the report says so (`stayed_disabled`).
|
|
26
28
|
*/
|
|
27
29
|
export declare const fillAutofillStep: (input: FillInput) => Effect.Effect<AutofillStepReport>;
|
|
28
30
|
export {};
|