@open-everywhere/create 0.2.1 → 0.3.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/README.md +16 -5
- package/bin/create-open-everywhere.js +4 -0
- package/package.json +3 -3
- package/src/cli.ts +37 -4
- package/src/deploy-status.ts +84 -0
- package/src/engine.ts +4 -3
- package/src/env-file.ts +11 -9
- package/src/scaffold.ts +21 -0
- package/src/steps/database.ts +4 -3
- package/src/steps/env-checklist.ts +28 -9
- package/src/steps/slack.ts +2 -2
- package/template/.env.example +10 -1
- package/template/AGENTS.md +17 -3
- package/template/README.md +14 -1
- package/template/claude/skills/quickstart-open-everywhere/SKILL.md +59 -22
- package/template/claude/skills/upgrade-open-everywhere/SKILL.md +29 -13
- package/template/scripts/goldens/roster-plan.txt +156 -0
package/README.md
CHANGED
|
@@ -27,7 +27,9 @@ npm create @open-everywhere my-agent
|
|
|
27
27
|
This scaffolds the quickstart app into `./my-agent`, prints the next steps and exits. It never
|
|
28
28
|
prompts. The directory must be new or empty. A fresh clone of an empty repository holds only `.git`,
|
|
29
29
|
and it counts as empty: run `npx @open-everywhere/create .` inside it. The scaffold refuses a
|
|
30
|
-
directory that holds anything else.
|
|
30
|
+
directory that holds anything else. Run inside an empty clone named `my-agent`,
|
|
31
|
+
`npx @open-everywhere/create my-agent` would make `my-agent/my-agent/`, so it refuses and prints the
|
|
32
|
+
`.` command instead. To nest on purpose, create the inner directory first. The app depends on the eight `@open-everywhere/*` libraries at
|
|
31
33
|
this CLI's own version — plus this package itself, as a dev dependency, for its `check` script — and
|
|
32
34
|
on `eve` at the pin core declares; its `postinstall` applies the eve patch. Its roster mounts the launch surfaces: Slack, Notion and GitHub. The app carries `AGENTS.md`,
|
|
33
35
|
a `.mcp.json` for the `open-everywhere-ops` MCP server and the `quickstart-open-everywhere` skill,
|
|
@@ -42,7 +44,10 @@ npx @open-everywhere/create --check
|
|
|
42
44
|
`--check` prompts for nothing, changes nothing, sends no telemetry and never scaffolds. It reports
|
|
43
45
|
each setup step with what is missing and the next command for it. Add `--json` for the same report
|
|
44
46
|
as one JSON object, which is what an agent-driven setup reads. `--route docker` judges against the
|
|
45
|
-
Docker route (the default is `vercel`), and `--host https://<host>` probes a deployment.
|
|
47
|
+
Docker route (the default is `vercel`), and `--host https://<host>` probes a deployment. With
|
|
48
|
+
`--host`, the env step also reads the deployment's public status route (`/eve/v1/oe/status`), so a
|
|
49
|
+
value set only on the deployment (in the Vercel dashboard, say) counts. Without it, the step reads
|
|
50
|
+
only `.env.local` and the shell.
|
|
46
51
|
|
|
47
52
|
Run it from inside an Open Everywhere app — a scaffolded one, or a clone of the repository. From a
|
|
48
53
|
directory that is not an app, it reports an unsatisfied repo step and tells you to scaffold one.
|
|
@@ -51,7 +56,13 @@ The same step list written out for a human is
|
|
|
51
56
|
[Setup steps](https://github.com/open-everywhere/open-everywhere/blob/main/docs/deploy/setup-steps.md).
|
|
52
57
|
That page is generated from the step list this command reports, so the two cannot drift.
|
|
53
58
|
|
|
54
|
-
This CLI starts on Node 18 or newer. The app it scaffolds needs
|
|
59
|
+
This CLI starts on Node 18 or newer, so `--check` can report an old Node. The app it scaffolds needs
|
|
60
|
+
Node 24, so a scaffold on an older Node exits non-zero and writes nothing.
|
|
61
|
+
|
|
62
|
+
The scaffolded app sends anonymous usage telemetry when it runs, ON by default. Its `README.md`
|
|
63
|
+
says how to turn it off (`OE_TELEMETRY=off` on the deployment), and the full disclosure is
|
|
64
|
+
[Telemetry](https://github.com/open-everywhere/open-everywhere/blob/main/docs/deploy/telemetry.md).
|
|
65
|
+
This CLI itself sends none.
|
|
55
66
|
|
|
56
67
|
## Docs
|
|
57
68
|
|
|
@@ -61,8 +72,8 @@ This CLI starts on Node 18 or newer. The app it scaffolds needs Node 24.
|
|
|
61
72
|
|
|
62
73
|
## Status
|
|
63
74
|
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
This package is pre-1.0: the API surface is expected to change, and a minor release may
|
|
76
|
+
break you. Pin an exact version.
|
|
66
77
|
|
|
67
78
|
## Licence
|
|
68
79
|
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
// and `npm create @open-everywhere` resolves it there. The bin keeps the command name a scaffolded
|
|
12
12
|
// app's `check` script already runs. One bin is declared, so `npm exec` picks it either way.
|
|
13
13
|
//
|
|
14
|
+
// THE NODE GATE IS NOT HERE. The scaffold refuses a Node below core's range (src/cli.ts
|
|
15
|
+
// `scaffoldNodeRefusal`, OPE-2399), and `--check` must still run on that Node to report it. Both
|
|
16
|
+
// need the parsed argv, so the gate lives in the TS entry, which tsx runs on any Node it supports.
|
|
17
|
+
//
|
|
14
18
|
// WHAT IT WRITES. With a `<dir>` argument it SCAFFOLDS, and that is the only write: it copies the
|
|
15
19
|
// quickstart app (`template/`) into a new or empty `<dir>` (`src/scaffold.ts`) and prints the next
|
|
16
20
|
// steps. With `--check` it only REPORTS on the current directory — every step is a pure `check()`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-everywhere/create",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "npx scaffold and setup check for Open Everywhere — one step engine, reported by --check for an agent-led setup.",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"test:env-pipe": "tsx scripts/env-pipe-test.ts"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@open-everywhere/core": "0.
|
|
50
|
-
"@open-everywhere/provider-slack": "0.
|
|
49
|
+
"@open-everywhere/core": "0.3.0",
|
|
50
|
+
"@open-everywhere/provider-slack": "0.3.0",
|
|
51
51
|
"tsx": "^4.23.9"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
package/src/cli.ts
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
// TWO JOBS, AND NOTHING ELSE (OPE-2233):
|
|
6
6
|
// 1. `<dir>` SCAFFOLDS the quickstart app (scaffold.ts) and prints what to do next.
|
|
7
7
|
// 2. `--check [--json]` REPORTS the setup steps for the current directory. Pure `check()` calls:
|
|
8
|
-
// no prompts, no writes, no network except the `--host` deploy probe
|
|
8
|
+
// no prompts, no writes, no network except the two `--host` reads (the deploy probe and the
|
|
9
|
+
// status route), and no telemetry. A scaffold on a Node below core's range is refused (OPE-2399).
|
|
9
10
|
//
|
|
10
11
|
// 🔴 THERE IS NO INTERACTIVE WIZARD, AND THIS CLI SENDS NO TELEMETRY. The TTY wizard is retired:
|
|
11
12
|
// setup is AGENT-LED (open the app in a coding agent, which reads AGENTS.md and drives the
|
|
@@ -17,8 +18,9 @@
|
|
|
17
18
|
import { checkAll, isSetupRoute, SETUP_ROUTES, type SetupRoute, type StepContext } from "./engine.js";
|
|
18
19
|
import { SETUP_STEPS } from "./steps/index.js";
|
|
19
20
|
import { CLI_VERSION } from "./version.js";
|
|
20
|
-
import { initGitRepo, scaffoldApp, ScaffoldRefusal } from "./scaffold.js";
|
|
21
|
+
import { initGitRepo, nestedNameRefusal, scaffoldApp, ScaffoldRefusal } from "./scaffold.js";
|
|
21
22
|
import { resolve } from "node:path";
|
|
23
|
+
import { coreNodeRange, nodeRangeSatisfied } from "@open-everywhere/core/agent/ops/package-info.js";
|
|
22
24
|
import { pathToFileURL } from "node:url";
|
|
23
25
|
import { slackAppNameProblem } from "@open-everywhere/provider-slack/agent/app-manifest.js";
|
|
24
26
|
import { readAppNaming } from "./app-naming.js";
|
|
@@ -39,7 +41,8 @@ const USAGE = `create-open-everywhere [<dir>] [--check [--json]] [--route vercel
|
|
|
39
41
|
two supported routes. A local run is the development loop
|
|
40
42
|
after a deploy, never a route.
|
|
41
43
|
--host <url> The deployment's public origin. The build + deploy step
|
|
42
|
-
probes its Slack route
|
|
44
|
+
probes its Slack route, and the env step reads the env
|
|
45
|
+
verdicts its status route (/eve/v1/oe/status) reports.
|
|
43
46
|
--app-name <name>
|
|
44
47
|
The Slack app's name in the manifest the Slack step prints.
|
|
45
48
|
Default: the app's identity.name setting, else "Open
|
|
@@ -181,6 +184,26 @@ function runScaffold(target: string): string | undefined {
|
|
|
181
184
|
}
|
|
182
185
|
}
|
|
183
186
|
|
|
187
|
+
/**
|
|
188
|
+
* The scaffold's Node gate (OPE-2399). The app needs the Node range `@open-everywhere/core` declares,
|
|
189
|
+
* and a scaffold on an older Node used to succeed with only npm's EBADENGINE warnings, so the person
|
|
190
|
+
* met the failure later and further from its cause. The gate refuses BEFORE a byte is written.
|
|
191
|
+
*
|
|
192
|
+
* It gates the scaffold only. `--check` still runs on an old Node, because its prerequisites step is
|
|
193
|
+
* the report that says which Node to install. An unreadable range does not block: the
|
|
194
|
+
* prerequisites step reports that case as "cannot tell".
|
|
195
|
+
*/
|
|
196
|
+
export function scaffoldNodeRefusal(version: string, range: string | undefined): string | undefined {
|
|
197
|
+
if (range === undefined || nodeRangeSatisfied(range, version) !== false) return undefined;
|
|
198
|
+
return `refusing to scaffold: Open Everywhere needs Node ${range} (found ${version}). Run \`nvm install 24 && nvm use 24\`, then run this command again.`;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** What `main` reads from the process, injectable so a test can drive any Node version. */
|
|
202
|
+
export interface MainOptions {
|
|
203
|
+
readonly nodeVersion?: string;
|
|
204
|
+
readonly nodeRange?: string;
|
|
205
|
+
}
|
|
206
|
+
|
|
184
207
|
/** What to do after a scaffold. The scaffold never prompts, so this is always printed. */
|
|
185
208
|
function nextSteps(target: string): string {
|
|
186
209
|
return [
|
|
@@ -197,7 +220,7 @@ function nextSteps(target: string): string {
|
|
|
197
220
|
].join("\n");
|
|
198
221
|
}
|
|
199
222
|
|
|
200
|
-
export async function main(argv: readonly string[]): Promise<number> {
|
|
223
|
+
export async function main(argv: readonly string[], options: MainOptions = {}): Promise<number> {
|
|
201
224
|
if (argv.includes("--help") || argv.includes("-h")) {
|
|
202
225
|
console.log(USAGE);
|
|
203
226
|
return 0;
|
|
@@ -226,6 +249,16 @@ export async function main(argv: readonly string[]): Promise<number> {
|
|
|
226
249
|
console.error("--check changes nothing, so it cannot scaffold. Scaffold first, then run --check from inside the app.");
|
|
227
250
|
return 2;
|
|
228
251
|
}
|
|
252
|
+
const nodeRefusal = scaffoldNodeRefusal(options.nodeVersion ?? process.versions.node, "nodeRange" in options ? options.nodeRange : coreNodeRange());
|
|
253
|
+
if (nodeRefusal !== undefined) {
|
|
254
|
+
console.error(nodeRefusal);
|
|
255
|
+
return 1;
|
|
256
|
+
}
|
|
257
|
+
const nested = nestedNameRefusal(target, process.cwd());
|
|
258
|
+
if (nested !== undefined) {
|
|
259
|
+
console.error(nested);
|
|
260
|
+
return 1;
|
|
261
|
+
}
|
|
229
262
|
const dir = runScaffold(target);
|
|
230
263
|
if (dir === undefined) return 1;
|
|
231
264
|
console.log(nextSteps(target));
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// The deployment's own env verdicts — `GET <host>/eve/v1/oe/status` (OPE-2399).
|
|
2
|
+
//
|
|
3
|
+
// `--check` reads `.env.local` and this shell. A Vercel app whose values were set in the dashboard
|
|
4
|
+
// holds them only on the deployment, so the env step read it as all-missing. With `--host`, the env
|
|
5
|
+
// step also reads the deployment's public status route and reports the verdicts the deployment gives
|
|
6
|
+
// for its own environment. The route is unauthenticated by design and carries only closed-vocabulary
|
|
7
|
+
// verdicts plus prose core wrote (packages/core/agent/ops/status.ts), so no secret crosses here.
|
|
8
|
+
//
|
|
9
|
+
// This module imports nothing from core. The route path is a copy of core's `OE_STATUS_PATH`, and
|
|
10
|
+
// scripts/engine-test.ts fails when the two differ: importing `ops/status.ts` would pull the
|
|
11
|
+
// access, sandbox and store resolvers into a CLI that must start before anything is configured.
|
|
12
|
+
|
|
13
|
+
/** The status route. A COPY of core's `OE_STATUS_PATH` — engine-test.ts pins the two equal. */
|
|
14
|
+
export const DEPLOY_STATUS_PATH = "/eve/v1/oe/status";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The status rows that judge the deployment's ENVIRONMENT, in the order the env step reports them.
|
|
18
|
+
* `secrets` is the root-of-trust pair (DATABASE_URL and the credential key), `postgres` is the
|
|
19
|
+
* store selection that DATABASE_URL drives, and `model-route` is the gateway. The other rows (Node,
|
|
20
|
+
* sandbox, egress, workflow storage, public URL) judge the host, not the env checklist.
|
|
21
|
+
*/
|
|
22
|
+
export const DEPLOYED_ENV_REQUIREMENTS = ["secrets", "postgres", "model-route"] as const;
|
|
23
|
+
|
|
24
|
+
export type Verdict = "yes" | "no" | "unknown";
|
|
25
|
+
|
|
26
|
+
export interface DeployedRequirement {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly met: Verdict;
|
|
29
|
+
readonly detail: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type DeployedStatusRead =
|
|
33
|
+
| { readonly ok: true; readonly url: string; readonly requirements: readonly DeployedRequirement[] }
|
|
34
|
+
| { readonly ok: false; readonly url: string; readonly detail: string };
|
|
35
|
+
|
|
36
|
+
const VERDICTS: readonly string[] = ["yes", "no", "unknown"];
|
|
37
|
+
|
|
38
|
+
/** The rows of a status document, or `undefined` when the body is not one. */
|
|
39
|
+
export function parseStatusRequirements(body: unknown): DeployedRequirement[] | undefined {
|
|
40
|
+
if (typeof body !== "object" || body === null) return undefined;
|
|
41
|
+
const rows = (body as { requirements?: unknown }).requirements;
|
|
42
|
+
if (!Array.isArray(rows)) return undefined;
|
|
43
|
+
const out: DeployedRequirement[] = [];
|
|
44
|
+
for (const row of rows) {
|
|
45
|
+
if (typeof row !== "object" || row === null) return undefined;
|
|
46
|
+
const { id, met, detail } = row as Record<string, unknown>;
|
|
47
|
+
if (typeof id !== "string" || typeof met !== "string" || !VERDICTS.includes(met)) return undefined;
|
|
48
|
+
out.push({ id, met: met as Verdict, detail: typeof detail === "string" ? detail : "" });
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Read the deployment's status document. One GET, no retry: the deploy probe owns cold starts. */
|
|
54
|
+
export async function readDeployedStatus(origin: string, fetchImpl: typeof fetch = fetch, timeoutMs = 15_000): Promise<DeployedStatusRead> {
|
|
55
|
+
const url = `${origin}${DEPLOY_STATUS_PATH}`;
|
|
56
|
+
let res: Response;
|
|
57
|
+
try {
|
|
58
|
+
res = await fetchImpl(url, { method: "GET", signal: AbortSignal.timeout(timeoutMs), redirect: "manual" });
|
|
59
|
+
} catch (err) {
|
|
60
|
+
return { ok: false, url, detail: `${url} did not answer (${err instanceof Error ? err.message : String(err)})` };
|
|
61
|
+
}
|
|
62
|
+
if (res.status !== 200) return { ok: false, url, detail: `${url} answered ${res.status}, not the status document` };
|
|
63
|
+
let body: unknown;
|
|
64
|
+
try {
|
|
65
|
+
body = JSON.parse(await res.text());
|
|
66
|
+
} catch {
|
|
67
|
+
return { ok: false, url, detail: `${url} answered 200, but the body is not JSON` };
|
|
68
|
+
}
|
|
69
|
+
const requirements = parseStatusRequirements(body);
|
|
70
|
+
if (requirements === undefined) return { ok: false, url, detail: `${url} answered 200, but the body is not a status document` };
|
|
71
|
+
return { ok: true, url, requirements };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The env step's verdict from a status document. Satisfied when the deployment reports `secrets`
|
|
76
|
+
* as "yes" and no env row as "no". An "unknown" row does not fail the step: the route uses it for
|
|
77
|
+
* "not measured" (no probe registered), never for "probably not". An absent row counts as unknown.
|
|
78
|
+
*/
|
|
79
|
+
export function deployedEnvVerdict(requirements: readonly DeployedRequirement[]): { satisfied: boolean; summary: string } {
|
|
80
|
+
const byId = new Map(requirements.map((r) => [r.id, r]));
|
|
81
|
+
const rows = DEPLOYED_ENV_REQUIREMENTS.map((id) => byId.get(id) ?? { id, met: "unknown" as const, detail: "not in the document" });
|
|
82
|
+
const satisfied = byId.get("secrets")?.met === "yes" && rows.every((r) => r.met !== "no");
|
|
83
|
+
return { satisfied, summary: rows.map((r) => `${r.id}=${r.met} (${r.detail})`).join("; ") };
|
|
84
|
+
}
|
package/src/engine.ts
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
//
|
|
7
7
|
// 🔴 THERE IS NO INTERACTIVE WIZARD (OPE-2233). The TTY wizard, its `WizardIO` prompt surface and
|
|
8
8
|
// every step's `automate()` are retired: setup is AGENT-LED. The agent reads this engine's report
|
|
9
|
-
// and runs the commands with the user's consent
|
|
10
|
-
// `scaffold_credential_key` tools
|
|
9
|
+
// and runs the commands with the user's consent. The ops MCP server's `scaffold_env` /
|
|
10
|
+
// `scaffold_credential_key` tools and the person's own `oe env set <NAME>` (every secret value,
|
|
11
|
+
// OPE-2396) do the writes a step's `automate()` used to do. So this engine
|
|
11
12
|
// is READ-ONLY by construction: `check()` inspects, `guide()` describes, and nothing writes.
|
|
12
13
|
//
|
|
13
14
|
// Resumability is structural, not a bookkeeping flag: `check()` inspects the REAL WORLD (env vars,
|
|
@@ -39,7 +40,7 @@ export interface StepContext {
|
|
|
39
40
|
readonly env: NodeJS.ProcessEnv;
|
|
40
41
|
/** The route the steps judge against. Absent means `vercel`. */
|
|
41
42
|
readonly route?: SetupRoute;
|
|
42
|
-
/** The deployment's public origin (`--host`), for the deploy probe. */
|
|
43
|
+
/** The deployment's public origin (`--host`), for the deploy probe and the env step's status read. */
|
|
43
44
|
readonly host?: string;
|
|
44
45
|
/** The chat app's name (`--app-name`), for the Slack manifest. It wins over {@link agentName}. */
|
|
45
46
|
readonly appName?: string;
|
package/src/env-file.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// Thin .env.local helpers for the setup steps' `check()`s.
|
|
2
2
|
//
|
|
3
3
|
// 🔴 READ-ONLY SINCE OPE-2233. This module used to carry `writeEnvLocal`, which the wizard's
|
|
4
|
-
// `automate()` steps called. Setup is agent-led now, and
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// `automate()` steps called. Setup is agent-led now, and two doors write `.env.local`: the ops MCP
|
|
5
|
+
// server's `scaffold_env` tool (non-secret config) and `oe env set <NAME>` (a secret, typed in the
|
|
6
|
+
// person's own terminal — OPE-2396). Both pass one gate on the target filename, so a value can never
|
|
7
|
+
// land in a tracked file (core agent/ops/quickstart.ts § envFileTargetRefusal). A third writer here
|
|
8
|
+
// would be a second gate to keep right.
|
|
8
9
|
//
|
|
9
10
|
// SECURITY: nothing here ever returns a secret VALUE to a caller for printing — `mergedEnv` and
|
|
10
11
|
// `isSet` are presence checks only. See AGENTS.md's "never log secrets" rule.
|
|
@@ -41,13 +42,14 @@ export function isSet(v: string | undefined): boolean {
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
/**
|
|
44
|
-
* What a "missing" detail adds (OPE-2222). `--check` reads `.env.local` and the
|
|
45
|
-
* the deployment's own environment. Setting a value on the deployment instead is a
|
|
46
|
-
* do, so a miss here can be a value the deployment already holds. The check does
|
|
47
|
-
* CLI to find out: that needs a login
|
|
45
|
+
* What a "missing" detail adds (OPE-2222). Without `--host`, `--check` reads `.env.local` and the
|
|
46
|
+
* shell, and NEVER the deployment's own environment. Setting a value on the deployment instead is a
|
|
47
|
+
* normal thing to do, so a miss here can be a value the deployment already holds. The check does
|
|
48
|
+
* not call a vendor CLI to find out: that needs a login. It names `--host` instead, which reads the
|
|
49
|
+
* deployment's public status route (OPE-2399, deploy-status.ts).
|
|
48
50
|
*/
|
|
49
51
|
export function missNote(route: SetupRoute): string {
|
|
50
52
|
const where = route === "docker" ? "the container's environment" : "the Vercel project";
|
|
51
53
|
const list = route === "docker" ? "`docker inspect` lists the names there" : "`npx vercel env ls production` lists the names there";
|
|
52
|
-
return `Did you set these on ${where} instead?
|
|
54
|
+
return `Did you set these on ${where} instead? Re-run with --host https://<host>: the env step then also reads the deployment's own verdicts from its status route. Without --host it reads only .env.local and this shell (${list})`;
|
|
53
55
|
}
|
package/src/scaffold.ts
CHANGED
|
@@ -99,6 +99,27 @@ export function isScaffoldableDir(dir: string): boolean {
|
|
|
99
99
|
return readdirSync(dir).every((name) => name === ".git");
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* The nested-name case (OPE-2399). A person who clones an empty repository named `my-agent`, enters
|
|
104
|
+
* it, and runs `npx @open-everywhere/create my-agent` gets `my-agent/my-agent/`. The scaffold is
|
|
105
|
+
* correct, but it is almost never what the person wanted. So when the target is a direct child of
|
|
106
|
+
* `cwd` with the same name, and `cwd` counts as empty (see {@link isScaffoldableDir}), this returns
|
|
107
|
+
* a refusal that names the `.` command. A person who does want the nested directory creates it
|
|
108
|
+
* first: `cwd` then holds it, is no longer empty, and the refusal does not apply.
|
|
109
|
+
*/
|
|
110
|
+
export function nestedNameRefusal(target: string, cwd: string): string | undefined {
|
|
111
|
+
const dir = resolve(cwd, target);
|
|
112
|
+
const here = resolve(cwd);
|
|
113
|
+
if (resolve(dir, "..") !== here || basename(dir) !== basename(here)) return undefined;
|
|
114
|
+
if (!isScaffoldableDir(here)) return undefined;
|
|
115
|
+
return [
|
|
116
|
+
`refusing to scaffold: you are inside an empty directory named "${basename(here)}", so this would create ${basename(here)}/${basename(dir)}/.`,
|
|
117
|
+
"To scaffold into this directory, run:",
|
|
118
|
+
" npx @open-everywhere/create .",
|
|
119
|
+
`To nest the app on purpose, create the directory first (\`mkdir ${basename(dir)}\`), then run this command again.`,
|
|
120
|
+
].join("\n");
|
|
121
|
+
}
|
|
122
|
+
|
|
102
123
|
/**
|
|
103
124
|
* Copy the template into `targetDir`. Creates the directory when it is absent. Throws a
|
|
104
125
|
* {@link ScaffoldRefusal} when it exists and is not an empty directory. A directory that holds only
|
package/src/steps/database.ts
CHANGED
|
@@ -30,7 +30,8 @@ function postgresResolution(env: NodeJS.ProcessEnv): { operational: boolean; mem
|
|
|
30
30
|
|
|
31
31
|
/** The next action for an unsatisfied database step, per route. */
|
|
32
32
|
function nextFor(route: SetupRoute): string {
|
|
33
|
-
const write =
|
|
33
|
+
const write =
|
|
34
|
+
"ask the person to run `npx oe env set DATABASE_URL` in their own terminal and paste the connection string at its hidden prompt — it selects postgres for both stores on its own";
|
|
34
35
|
return route === "vercel"
|
|
35
36
|
? `add Neon from the Vercel Marketplace (\`npx vercel install neon\`, or the project's Storage → Neon → Connect; either sets DATABASE_URL on the project), then ${write}`
|
|
36
37
|
: `provision a Postgres the container can reach (the deployment contract names it), then ${write}`;
|
|
@@ -72,9 +73,9 @@ export const databaseStep: SetupStep = {
|
|
|
72
73
|
summary: "Both routes need Postgres: an ephemeral disk (Vercel) or a replaced container (Docker) loses every local store.",
|
|
73
74
|
instructions: [
|
|
74
75
|
vercel
|
|
75
|
-
? "`npx vercel install neon` provisions Neon and connects it to the linked project, which sets DATABASE_URL there. The project's Storage → Neon → Connect does the same thing."
|
|
76
|
+
? "`npx vercel install neon` provisions Neon and connects it to the linked project, which sets DATABASE_URL there. The project's Storage → Neon → Connect does the same thing. The integration can also enable Neon Auth (NEON_AUTH_BASE_URL, VITE_NEON_AUTH_URL): Open Everywhere does not use it, so leave it off, or ignore those two variables."
|
|
76
77
|
: "Provision a Postgres the container can reach (Neon, RDS, or your own server). The deployment contract states what it must satisfy.",
|
|
77
|
-
"Write the same connection string into .env.local with the
|
|
78
|
+
"Write the same connection string into .env.local with `npx oe env set DATABASE_URL`, run in your own terminal: it reads the value from a hidden prompt. It selects postgres for the operational store and the memory backing on its own — no provider selector needed. Never paste a connection string into the chat, and never pass it to an ops tool.",
|
|
78
79
|
vercel
|
|
79
80
|
? "The deployment needs it too: the Neon integration already set DATABASE_URL on the Vercel project."
|
|
80
81
|
: "The deployment needs it too: DATABASE_URL is part of the container's environment.",
|
|
@@ -12,22 +12,40 @@
|
|
|
12
12
|
import { preflight } from "@open-everywhere/core/agent/ops/quickstart.js";
|
|
13
13
|
import { routeOf, type SetupStep, type StepContext } from "../engine.js";
|
|
14
14
|
import { mergedEnv, missNote } from "../env-file.js";
|
|
15
|
+
import { normalizeHost } from "../deploy-probe.js";
|
|
16
|
+
import { deployedEnvVerdict, readDeployedStatus } from "../deploy-status.js";
|
|
15
17
|
|
|
16
18
|
export const envChecklistStep: SetupStep = {
|
|
17
19
|
id: "env-checklist",
|
|
18
20
|
title: "Env var checklist",
|
|
19
|
-
|
|
21
|
+
// WITH `--host`, THE DEPLOYMENT'S OWN VERDICT COUNTS TOO (OPE-2399). A Vercel app configured in
|
|
22
|
+
// the dashboard holds its values only on the deployment, so the local reading alone said
|
|
23
|
+
// "all missing". The step then reads the public status route (deploy-status.ts). Either reading
|
|
24
|
+
// can satisfy the step, and the detail names which one did. A status route that cannot be read
|
|
25
|
+
// leaves the local verdict as it was and says why.
|
|
26
|
+
async check(ctx: StepContext) {
|
|
20
27
|
const env = mergedEnv(ctx.cwd, ctx.env) as NodeJS.ProcessEnv;
|
|
21
28
|
const route = routeOf(ctx);
|
|
22
29
|
const { checks, ready } = preflight(env, { target: route });
|
|
30
|
+
if (ready) return { satisfied: true, detail: `all required env vars present for the ${route} route` };
|
|
23
31
|
const missing = checks.filter((c) => c.status === "missing");
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
const localMiss = `missing from .env.local and this shell: ${missing.map((c) => c.name).join(", ")}`;
|
|
33
|
+
const localNext = missing.map((c) => c.fix).filter((f): f is string => Boolean(f)).join(" · ");
|
|
34
|
+
const origin = ctx.host === undefined ? undefined : normalizeHost(ctx.host);
|
|
35
|
+
if (origin === undefined) return { satisfied: false, detail: `${localMiss}. ${missNote(route)}`, next: localNext };
|
|
36
|
+
const read = await readDeployedStatus(origin);
|
|
37
|
+
if (!read.ok) return { satisfied: false, detail: `${localMiss}. The deployment's own verdicts could not be read: ${read.detail}`, next: localNext };
|
|
38
|
+
const deployed = deployedEnvVerdict(read.requirements);
|
|
39
|
+
return deployed.satisfied
|
|
40
|
+
? {
|
|
41
|
+
satisfied: true,
|
|
42
|
+
detail: `the deployment reports its env as set (${read.url}): ${deployed.summary}. The local reading differs (${localMiss}); that is expected when the values live only on the deployment`,
|
|
43
|
+
}
|
|
44
|
+
: {
|
|
45
|
+
satisfied: false,
|
|
46
|
+
detail: `the deployment reports its env as NOT set (${read.url}): ${deployed.summary}. Locally, ${localMiss}`,
|
|
47
|
+
next: localNext,
|
|
48
|
+
};
|
|
31
49
|
},
|
|
32
50
|
// 🔴 `guide()` IS STATIC, AND THAT IS DELIBERATE (OPE-2233). It used to dump the live preflight
|
|
33
51
|
// rows, which read `process.versions.node` and the operator's `.env.local`. `guide()` is now read
|
|
@@ -48,7 +66,8 @@ export const envChecklistStep: SetupStep = {
|
|
|
48
66
|
: "The Vercel route needs NO AI_GATEWAY_API_KEY: a deployed project authenticates to the AI Gateway with OIDC.",
|
|
49
67
|
"Each chat surface adds its own names — Slack reads SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET from the environment.",
|
|
50
68
|
"Not needed on a deployment: OE_PUBLIC_BASE_URL (only for a custom domain) and OE_INTAKE_PAGE_SIGNING_KEY (the deployment mints it into the credential store).",
|
|
51
|
-
"Run `npx @open-everywhere/create --check --json`, or the ops tool `preflight`, for the live verdict per name.",
|
|
69
|
+
"Run `npx @open-everywhere/create --check --json`, or the ops tool `preflight`, for the live verdict per name. Both read .env.local and the shell only.",
|
|
70
|
+
"Set the values on the deployment instead (the Vercel dashboard, say)? Add `--host https://<host>`: the step then also reads the deployment's own verdicts from its public `/eve/v1/oe/status` route.",
|
|
52
71
|
],
|
|
53
72
|
};
|
|
54
73
|
},
|
package/src/steps/slack.ts
CHANGED
|
@@ -51,7 +51,7 @@ export const slackStep: SetupStep = {
|
|
|
51
51
|
next:
|
|
52
52
|
'open https://<host>/setup once the deployment is up (it creates and installs the Slack app from one pasted configuration ' +
|
|
53
53
|
'token, with no env var to set), or create the app from the manifest the ops tool `surface_manifest { surface: "slack" }` ' +
|
|
54
|
-
"returns
|
|
54
|
+
"returns, then have the person run `npx oe env set SLACK_BOT_TOKEN` and `npx oe env set SLACK_SIGNING_SECRET` in their own terminal",
|
|
55
55
|
};
|
|
56
56
|
},
|
|
57
57
|
guide(ctx: StepContext) {
|
|
@@ -76,7 +76,7 @@ export const slackStep: SetupStep = {
|
|
|
76
76
|
}). A second install in one workspace needs its own name: re-run with --app-name "<name>".`,
|
|
77
77
|
"Install to Workspace, then OAuth & Permissions → copy the Bot User OAuth Token (xoxb-…) = SLACK_BOT_TOKEN.",
|
|
78
78
|
"Basic Information → App Credentials → copy the Signing Secret = SLACK_SIGNING_SECRET.",
|
|
79
|
-
"Write both with
|
|
79
|
+
"Write both with `npx oe env set SLACK_BOT_TOKEN` and `npx oe env set SLACK_SIGNING_SECRET`, run in your own terminal: each reads the value from a hidden prompt. Never paste a secret into the chat, and never pass one to an ops tool.",
|
|
80
80
|
"THE SHORT WAY, once the deployment is up: open https://<host>/setup. It creates the Slack app from this same manifest with one pasted Slack app configuration token, installs it, and keeps every credential in the deployment's own encrypted store — no env var to set. This check cannot see that store, so it still reports this step unsatisfied afterwards; the status endpoint can.",
|
|
81
81
|
"The manifest's URLs say YOUR-DEPLOY-URL until you deploy. Slack cannot verify Event Subscriptions before a deploy that holds SLACK_SIGNING_SECRET is up. After the deploy, paste the manifest again with your host (App Manifest → Save Changes), then retry the verification under Event Subscriptions.",
|
|
82
82
|
"Note two ids for the trust edits: the workspace (team) id T… (the segment after /client/ in the workspace URL at https://app.slack.com), and your own member id U… (your Slack profile → ⋮ More → Copy member ID).",
|
package/template/.env.example
CHANGED
|
@@ -18,7 +18,7 @@ AI_GATEWAY_API_KEY=
|
|
|
18
18
|
# replaced Docker container starts from an empty volume, so without it core throws at the first
|
|
19
19
|
# store or DM-memory use. On the Vercel route add Neon from the Marketplace
|
|
20
20
|
# (`npx vercel install neon`, or project -> Storage -> Neon -> Connect): it sets DATABASE_URL on the
|
|
21
|
-
# project. Copy the same value here so the operator tools (`npx oe secret`, the ops server's
|
|
21
|
+
# project. Copy the same value here (`npx oe env set DATABASE_URL`, in your own terminal) so the operator tools (`npx oe secret`, the ops server's
|
|
22
22
|
# `secret_set`) write the store the deployment reads. A local run needs nothing: it uses an embedded
|
|
23
23
|
# database under .open-everywhere-data/.
|
|
24
24
|
DATABASE_URL=
|
|
@@ -38,6 +38,15 @@ DATABASE_URL=
|
|
|
38
38
|
# whose credential names `broker: "db"` in the encrypted store. The Slack variables and
|
|
39
39
|
# GITHUB_WEBHOOK_SECRET below are read from the ENVIRONMENT only, so they stay environment variables.
|
|
40
40
|
|
|
41
|
+
# --- Telemetry (https://github.com/open-everywhere/open-everywhere/blob/main/docs/deploy/telemetry.md) ---
|
|
42
|
+
# The deployed app sends ANONYMOUS USAGE TELEMETRY, ON BY DEFAULT: event names, enums, coarse
|
|
43
|
+
# buckets, public model ids and the app version, with a random per-install id (service.instance.id).
|
|
44
|
+
# Never message or memory content, org names, workspace, channel, user or session ids, or env
|
|
45
|
+
# values. The page above lists every event. To turn it
|
|
46
|
+
# off, set this ON THE DEPLOYMENT (the Vercel project or the container's environment): a value here
|
|
47
|
+
# only reaches a local run, because .env.local never ships. DO_NOT_TRACK=1 does the same.
|
|
48
|
+
# OE_TELEMETRY=off
|
|
49
|
+
|
|
41
50
|
# --- Slack (https://github.com/open-everywhere/open-everywhere/blob/main/docs/deploy/surfaces/slack.md) ---
|
|
42
51
|
# Slack app -> OAuth & Permissions -> Bot User OAuth Token (xoxb-…).
|
|
43
52
|
SLACK_BOT_TOKEN=
|
package/template/AGENTS.md
CHANGED
|
@@ -17,17 +17,31 @@ Setup is yours to drive, with the user's consent at every command. Use the
|
|
|
17
17
|
- **Never propose a local run as a setup step.** `npm run dev` is the development loop after the
|
|
18
18
|
deploy — changing tools and skills, evals, debugging a turn. A local run has no public HTTPS URL
|
|
19
19
|
for Slack to reach and a different store, so it proves little about the deployment.
|
|
20
|
-
- **Never ask the user to paste a secret into the chat
|
|
21
|
-
|
|
20
|
+
- **Never ask the user to paste a secret into the chat, and never pass one to a tool.** The user
|
|
21
|
+
types each secret into their own terminal with `npx oe env set <NAME>` (a hidden prompt into
|
|
22
|
+
`.env.local`). You handle names only: `scaffold_env { secretNames }` gives the command per name,
|
|
23
|
+
and `scaffold_credential_key` mints the store key without printing it.
|
|
24
|
+
- **Tell the user about telemetry before the first deploy.** The deployed app sends anonymous usage
|
|
25
|
+
telemetry, and it is ON by default: event names, enums, coarse buckets, public model ids and the
|
|
26
|
+
app version, with a random per-install id (`service.instance.id`). It never sends message or
|
|
27
|
+
memory content, org names, workspace, channel, user or session ids, or env values. To turn it off, they set `OE_TELEMETRY=off` (or
|
|
28
|
+
`DO_NOT_TRACK=1`) on the deployment itself. The full list of events is
|
|
29
|
+
`https://github.com/open-everywhere/open-everywhere/blob/main/docs/deploy/telemetry.md`. Ask which
|
|
30
|
+
they want, and do not decide for them.
|
|
22
31
|
- `npx @open-everywhere/create --check --json` is the status report: every step, with `satisfied`,
|
|
23
32
|
`detail` and a `next` command. Add `--route docker` for the Docker route and
|
|
24
|
-
`--host https://<host>` to probe a deployment. The human-readable version of the same step list is
|
|
33
|
+
`--host https://<host>` to probe a deployment and read the env verdicts it reports for itself. The human-readable version of the same step list is
|
|
25
34
|
`https://github.com/open-everywhere/open-everywhere/blob/main/docs/deploy/setup-steps.md`.
|
|
26
35
|
|
|
27
36
|
## Where things live
|
|
28
37
|
|
|
29
38
|
- `roster.config.ts` — what the agent can do. `roster.lock.json` is the reviewed roll-call of every
|
|
30
39
|
contribution. Both are committed.
|
|
40
|
+
- `scripts/goldens/roster-plan.txt` — the roster review surface: one line per slot file `oe build`
|
|
41
|
+
writes, with the package that mounts it. The slot tree is not committed, so this file is how a
|
|
42
|
+
pull request shows what the agent gains or loses. `oe build` keeps it current, and
|
|
43
|
+
`npx oe build --check` fails when it differs from the plan. Commit it, and read its diff with the
|
|
44
|
+
lock's. Never edit it by hand.
|
|
31
45
|
- `agent/agent.ts` — the eve agent definition.
|
|
32
46
|
- `agent/` — the config: access bundles, identity and trust, memory domains, models, settings, spend
|
|
33
47
|
caps, webhooks. Each file's header says what it controls.
|
package/template/README.md
CHANGED
|
@@ -28,7 +28,19 @@ It is generated from the same step list the status check reports, so it cannot d
|
|
|
28
28
|
|
|
29
29
|
`npx @open-everywhere/create --check` reports every setup step and the next command for each
|
|
30
30
|
unsatisfied one. It changes nothing. Add `--json` for the report as data, `--route docker` to judge
|
|
31
|
-
against the Docker route, and `--host https://<host>` to probe a deployment.
|
|
31
|
+
against the Docker route, and `--host https://<host>` to probe a deployment. With `--host`, the env
|
|
32
|
+
step also reads the deployment's own verdicts, so values set only in the Vercel dashboard count.
|
|
33
|
+
|
|
34
|
+
## Telemetry
|
|
35
|
+
|
|
36
|
+
The deployed app sends **anonymous usage telemetry, ON by default**: event names, enums, coarse
|
|
37
|
+
buckets, public model ids and the app version. Each event carries a random per-install id
|
|
38
|
+
(`service.instance.id`). It never sends message or memory content, org names, workspace, channel,
|
|
39
|
+
user or session ids, or env values. **To turn it off, set `OE_TELEMETRY=off`** (or `DO_NOT_TRACK=1`) on the deployment:
|
|
40
|
+
the Vercel project's environment or the container's. `.env.local` alone does not do it, because it
|
|
41
|
+
never ships. Every event and attribute is listed in the
|
|
42
|
+
[telemetry disclosure](https://github.com/open-everywhere/open-everywhere/blob/main/docs/deploy/telemetry.md).
|
|
43
|
+
The `@open-everywhere/create` CLI sends none.
|
|
32
44
|
|
|
33
45
|
## Develop locally
|
|
34
46
|
|
|
@@ -44,6 +56,7 @@ without a public tunnel.
|
|
|
44
56
|
| --- | --- |
|
|
45
57
|
| `roster.config.ts` | What the agent can do: which packages contribute, and which eve built-ins it takes away. |
|
|
46
58
|
| `roster.lock.json` | The reviewed roll-call of every contribution. `npx oe build --accept` updates it. Review its diff. |
|
|
59
|
+
| `scripts/goldens/roster-plan.txt` | The roster review surface: one line per slot file `oe build` writes, with the package that mounts it. `oe build` keeps it current and `npx oe build --check` fails when it drifts. Commit it, and review its diff with the lock's. |
|
|
47
60
|
| `agent/agent.ts` | The eve agent definition. |
|
|
48
61
|
| `agent/access/` | Bundles and bindings (what the agent may reach, and where), connector credentials, browser hosts, and the pre-approval rules (what runs with no approval card). |
|
|
49
62
|
| `agent/identity/` | Trusted surfaces, principals and groups. |
|
|
@@ -22,9 +22,13 @@ that repository ships no `env:pipe` script. Everything else is the same.
|
|
|
22
22
|
- The ops MCP tools check and scaffold. **You** run install, build and deploy commands in the
|
|
23
23
|
user's shell: show the command, get a yes, then run it. Never run a deploy, create a cloud
|
|
24
24
|
resource, or write a secret without explicit confirmation.
|
|
25
|
-
- **Never ask the user to paste a secret into the chat, and never echo or
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
- **Never ask the user to paste a secret into the chat, never pass one to a tool, and never echo or
|
|
26
|
+
commit one.** A tool call is part of your transcript. The user types each secret into their OWN
|
|
27
|
+
terminal with `npx oe env set <NAME>`: it reads the value from a hidden prompt and writes it to the
|
|
28
|
+
gitignored `.env.local`. You only ever handle the NAME: `scaffold_env { secretNames: [...] }`
|
|
29
|
+
returns the command per name and whether the file holds a value yet. `scaffold_env { values }`
|
|
30
|
+
takes non-secret config only, and its schema refuses a secret name. Mint the credential-store key
|
|
31
|
+
with `scaffold_credential_key`, which never prints it.
|
|
28
32
|
- **Never propose a local run as a setup step.** `npm run dev` is the development loop AFTER the
|
|
29
33
|
deploy. A local run has no public HTTPS URL for Slack to reach and keeps its state in a different
|
|
30
34
|
store, so it proves little about the deployment. See "Develop locally" below.
|
|
@@ -32,9 +36,17 @@ that repository ships no `env:pipe` script. Everything else is the same.
|
|
|
32
36
|
`OE_CREDENTIAL_ENCRYPTION_KEY`, `SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET` and
|
|
33
37
|
`GITHUB_WEBHOOK_SECRET` from its **environment**: the Slack bundle and the GitHub webhook check
|
|
34
38
|
never read the credential store. So these go in `.env.local`, and then into the deployment's own
|
|
35
|
-
environment. `secret_set` is for a credential whose `broker` is `"db"` (and
|
|
36
|
-
`NOTION_WEBHOOK_SECRET`)
|
|
37
|
-
|
|
39
|
+
environment. `secret_set { names: [...] }` is for a credential whose `broker` is `"db"` (and
|
|
40
|
+
`NOTION_WEBHOOK_SECRET`): it moves each named value from `.env.local` into the store, so the user
|
|
41
|
+
runs `npx oe env set <NAME>` first. It needs `DATABASE_URL` and the key in `.env.local` too.
|
|
42
|
+
Nothing reads a stored secret back out (`secret_list` returns names only).
|
|
43
|
+
- **If an ops tool answers "the app now runs @open-everywhere/core X; this ops server runs Y"**, the
|
|
44
|
+
server predates an upgrade. Ask the user to restart it (`/mcp`, then reconnect
|
|
45
|
+
`open-everywhere-ops`) and call again. Never work around it: a stale server serves old code. A
|
|
46
|
+
server whose core predates this check cannot refuse: after an upgrade, an input-validation error
|
|
47
|
+
that names `values` or `secrets`, a `scaffold_env` reply with no `secrets` list for the
|
|
48
|
+
`secretNames` you sent, or "Tool … not found", means the same thing. Restart it. Never fall back
|
|
49
|
+
to passing a value.
|
|
38
50
|
- Every command runs from the app root.
|
|
39
51
|
|
|
40
52
|
## Step 1 — ask which route
|
|
@@ -53,11 +65,26 @@ that repository ships no `env:pipe` script. Everything else is the same.
|
|
|
53
65
|
Nothing beyond these two is supported. For any other host, read the contract and follow the Docker
|
|
54
66
|
route; do not invent a recipe.
|
|
55
67
|
|
|
68
|
+
## Tell the user about telemetry, before the first deploy
|
|
69
|
+
|
|
70
|
+
**The deployed app sends anonymous usage telemetry, and it is ON by default.** Tell the user that
|
|
71
|
+
before the first deploy, and ask whether they want it. Do not decide for them. It sends event names,
|
|
72
|
+
enums, coarse buckets, public model ids and the app version, with a random per-install id
|
|
73
|
+
(`service.instance.id`). It never sends message or memory content, org names, workspace, channel,
|
|
74
|
+
user or session ids, or env values. The full list
|
|
75
|
+
of events is `https://github.com/open-everywhere/open-everywhere/blob/main/docs/deploy/telemetry.md`.
|
|
76
|
+
|
|
77
|
+
To turn it off, `OE_TELEMETRY=off` (or `DO_NOT_TRACK=1`) must be set on the DEPLOYMENT: a value in
|
|
78
|
+
`.env.local` reaches only a local run. On the Vercel route, at step 9:
|
|
79
|
+
`printf off | npx vercel env add OE_TELEMETRY production`. On the Docker route, put it in the
|
|
80
|
+
container's environment. Every boot prints a line that says whether telemetry is on.
|
|
81
|
+
|
|
56
82
|
## Status, at every step
|
|
57
83
|
|
|
58
84
|
- `npx @open-everywhere/create --check --json` — the step list as data: `satisfied`, `detail`, and a
|
|
59
85
|
`next` command per unsatisfied step. It changes nothing. Pass `--route docker` on the Docker
|
|
60
|
-
route, and `--host https://<host>` once a deployment exists
|
|
86
|
+
route, and `--host https://<host>` once a deployment exists: the env step then also reads the
|
|
87
|
+
deployment's own verdicts from its public status route. In a clone of the repository, run
|
|
61
88
|
`node packages/create/bin/create-open-everywhere.js --check --json` instead.
|
|
62
89
|
- The `preflight` tool — the env verdict per name. Pass `target: "vercel"` or `target: "docker"`.
|
|
63
90
|
|
|
@@ -74,18 +101,21 @@ tool. The same step list, written for a human, is
|
|
|
74
101
|
3. **Database.** `npx vercel install neon` provisions a Neon database and connects it to the linked
|
|
75
102
|
project, which sets `DATABASE_URL` there. (`vercel install` is an alias of
|
|
76
103
|
`vercel integration add`; the Marketplace slug is `neon`.) The dashboard path — project →
|
|
77
|
-
**Storage → Neon → Connect** — does the same thing.
|
|
104
|
+
**Storage → Neon → Connect** — does the same thing. The integration can also enable **Neon
|
|
105
|
+
Auth** (`NEON_AUTH_BASE_URL`, `VITE_NEON_AUTH_URL`). Open Everywhere does not use it: leave it
|
|
106
|
+
off, or ignore those two variables. Then get the same value into `.env.local`
|
|
78
107
|
for the operator tools, either with `npx vercel env pull` (it writes the project's environment
|
|
79
108
|
into `.env.local`, overwriting it, so pull before you add anything local) or by asking the user
|
|
80
|
-
|
|
109
|
+
to run `npx oe env set DATABASE_URL` and paste the connection string at its prompt. **That one value is the whole
|
|
81
110
|
step:** it resolves both the operational store and the memory backing to postgres on its own, so
|
|
82
111
|
set no provider selector. A selector pointing AWAY from postgres is the only thing that breaks
|
|
83
112
|
it.
|
|
84
113
|
4. **Key.** `scaffold_credential_key`.
|
|
85
114
|
5. **Slack app.** Call `surface_manifest { surface: "slack" }` and hand the user the manifest and
|
|
86
115
|
the steps it returns. Before the first deploy the manifest keeps `YOUR-DEPLOY-URL`. The user
|
|
87
|
-
creates and installs the app, then
|
|
88
|
-
|
|
116
|
+
creates and installs the app, then runs `npx oe env set SLACK_BOT_TOKEN` and
|
|
117
|
+
`npx oe env set SLACK_SIGNING_SECRET` in their own terminal. Confirm with
|
|
118
|
+
`scaffold_env { secretNames: ["SLACK_BOT_TOKEN", "SLACK_SIGNING_SECRET"] }`: both read `present: true`.
|
|
89
119
|
6. **Vouch the workspace.** Ask for the team id (`T…`: the segment after `/client/` in the
|
|
90
120
|
workspace URL at app.slack.com). In `agent/identity/surfaces.ts` add
|
|
91
121
|
`defineSurface({ key: "slack/<team-id>", trust: "internal" })`.
|
|
@@ -96,7 +126,8 @@ tool. The same step list, written for a human, is
|
|
|
96
126
|
9. **Deployment env.** `.env.local` never ships, so the deployment reads only what you set ON it.
|
|
97
127
|
The names are `OE_CREDENTIAL_ENCRYPTION_KEY`, `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET`. The
|
|
98
128
|
Neon integration already set `DATABASE_URL` there, and that one value resolves both stores — so
|
|
99
|
-
there is no `OE_OPERATIONAL_PROVIDER` or `OE_MEMORY_PROVIDER` to push.
|
|
129
|
+
there is no `OE_OPERATIONAL_PROVIDER` or `OE_MEMORY_PROVIDER` to push. Add `OE_TELEMETRY` (value
|
|
130
|
+
`off`) only when the user chose to turn telemetry off (see the telemetry section above).
|
|
100
131
|
Confirm each command first, and **never let a value reach your own output.**
|
|
101
132
|
- **In a scaffolded app:** `npm run -s env:pipe -- <NAME> | npx vercel env add <NAME> production`.
|
|
102
133
|
Always pipe `env:pipe` straight into `vercel env add`, as written. Never run it bare: your
|
|
@@ -127,11 +158,12 @@ public HTTPS URL, Postgres, a sandbox backend, egress control, a model route, an
|
|
|
127
158
|
Then:
|
|
128
159
|
|
|
129
160
|
1. **Install and build.** `npm install`, then `npm run build`.
|
|
130
|
-
2. **Postgres.** Provision one the container can reach
|
|
131
|
-
one value resolves both stores to postgres;
|
|
161
|
+
2. **Postgres.** Provision one the container can reach. The user runs `npx oe env set DATABASE_URL`
|
|
162
|
+
and pastes its connection string at the prompt. That one value resolves both stores to postgres;
|
|
163
|
+
set no provider selector.
|
|
132
164
|
3. **Key.** `scaffold_credential_key`.
|
|
133
165
|
4. **Model route.** There is no OIDC off Vercel, so the user supplies `AI_GATEWAY_API_KEY` (Vercel
|
|
134
|
-
→ AI Gateway → API Keys issues one for any host)
|
|
166
|
+
→ AI Gateway → API Keys issues one for any host) with `npx oe env set AI_GATEWAY_API_KEY`. Running a different model backend instead is
|
|
135
167
|
an **adapter swap in app code**
|
|
136
168
|
(`https://github.com/open-everywhere/open-everywhere/blob/main/docs/extending/adapter-model.md`),
|
|
137
169
|
which `--check` cannot see: that step stays `missing` on the Docker route either way, so read it
|
|
@@ -147,9 +179,9 @@ Then:
|
|
|
147
179
|
|
|
148
180
|
## Develop locally
|
|
149
181
|
|
|
150
|
-
Only when the user asks to change or debug the agent — never as a setup step.
|
|
151
|
-
`AI_GATEWAY_API_KEY`
|
|
152
|
-
then `npm run dev`. A local run keeps its state in an embedded database under
|
|
182
|
+
Only when the user asks to change or debug the agent — never as a setup step. The user creates
|
|
183
|
+
`AI_GATEWAY_API_KEY` (Vercel → AI Gateway → API Keys) and writes it with
|
|
184
|
+
`npx oe env set AI_GATEWAY_API_KEY`, then `npm run dev`. A local run keeps its state in an embedded database under
|
|
153
185
|
`.open-everywhere-data/`, and Slack cannot reach it without a public tunnel.
|
|
154
186
|
|
|
155
187
|
## Notes
|
|
@@ -161,7 +193,12 @@ then `npm run dev`. A local run keeps its state in an embedded database under
|
|
|
161
193
|
- The deployment's own identity (`deploymentIdentity`) is code in `agent/identity/surfaces.ts`, not
|
|
162
194
|
env.
|
|
163
195
|
- `@open-everywhere/create` has no interactive wizard and sends no telemetry. It scaffolds
|
|
164
|
-
(`npx @open-everywhere/create <dir>`) and reports status (`--check`). Nothing else.
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
196
|
+
(`npx @open-everywhere/create <dir>`) and reports status (`--check`). Nothing else. The deployed
|
|
197
|
+
app is a different matter: its telemetry is on by default (see the telemetry section above).
|
|
198
|
+
- 🔴 **Without `--host`, `--check` reads `.env.local` and your shell, never the deployment's own
|
|
199
|
+
environment.** With `--host`, the env step also reads the deployment's status route, which reports
|
|
200
|
+
`DATABASE_URL` and the credential key (its `secrets` row), the store selection and the model route.
|
|
201
|
+
The env step does not judge the Slack secrets, so even a "9/9 satisfied" is not proof that the
|
|
202
|
+
deployment holds `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET`. The same status document's
|
|
203
|
+
`surfaces.slack.credentials` reports whether both are present: read it with
|
|
204
|
+
`curl -s https://<host>/eve/v1/oe/status`. Slack's **Verified** is what proves the signing secret.
|
|
@@ -66,7 +66,8 @@ Those are decisions, not steps.
|
|
|
66
66
|
|
|
67
67
|
`--plan` also prints a **template drift** report. It compares every file the scaffold copied into
|
|
68
68
|
this app with the TARGET release's `@open-everywhere/create` template, and lists each one that
|
|
69
|
-
differs, with a one-line size of its diff. An upgrade changes only `package.json
|
|
69
|
+
differs, with a one-line size of its diff. An upgrade changes only `package.json` and
|
|
70
|
+
`package-lock.json`, so a scaffolded
|
|
70
71
|
file stays as the old template wrote it. A stale copy can typecheck and build and still break the
|
|
71
72
|
deployment: the 0.1.2 `agent/lib/register-adapters.ts` registers no Postgres client on a bare
|
|
72
73
|
`DATABASE_URL`, so a Vercel+Neon deployment of 0.1.4 fails at its first write.
|
|
@@ -82,6 +83,14 @@ the adapters by hand to the one-call copy: move any adapter the user registered
|
|
|
82
83
|
| --- | --- |
|
|
83
84
|
| SYNC | a template-owned file — wiring, a script, `AGENTS.md`, `README.md`, `.env.example`, a skill. Plan to copy the target's file over this one, after you read the diff. |
|
|
84
85
|
| config | the app's own config-as-code. A difference is normal once the app is configured. Merge the template's change by hand only if the user wants it. |
|
|
86
|
+
| DELETE | a release up to the target removed this file from the template, and the app still has it. Plan to delete it. eve 0.69 and later refuse `agent/instrumentation.ts` at build. |
|
|
87
|
+
| app-owned | `.oe-template-ignore` names the file, so the app owns it. Nothing to do. |
|
|
88
|
+
|
|
89
|
+
`.oe-template-ignore` at the app root lists the template files the app removed or owns on purpose:
|
|
90
|
+
one app-relative path per line, a trailing `/` for a directory, `#` for a comment. The report prints
|
|
91
|
+
nothing for an ignored file the app does not have, and one `app-owned` line for one it has. Add a
|
|
92
|
+
path only when the user says the app owns that file. Never add one to silence a SYNC line you have
|
|
93
|
+
not read.
|
|
85
94
|
|
|
86
95
|
The report never writes a file. If it says the drift check did not run, compare the files with the
|
|
87
96
|
target's template by hand. An installed core without the report prints none: `oe upgrade` runs the
|
|
@@ -99,7 +108,11 @@ In order, and it stops at the first step that fails:
|
|
|
99
108
|
1. bump every `@open-everywhere/*` package to the target, renaming a dependency on the retired
|
|
100
109
|
unscoped `create-open-everywhere` to `@open-everywhere/create` as it goes;
|
|
101
110
|
2. pin `eve` to the version the target core declares as its peer;
|
|
102
|
-
3. `npm install` — its `postinstall` runs `oe-eve-patch`, which the app refuses to boot without
|
|
111
|
+
3. `npm install` — its `postinstall` runs `oe-eve-patch`, which the app refuses to boot without.
|
|
112
|
+
Before it, the run drops the `package-lock.json` entries of `eve`, of every
|
|
113
|
+
`@open-everywhere/*` package and of every package that peers on one of them, so npm resolves
|
|
114
|
+
that set again. If the install still stops with ERESOLVE (a core at 0.2.1 or earlier does not
|
|
115
|
+
drop them), run `rm package-lock.json && npm install`, then run `oe upgrade` again;
|
|
103
116
|
4. run the config codemods the target's notes name, and print the migrations that are yours;
|
|
104
117
|
5. `oe build --accept` — this rewrites `roster.lock.json`;
|
|
105
118
|
6. `npm run typecheck`;
|
|
@@ -136,7 +149,7 @@ codemod. Do not delete the marker to get past this refusal.
|
|
|
136
149
|
|
|
137
150
|
```
|
|
138
151
|
git diff roster.lock.json
|
|
139
|
-
git diff package.json
|
|
152
|
+
git diff package.json package-lock.json
|
|
140
153
|
git status
|
|
141
154
|
```
|
|
142
155
|
|
|
@@ -149,7 +162,8 @@ Then run the app's own checks once more if anything above was fixed by hand:
|
|
|
149
162
|
|
|
150
163
|
Then act on the template drift report. A core that carries it prints it again after the install;
|
|
151
164
|
if this run printed no "Template drift" heading, run `npx oe upgrade --to <target> --plan` now to get it. For
|
|
152
|
-
each
|
|
165
|
+
each DELETE line, delete the file. If the user says the app owns it, keep it and name it in
|
|
166
|
+
`.oe-template-ignore`. For each SYNC line, read the diff against the installed template, for example
|
|
153
167
|
`diff node_modules/@open-everywhere/create/template/agent/lib/register-adapters.ts agent/lib/register-adapters.ts`.
|
|
154
168
|
Keep any edit the user made on purpose, and copy the template's file otherwise. For
|
|
155
169
|
`agent/lib/register-adapters.ts`, the user's edits belong in the `customAdapters` hook of the
|
|
@@ -171,7 +185,7 @@ Commit on a branch, never on the default branch. The body carries:
|
|
|
171
185
|
- what changed in `roster.lock.json`, in your own words;
|
|
172
186
|
- **the env names the deployment needs before this merges**, names only;
|
|
173
187
|
- the manual steps, and who does each one.
|
|
174
|
-
- the template files you synced, and each SYNC line you left as it is, with the reason.
|
|
188
|
+
- the template files you synced or deleted, and each SYNC or DELETE line you left as it is, with the reason.
|
|
175
189
|
|
|
176
190
|
Then stop. The admin reviews the lock diff and merges. The merge deploys.
|
|
177
191
|
|
|
@@ -179,21 +193,23 @@ Then stop. The admin reviews the lock diff and merges. The merge deploys.
|
|
|
179
193
|
|
|
180
194
|
A green build is not a working deployment.
|
|
181
195
|
|
|
182
|
-
**
|
|
183
|
-
JSON route that reports the deployment's version, whether the
|
|
184
|
-
|
|
185
|
-
answers, and the Slack posture.
|
|
186
|
-
|
|
187
|
-
|
|
196
|
+
**Read the status route, `GET /eve/v1/oe/status`.** It ships from core 0.1.4. It is an
|
|
197
|
+
unauthenticated, non-sensitive JSON route that reports the deployment's version, whether the
|
|
198
|
+
database is reachable, the sandbox backend, whether egress is enforced, whether the model route
|
|
199
|
+
answers, and the Slack posture. A deployment can hide it on purpose, with a roster exclusion or an
|
|
200
|
+
edge rule (`docs/deploy/contract.md` § Hiding the status route). A 404 or a 403 there can be that
|
|
201
|
+
choice, not a fault: ask the operator before you call it broken. Never read some other route as if
|
|
202
|
+
it were this one. When the route answers, report each field, in this order:
|
|
188
203
|
|
|
189
204
|
1. **version** — it reads the target. If it still reads the old version, the deploy has not
|
|
190
205
|
finished, or it failed. Nothing below is meaningful until this matches.
|
|
191
|
-
2. **database reachable
|
|
206
|
+
2. **database reachable** (the `postgres` verdict).
|
|
192
207
|
3. **sandbox backend**, and **egress enforced**.
|
|
193
208
|
4. **model route answers.**
|
|
194
209
|
5. **Slack** — credentials present, workspace installed, events verified.
|
|
195
210
|
|
|
196
|
-
**
|
|
211
|
+
**When the route does not answer**, on a core older than 0.1.4 or on a deployment that hides it,
|
|
212
|
+
confirm what you can and say plainly what you could not:
|
|
197
213
|
|
|
198
214
|
- the deploy finished, from the host's own deployment log;
|
|
199
215
|
- `npx @open-everywhere/create --check --json --host https://<host>` — its `build-deploy` step
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
agent/channels/aws-sso-callback.ts mounted @open-everywhere/core
|
|
2
|
+
agent/channels/control-mcp.ts mounted @open-everywhere/core
|
|
3
|
+
agent/channels/control-read.ts mounted @open-everywhere/core
|
|
4
|
+
agent/channels/credential-intake-page.ts mounted @open-everywhere/core
|
|
5
|
+
agent/channels/github.ts mounted @open-everywhere/provider-github
|
|
6
|
+
agent/channels/notion.ts mounted @open-everywhere/provider-notion
|
|
7
|
+
agent/channels/oe-oauth-callback.ts mounted @open-everywhere/core
|
|
8
|
+
agent/channels/oe-status.ts mounted @open-everywhere/core
|
|
9
|
+
agent/channels/policy-pages.ts mounted @open-everywhere/core
|
|
10
|
+
agent/channels/slack-commands.ts mounted @open-everywhere/provider-slack
|
|
11
|
+
agent/channels/slack-setup-page.ts mounted @open-everywhere/provider-slack
|
|
12
|
+
agent/channels/slack.ts mounted @open-everywhere/provider-slack
|
|
13
|
+
agent/channels/test-wake.ts mounted @open-everywhere/core
|
|
14
|
+
agent/channels/transcript-relay.ts mounted @open-everywhere/core
|
|
15
|
+
agent/channels/unified.ts mounted @open-everywhere/core
|
|
16
|
+
agent/channels/webhook-reveal-page.ts mounted @open-everywhere/core
|
|
17
|
+
agent/channels/webhooks.ts mounted @open-everywhere/core
|
|
18
|
+
agent/connections/notion.ts mounted @open-everywhere/core
|
|
19
|
+
agent/hooks/approval-raised.ts mounted @open-everywhere/core
|
|
20
|
+
agent/hooks/approval-settlement.ts mounted @open-everywhere/core
|
|
21
|
+
agent/hooks/binding-bridge.ts mounted @open-everywhere/core
|
|
22
|
+
agent/hooks/connector-audit.ts mounted @open-everywhere/core
|
|
23
|
+
agent/hooks/egress.ts mounted @open-everywhere/core
|
|
24
|
+
agent/hooks/eve-patch-gate.ts mounted @open-everywhere/core
|
|
25
|
+
agent/hooks/fire-carriage.ts mounted @open-everywhere/core
|
|
26
|
+
agent/hooks/fire-toolset.ts mounted @open-everywhere/core
|
|
27
|
+
agent/hooks/held-question.ts mounted @open-everywhere/core
|
|
28
|
+
agent/hooks/job-posture.ts mounted @open-everywhere/core
|
|
29
|
+
agent/hooks/lean-seat.ts mounted @open-everywhere/core
|
|
30
|
+
agent/hooks/learn.ts mounted @open-everywhere/core
|
|
31
|
+
agent/hooks/link-claim.ts mounted @open-everywhere/core
|
|
32
|
+
agent/hooks/log-flush.ts mounted @open-everywhere/core
|
|
33
|
+
agent/hooks/loop-breaker.ts mounted @open-everywhere/core
|
|
34
|
+
agent/hooks/memory.ts mounted @open-everywhere/core
|
|
35
|
+
agent/hooks/native-input-audit.ts mounted @open-everywhere/core
|
|
36
|
+
agent/hooks/own-account-ask.ts mounted @open-everywhere/core
|
|
37
|
+
agent/hooks/requester-identity.ts mounted @open-everywhere/core
|
|
38
|
+
agent/hooks/requester-messages.ts mounted @open-everywhere/core
|
|
39
|
+
agent/hooks/routine-outcome.ts mounted @open-everywhere/core
|
|
40
|
+
agent/hooks/routine-silence.ts mounted @open-everywhere/core
|
|
41
|
+
agent/hooks/sandbox-lifecycle.ts mounted @open-everywhere/adapters
|
|
42
|
+
agent/hooks/session-park.ts mounted @open-everywhere/core
|
|
43
|
+
agent/hooks/spawn-taint.ts mounted @open-everywhere/core
|
|
44
|
+
agent/hooks/spend.ts mounted @open-everywhere/core
|
|
45
|
+
agent/hooks/stall-guard.ts mounted @open-everywhere/core
|
|
46
|
+
agent/hooks/telemetry.ts mounted @open-everywhere/core
|
|
47
|
+
agent/hooks/turn-anchor.ts mounted @open-everywhere/core
|
|
48
|
+
agent/hooks/wake-accounting-turn.ts mounted @open-everywhere/core
|
|
49
|
+
agent/hooks/wake-turn-start.ts mounted @open-everywhere/core
|
|
50
|
+
agent/hooks/window-routing.ts mounted @open-everywhere/core
|
|
51
|
+
agent/lib/providers.generated.ts providers slack,notion,github
|
|
52
|
+
agent/schedules/directory-sync.ts mounted @open-everywhere/core
|
|
53
|
+
agent/schedules/dispatch.ts mounted @open-everywhere/core
|
|
54
|
+
agent/schedules/dream-mode3.ts mounted @open-everywhere/core
|
|
55
|
+
agent/schedules/notion-ingress.ts mounted @open-everywhere/provider-notion
|
|
56
|
+
agent/schedules/tidy.ts mounted @open-everywhere/core
|
|
57
|
+
agent/skills/scoped.ts mounted @open-everywhere/core
|
|
58
|
+
agent/tools/add_label.ts mounted @open-everywhere/core
|
|
59
|
+
agent/tools/add_routine_rule.ts mounted @open-everywhere/core
|
|
60
|
+
agent/tools/agent_version.ts mounted @open-everywhere/core
|
|
61
|
+
agent/tools/ask_question.ts mounted @open-everywhere/core
|
|
62
|
+
agent/tools/ask_room.ts mounted @open-everywhere/core
|
|
63
|
+
agent/tools/assign.ts mounted @open-everywhere/core
|
|
64
|
+
agent/tools/aws.ts mounted @open-everywhere/core
|
|
65
|
+
agent/tools/bash.ts framework-disabled
|
|
66
|
+
agent/tools/browser_tools.ts mounted @open-everywhere/core
|
|
67
|
+
agent/tools/cancel_routine.ts mounted @open-everywhere/core
|
|
68
|
+
agent/tools/cancel_work.ts mounted @open-everywhere/core
|
|
69
|
+
agent/tools/capture_events.ts mounted @open-everywhere/core
|
|
70
|
+
agent/tools/check_pr_status.ts mounted @open-everywhere/core
|
|
71
|
+
agent/tools/checkout_repo.ts mounted @open-everywhere/core
|
|
72
|
+
agent/tools/clear_connector_override.ts mounted @open-everywhere/core
|
|
73
|
+
agent/tools/clear_spend_limit.ts mounted @open-everywhere/core
|
|
74
|
+
agent/tools/complete_job.ts mounted @open-everywhere/core
|
|
75
|
+
agent/tools/complete_thread.ts mounted @open-everywhere/core
|
|
76
|
+
agent/tools/confirm_link.ts mounted @open-everywhere/core
|
|
77
|
+
agent/tools/connector.ts mounted @open-everywhere/core
|
|
78
|
+
agent/tools/create_agent.ts mounted @open-everywhere/core
|
|
79
|
+
agent/tools/create_routine.ts mounted @open-everywhere/core
|
|
80
|
+
agent/tools/create_skill.ts mounted @open-everywhere/core
|
|
81
|
+
agent/tools/create_ticket.ts mounted @open-everywhere/core
|
|
82
|
+
agent/tools/declare_webhook.ts mounted @open-everywhere/core
|
|
83
|
+
agent/tools/delete_skill.ts mounted @open-everywhere/core
|
|
84
|
+
agent/tools/describe_image.ts mounted @open-everywhere/core
|
|
85
|
+
agent/tools/dm_person.ts mounted @open-everywhere/core
|
|
86
|
+
agent/tools/edit_reply.ts mounted @open-everywhere/core
|
|
87
|
+
agent/tools/edit_routine.ts mounted @open-everywhere/core
|
|
88
|
+
agent/tools/enable_routine.ts mounted @open-everywhere/core
|
|
89
|
+
agent/tools/explain_permission.ts mounted @open-everywhere/core
|
|
90
|
+
agent/tools/extend_workspace_time.ts mounted @open-everywhere/adapters
|
|
91
|
+
agent/tools/get_pr_feedback.ts mounted @open-everywhere/core
|
|
92
|
+
agent/tools/grant_tools.ts mounted @open-everywhere/core
|
|
93
|
+
agent/tools/halt.ts mounted @open-everywhere/core
|
|
94
|
+
agent/tools/link_identity.ts mounted @open-everywhere/core
|
|
95
|
+
agent/tools/list_recent_events.ts mounted @open-everywhere/core
|
|
96
|
+
agent/tools/list_repos.ts mounted @open-everywhere/core
|
|
97
|
+
agent/tools/list_routines.ts mounted @open-everywhere/core
|
|
98
|
+
agent/tools/list_skills.ts mounted @open-everywhere/core
|
|
99
|
+
agent/tools/list_webhooks.ts mounted @open-everywhere/core
|
|
100
|
+
agent/tools/memory_admin_list.ts mounted @open-everywhere/core
|
|
101
|
+
agent/tools/memory_admin_read.ts mounted @open-everywhere/core
|
|
102
|
+
agent/tools/message_thread_seat.ts mounted @open-everywhere/core
|
|
103
|
+
agent/tools/no_reply.ts mounted @open-everywhere/core
|
|
104
|
+
agent/tools/notion_search.ts mounted @open-everywhere/provider-notion
|
|
105
|
+
agent/tools/open_pull_request.ts mounted @open-everywhere/core
|
|
106
|
+
agent/tools/permission_fit_report.ts mounted @open-everywhere/core
|
|
107
|
+
agent/tools/post_file.ts mounted @open-everywhere/core
|
|
108
|
+
agent/tools/post_message.ts mounted @open-everywhere/core
|
|
109
|
+
agent/tools/post_pr_walkthrough.ts mounted @open-everywhere/core
|
|
110
|
+
agent/tools/purge_memory.ts mounted @open-everywhere/core
|
|
111
|
+
agent/tools/query_analytics.ts mounted @open-everywhere/core
|
|
112
|
+
agent/tools/react.ts mounted @open-everywhere/core
|
|
113
|
+
agent/tools/read_channel.ts mounted @open-everywhere/core
|
|
114
|
+
agent/tools/read_docs.ts mounted @open-everywhere/core
|
|
115
|
+
agent/tools/read_file_upload.ts mounted @open-everywhere/core
|
|
116
|
+
agent/tools/read_file.ts framework-disabled
|
|
117
|
+
agent/tools/read_github_issue.ts mounted @open-everywhere/core
|
|
118
|
+
agent/tools/read_notion_comments.ts mounted @open-everywhere/provider-notion
|
|
119
|
+
agent/tools/read_notion_page.ts mounted @open-everywhere/provider-notion
|
|
120
|
+
agent/tools/read_routine_transcript.ts mounted @open-everywhere/core
|
|
121
|
+
agent/tools/read_thread_seat.ts mounted @open-everywhere/core
|
|
122
|
+
agent/tools/read_thread.ts mounted @open-everywhere/core
|
|
123
|
+
agent/tools/read_webhook_history.ts mounted @open-everywhere/core
|
|
124
|
+
agent/tools/read_work_channel.ts mounted @open-everywhere/core
|
|
125
|
+
agent/tools/read_work_thread.ts mounted @open-everywhere/core
|
|
126
|
+
agent/tools/record_follow_up.ts mounted @open-everywhere/core
|
|
127
|
+
agent/tools/record_job_state.ts mounted @open-everywhere/core
|
|
128
|
+
agent/tools/record_watch_state.ts mounted @open-everywhere/core
|
|
129
|
+
agent/tools/remove_routine_rule.ts mounted @open-everywhere/core
|
|
130
|
+
agent/tools/reply.ts mounted @open-everywhere/core
|
|
131
|
+
agent/tools/report_run_failed.ts mounted @open-everywhere/core
|
|
132
|
+
agent/tools/request_access.ts mounted @open-everywhere/core
|
|
133
|
+
agent/tools/request_credential_grant.ts mounted @open-everywhere/core
|
|
134
|
+
agent/tools/resume.ts mounted @open-everywhere/core
|
|
135
|
+
agent/tools/revoke_connector.ts mounted @open-everywhere/core
|
|
136
|
+
agent/tools/revoke_credential_grant.ts mounted @open-everywhere/core
|
|
137
|
+
agent/tools/revoke_routine_permissions.ts mounted @open-everywhere/core
|
|
138
|
+
agent/tools/rotate_webhook.ts mounted @open-everywhere/core
|
|
139
|
+
agent/tools/run_routine_now.ts mounted @open-everywhere/core
|
|
140
|
+
agent/tools/sandbox_tools.ts mounted @open-everywhere/core
|
|
141
|
+
agent/tools/search.ts mounted @open-everywhere/core
|
|
142
|
+
agent/tools/session_cost.ts mounted @open-everywhere/core
|
|
143
|
+
agent/tools/set_dm_delivery.ts mounted @open-everywhere/core
|
|
144
|
+
agent/tools/set_spend_limit.ts mounted @open-everywhere/core
|
|
145
|
+
agent/tools/set_state.ts mounted @open-everywhere/core
|
|
146
|
+
agent/tools/spawn_thread_session.ts mounted @open-everywhere/core
|
|
147
|
+
agent/tools/spend_report.ts mounted @open-everywhere/core
|
|
148
|
+
agent/tools/stand_down.ts mounted @open-everywhere/core
|
|
149
|
+
agent/tools/subscribe_pr.ts mounted @open-everywhere/core
|
|
150
|
+
agent/tools/unlink_identity.ts mounted @open-everywhere/core
|
|
151
|
+
agent/tools/update_status.ts mounted @open-everywhere/core
|
|
152
|
+
agent/tools/usage_report.ts mounted @open-everywhere/core
|
|
153
|
+
agent/tools/walk_pr.ts mounted @open-everywhere/core
|
|
154
|
+
agent/tools/web_fetch.ts framework-disabled
|
|
155
|
+
agent/tools/work.ts mounted @open-everywhere/core
|
|
156
|
+
agent/tools/write_file.ts framework-disabled
|