Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1c19589
Publish each release's Compose files and draft images.
Oct 2, 2026
eba8300
Report the process settings Core loaded, and check them before startup.
Oct 2, 2026
1a9b11b
Replace the Python Core installer with Compose and a Go oac command.
Oct 2, 2026
95c1991
Describe the Compose installation and drop the old config.json flow.
Oct 2, 2026
44be316
Leave lifecycle to Docker Compose and keep oac for checks and domain …
Oct 2, 2026
02d4d5d
Keep Compose startup working with the published gateway image.
Oct 2, 2026
ad36dd4
Default Compose images to the latest tags.
Oct 2, 2026
6e04489
Wait for the execution lease to clear before a lifecycle restart.
Oct 2, 2026
e5a32f5
Run managed domain setup inside the gateway
Oct 2, 2026
ac15b8d
Move Compose initialization and health checks into oac
Oct 2, 2026
53c656c
Split deploy/install by what each part installs
Oct 2, 2026
1f107e1
Let Core and Web own their startup defaults
Oct 3, 2026
e1cee2b
Simplify the Compose installation around the new defaults
Oct 3, 2026
f47190c
Fix CI after moving Harness and installer defaults into Core
Oct 3, 2026
2b6fdb7
Require checking CI after each pull request push
Oct 3, 2026
1a53a32
Drop the Docker CLI from the gateway image
Oct 3, 2026
619a826
Serve Core's API through Web and drop managed HTTPS
Oct 3, 2026
ec5f85e
Update docs and the console for Web forwarding
Oct 3, 2026
8f47367
Match the console tests to the public-address notice
Oct 3, 2026
5bcf938
Forward the API reference and keep Core connections warm
Oct 3, 2026
38eba25
Add a local installer that builds this checkout
Oct 3, 2026
63d133a
Run installer checks when the local installer changes
Oct 3, 2026
fd61a9e
Rename the checkout installer to install.dev.sh
Oct 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/api-acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,9 @@ jobs:
with:
go-version-file: go.mod
cache: true
- name: Build standalone commands and verify migration entrypoints
env:
OAC_TEST_DATABASE_URL: postgres://agents_api:agents_api_test_only@127.0.0.1:${{ job.services.postgres.ports['5432'] }}/oac_ci_tests?sslmode=disable
- name: Build standalone commands
run: |
OAC_DEV_CORE_BUILD_DIR="$RUNNER_TEMP/oac-core-build" make build-core
OAC_DATABASE_URL="$OAC_TEST_DATABASE_URL" "$RUNNER_TEMP/oac-core-build/oac-core-migrate"
"$RUNNER_TEMP/oac-core-build/oac-core-device" --help
"$RUNNER_TEMP/oac-core-build/oac-core-environment-key" --help
- uses: actions/setup-python@v6
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,12 @@ jobs:
- uses: actions/checkout@v7
with:
ref: ${{ inputs.ref || github.sha }}
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Allocate an isolated Compose project
run: python3 -c 'import uuid; print("COMPOSE_SMOKE_PROJECT=oac-smoke-" + uuid.uuid4().hex)' >> "$GITHUB_ENV"
- name: Start published images and verify the installation
- name: Build the images, start the installation and verify it
timeout-minutes: 17
run: python3 scripts/compose-smoke.py
- name: Remove test containers and volumes
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ jobs:
for asset in "$HOME/.oac/build/core-distribution/"*; do
if [[ -f "$asset" ]]; then ln "$asset" "$HOME/.oac/build/release-upload/"; fi
done
cp deploy/install-release.sh "$HOME/.oac/build/release-upload/install.sh"
cp deploy/install.sh "$HOME/.oac/build/release-upload/install.sh"
(cd "$HOME/.oac/build/release-upload" && sha256sum install.sh > install.sh.sha256)
- uses: actions/upload-artifact@v6
with:
Expand All @@ -141,8 +141,8 @@ jobs:
compression-level: 0
if-no-files-found: error

- name: Sign in to GHCR for version releases
if: github.event_name == 'push'
- name: Sign in to GHCR
if: github.event_name == 'push' || inputs.draft_release
env:
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
Expand All @@ -159,5 +159,5 @@ jobs:
RELEASE_MODE: ${{ github.event_name == 'push' && 'publish' || 'draft' }}
run: python3 scripts/publish-core-release.py --assets "$HOME/.oac/build/release-upload"
- name: Remove registry credentials
if: always() && github.event_name == 'push'
if: always() && (github.event_name == 'push' || inputs.draft_release)
run: rm -f "$RUNNER_TEMP/oac-release-docker/config.json"
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ OpenAgentCore is pre-release. Replace superseded interfaces, execution paths and
## Working in this repository

- For each new task, create a new Git worktree. Name its directory after that change's commit subject, in kebab-case, beside the checkout. Run `git pull --ff-only` on the base branch, and create the feature branch in that worktree before development.
- After every push to a pull request, wait 60 seconds, then run `gh pr checks` and confirm CI passes. Fix any failure before reporting the work as done.
- [CONTRIBUTING.md](CONTRIBUTING.md): documentation ownership, repository boundary, workflow, independent review, required checks and naming.
- [Develop OpenAgentCore](docs/development.md): setup, the repository map, focused checks and [each extension boundary](docs/development.md#choose-an-extension-boundary).
- [API index](docs/api/index.md): each route's caller and credential.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ This guide owns how to work in the repository: documentation ownership, the repo
| Distribution builds, Runtime image builds, CI and publication | [Maintainer guide](docs/maintainers.md) |
| Website: landing page, bilingual documentation maintenance, documentation site build and GitHub Pages publication | [Website guide](website/README.md) |
| Self-hosted Runtime installation, recovery and local operation | [Self-hosted execution](docs/getting-started/self-hosted.md) |
| Installer lifecycle, locking, generated state, managed HTTPS and downloads | [Installer design rules](deploy/install/README.md) |
| Installer lifecycle, locking, generated state, managed HTTPS and downloads | [Deployment](deploy/README.md) and [Node installer](deploy/node/README.md) |
| Operator installation and alternatives | [Installation](docs/getting-started/install.md), [installation options](docs/getting-started/install-options.md) |
| Settings, defaults, files and installation layout | [Configuration](docs/configuration.md) |
| Operator commands, keys, backup and version policy | [Operations](docs/getting-started/operations.md) |
Expand Down
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,13 @@ check-microsandbox-provider:
check-distribution:
node --test scripts/build-native-catalog.test.mjs
go test ./services/web -count=1
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s deploy/install -p 'test_*.py'
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s deploy/node -p 'test_*.py'
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s deploy/compose -p 'test_*.py'
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s scripts/acceptance -p 'test_*.py'
PYTHONDONTWRITEBYTECODE=1 python3 deploy/test_install.py
PYTHONDONTWRITEBYTECODE=1 python3 scripts/core-distribution-manifest.test.py
PYTHONDONTWRITEBYTECODE=1 python3 scripts/publish-core-release.test.py
PYTHONDONTWRITEBYTECODE=1 python3 scripts/install-release.test.py
PYTHONDONTWRITEBYTECODE=1 python3 scripts/config-reference.py --check
bash -n deploy/install/install.sh deploy/install-release.sh scripts/build-web.sh scripts/build-core-distribution.sh scripts/build-core-image-context.sh scripts/prepare-release-runtimes.sh
bash -n deploy/install.sh scripts/build-web.sh scripts/build-core-distribution.sh scripts/build-core-image-context.sh scripts/prepare-release-runtimes.sh
./scripts/build-web.sh

build-core-distribution:
Expand Down
2 changes: 1 addition & 1 deletion apps/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pnpm --filter @oac/web build
pnpm test:web:acceptance
```

`pnpm test:web:acceptance` runs the Playwright tests in `apps/web/e2e` in Chrome against the fixture console. After each test, every spec except `domain.spec.ts` checks that the browser sent nothing to `/v1` and no `Authorization` header. The tests do not exercise `services/web` or a real Core; the console server has its own Go tests. `make check-web` runs all of these; [CONTRIBUTING.md](../../CONTRIBUTING.md) lists the repository's required checks.
`pnpm test:web:acceptance` runs the Playwright tests in `apps/web/e2e` in Chrome against the fixture console. After each test, every spec checks that the browser sent nothing to `/v1` and no `Authorization` header. The tests do not exercise `services/web` or a real Core; the console server has its own Go tests. `make check-web` runs all of these; [CONTRIBUTING.md](../../CONTRIBUTING.md) lists the repository's required checks.

## README screenshots

Expand Down
95 changes: 0 additions & 95 deletions apps/web/e2e/domain.spec.ts

This file was deleted.

2 changes: 1 addition & 1 deletion apps/web/e2e/nodes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ test("issues no command before the installation is read, for a loopback public U
await page.unroute("**/core/v1/installation");
await add.getByRole("button", { name: "Try again" }).click();
// Nodes on other machines can't reach a loopback public_url.
await expect(add.getByRole("status")).toHaveText("Configure a domain and HTTPS in System before adding nodes.");
await expect(add.getByRole("status")).toHaveText("Set a public HTTPS address before adding nodes.");
await expect(add.getByRole("button", { name: "Generate command" })).toHaveCount(0);
await add.getByRole("button", { name: "Close dialog" }).click();
await expect(page.getByRole("button", { name: "Add node", exact: true })).toBeDisabled();
Expand Down
8 changes: 4 additions & 4 deletions apps/web/e2e/overview-readiness.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ test("successful empty reads preserve true zero counts and empty states", async
await expect(failed(page)).toHaveCount(0);
});

test("local-only address has a domain setup link on all three pages and blocks Add node", async ({ page, request }) => {
test("local-only address links to System on other pages and blocks Add node", async ({ page, request }) => {
await openConsole(page, request, "overview", { installation: "local" });
const notice = page.getByRole("status", { name: "Public address needs attention" });
await expect(notice.getByRole("button", { name: "Configure domain and HTTPS" })).toBeVisible();
await expect(notice.getByRole("button", { name: "Review the public address" })).toBeVisible();
await expect(page.locator(".getting-started-step").first()).toContainText("To do");
await expect(page.locator(".getting-started-step").first()).toContainText("Configure HTTPS");
await page.getByRole("button", { name: "Nodes", exact: true }).click();
Expand All @@ -89,7 +89,7 @@ test("local-only address has a domain setup link on all three pages and blocks A
await expect(page.getByText("Add node is unavailable while the public address is local only.")).toBeVisible();
await page.getByRole("button", { name: "System", exact: true }).click();
await expect(notice).toBeVisible();
await expect(page.getByRole("button", { name: "Configure domain and HTTPS" })).toHaveCount(1);
await expect(notice.getByRole("button", { name: "Review the public address" })).toHaveCount(0);
expect(await writes(request)).toEqual([]);
});

Expand All @@ -102,7 +102,7 @@ for (const language of ["en", "zh-CN"] as const) {
await page.getByRole("menuitemradio", { name: "简体中文" }).click();
}
await expect(page.locator(".overview-activity .error-state")).toContainText(language === "en" ? "Could not read the data" : "无法读取数据");
await expect(page.locator(".installation-notice")).toContainText(language === "en" ? "Configure HTTPS before connecting" : "连接外部应用和节点前");
await expect(page.locator(".installation-notice")).toContainText(language === "en" ? "Set a public HTTPS address before connecting" : "连接外部应用和节点前");
if (language === "zh-CN") await expect(page.locator("body")).not.toContainText("Core request failed");
await expect(page.getByRole("article").first()).toContainText(language === "en" ? "Down" : "不可用");
for (const width of [1280, 1440]) {
Expand Down
3 changes: 1 addition & 2 deletions apps/web/src/ConsoleApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { SandboxManagerView } from "./features/sandbox/SandboxManagerView";
import { SessionLogPage } from "./features/sessions/SessionLogPage";
import { SessionPage } from "./features/sessions/SessionPage";
import { SkillsPage } from "./features/skills/SkillsPage";
import { DomainPage } from "./features/system/DomainPage";
import { SystemPage } from "./features/system/SystemPage";
import { VaultsPage } from "./features/vaults/VaultsPage";
import { consoleDepth, ConsoleNavigationContext, useConsoleNavigation, hashWithParams, routeParamsFromHash, type ConsoleIntent, type RouteParams } from "./lib/console-navigation";
Expand Down Expand Up @@ -57,7 +56,7 @@ function ConsolePage({ view }: { view: ConsoleView }) {
case "vaults": return <VaultsPage />;
case "projects": return <ProjectsPage />;
case "nodes": return <SandboxManagerView />;
case "system": return params.id === "sandbox" ? <SandboxDeploymentPage /> : params.id === "domain" ? <DomainPage /> : <SystemPage />;
case "system": return params.id === "sandbox" ? <SandboxDeploymentPage /> : <SystemPage />;
}
}

Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/components/InstallationNotice.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ const installation: CoreInstallation = {
};

describe("local-only installation notice", () => {
it("links to domain setup without exposing installer commands", () => {
it("links to the public address without exposing installer commands", () => {
const html = renderToStaticMarkup(<InstallationNotice installation={installation} />);
expect(html).toContain("Configure domain and HTTPS");
expect(html).toContain("Configure HTTPS before connecting applications and nodes");
expect(html).toContain("Review the public address");
expect(html).toContain("Set a public HTTPS address before connecting applications and nodes");
expect(html).not.toContain("config.json");
expect(html).not.toContain("oac apply");
});
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/InstallationNotice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export function InstallationNotice({ installation }: { installation: CoreInstall
if (!installation?.local_only) return null;
return <aside className="installation-notice" role="status" aria-label={t("installationNotice.title")}>
<p>{t("installationNotice.body")}</p>
{view !== "system" || params.id ? <button className="text-action" onClick={() => navigate("system", { id: "domain" })}>{t("installationNotice.configure")}</button> : null}
{view !== "system" || params.id ? <button className="text-action" onClick={() => navigate("system")}>{t("installationNotice.configure")}</button> : null}
</aside>;
}
Loading
Loading