Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 6 additions & 2 deletions .github/workflows/static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,18 @@ jobs:
astro-${{ runner.os }}-
- name: Install dependencies
run: pnpm install --frozen-lockfile --prefer-offline
- name: Test site plugins
run: pnpm test
- name: Setup Pages
id: pages
if: github.ref == 'refs/heads/main'
uses: actions/configure-pages@v5
- name: Build site
env:
SITE: ${{ steps.pages.outputs.origin }}
BASE_PATH: ${{ steps.pages.outputs.base_path }}
# The Pages API can report an isolated hostname instead of the public URL.
# Use the public project URL for both pull-request and production builds.
SITE: https://microsoft.github.io
BASE_PATH: /scope
run: pnpm run build
- name: Upload artifact
if: github.ref == 'refs/heads/main'
Expand Down
29 changes: 23 additions & 6 deletions website/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ A static documentation site published to GitHub Pages.
`website/`)
- Deployed by `.github/workflows/static.yml` (build + deploy jobs),
which builds from `website/` via a `working-directory` default and
`website/**` path filters; `site` and `base` are driven by
`actions/configure-pages` outputs with safe localhost defaults
`website/**` path filters; both PR and production builds explicitly use
`SITE=https://microsoft.github.io` and `BASE_PATH=/scope`.
Do not derive these from `actions/configure-pages` outputs, which can
report an isolated hostname instead of the public project URL.
Local development keeps localhost and `/` defaults.

## Where things live

Expand All @@ -29,6 +32,8 @@ A static documentation site published to GitHub Pages.
- `src/plugins/remark-http-snippets.mjs` — custom remark plugin that
expands fenced ` ```http ` blocks into multi-language Starlight
`<Tabs>` (curl, JS fetch, Python, Go, Java, C#)
- `src/plugins/remark-base-path.mjs`: prefixes internal Markdown URLs and
literal MDX `href`/`src` attributes with the configured deployment base
- `astro.config.mjs` — sidebar, plugins, `markdown.remarkPlugins`,
`starlight-openapi` config
- `dist/` — build output (gitignored)
Expand Down Expand Up @@ -125,13 +130,22 @@ Plain JSON examples (response shapes, profile config) stay as

### REST API reference page

- Link to `/reference/api/` for the generated reference landing page.
`/reference/api/operations/` is not a page.
- **Auto-generated** per-endpoint pages live under
`/reference/api/...` (built from
`src/openapi/scope-openapi.json` by `starlight-openapi`).
- The hand-written `reference/rest-api.md` is a narrative overview
with cross-links to the auto-generated pages and the live Swagger.
Don't duplicate the per-endpoint detail there.

### Internal links

Use site-root paths such as `/getting-started/access/` in Markdown links
and literal MDX `href`/`src` attributes. The base-path remark plugin adds
`/scope` in the public build while keeping local root deployments working.
Do not hard-code the deployment prefix in content or code examples.

### Sidebar

Sidebar order is set in `astro.config.mjs`. Adding a new page
Expand All @@ -154,15 +168,18 @@ groups are spread via `...openAPISidebarGroups`.

```sh
pnpm install
pnpm test # plugin regressions, using Node's built-in test runner
pnpm run build # writes dist/
pnpm run dev # local preview at http://localhost:4321
pnpm run refresh:openapi # generate the OpenAPI snapshot from scope-core
```

A green `pnpm run build` is the gate. As of the last edit it produces
**164 pages** (≈ 23 hand-written + the rest auto-generated from the
OpenAPI spec). A drop in page count usually means a content collection
file failed to parse.
Both `pnpm test` and `pnpm run build` must pass. The public build uses
`SITE=https://microsoft.github.io BASE_PATH=/scope pnpm run build`;
exercise that configuration when changing links or deployment settings,
not just the local `/` default. The current snapshot produces **200
pages**, including the generated API reference. An unexpected drop in
page count can indicate a content collection file failed to parse.

## Workflow

Expand Down
32 changes: 29 additions & 3 deletions website/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The product and this documentation site live in
│ │ └── resources/
│ ├── openapi/scope-openapi.json # artifact generated from the API registry
│ ├── plugins/
│ │ ├── remark-base-path.mjs # applies the deployment base to internal links
│ │ └── remark-http-snippets.mjs # turns ```http blocks into multi-language tabs
│ └── content.config.ts
├── astro.config.mjs # sidebar, plugins, starlight-openapi config
Expand All @@ -42,12 +43,21 @@ Sidebar order is defined in `astro.config.mjs`, not by directory order.
| `pnpm dev` | Start local dev server at `localhost:4321` |
| `pnpm build` | Build the production site to `./dist/` |
| `pnpm preview` | Preview the production build locally |
| `pnpm test` | Test site plugins with Node's built-in test runner |
| `pnpm refresh:openapi` | Generate the OpenAPI snapshot from `scope-core` |

## Authoring docs

- Use `.md` for plain Markdown, `.mdx` whenever the page contains JSX
(e.g. Starlight `<Tabs>`).
- Write internal Markdown links and literal MDX `href`/`src` attributes
relative to the site root, such as `/getting-started/access/`.
[src/plugins/remark-base-path.mjs](src/plugins/remark-base-path.mjs)
adds the configured base path at build time. Do not hard-code `/scope`
in content. External URLs, relative links, fragments, and code examples
are left unchanged.
- Link to `/reference/api/` for the generated API reference landing page.
`/reference/api/operations/` has endpoint pages beneath it, but no index.
- Write HTTP examples as a single fenced ` ```http ` block — the
custom remark plugin in
[src/plugins/remark-http-snippets.mjs](src/plugins/remark-http-snippets.mjs)
Expand All @@ -71,9 +81,25 @@ where to look in scope-core for any given topic.
Pushed builds deploy to GitHub Pages via
[../.github/workflows/static.yml](../.github/workflows/static.yml).
The workflow builds from this `website/` directory (via a
`working-directory` default and `website/**` path filters). `site`
and `base` are driven by `actions/configure-pages` outputs with safe
localhost defaults.
`working-directory` default and `website/**` path filters). Both pull-request
and production builds use `SITE=https://microsoft.github.io` and
`BASE_PATH=/scope`, matching the public
[documentation URL](https://microsoft.github.io/scope/).
`actions/configure-pages` still configures deployment, but its reported
hostname and base path are not used to generate URLs: it can report an
isolated Pages hostname instead of the public project URL.

Local development defaults to the site root (`/`). To reproduce the
public deployment locally, run these commands from `website/`:

```sh
pnpm test
SITE=https://microsoft.github.io BASE_PATH=/scope pnpm build
SITE=https://microsoft.github.io BASE_PATH=/scope pnpm preview
```

Open `/scope/` on the preview server. Keep `BASE_PATH` the same for the
build and preview so assets, navigation, and search use the same URLs.

## Learn more

Expand Down
10 changes: 6 additions & 4 deletions website/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { execSync } from 'node:child_process';
import remarkBasePath from './src/plugins/remark-base-path.mjs';
import remarkHttpSnippets from './src/plugins/remark-http-snippets.mjs';

// https://astro.build/config
// `site` and `base` are driven by the GitHub Pages deployment URL in CI
// (set via env vars from `actions/configure-pages` outputs), with safe
// defaults for local development.
// (set explicitly in the deployment workflow), with safe defaults
// for local development.
//
// `DOC_PORT` is read from the `.env` file that `worktree-env` writes to
// the git repo root (so each worktree binds to a unique dev/preview
Expand Down Expand Up @@ -47,13 +48,14 @@ function readDotEnv(name) {
return undefined;
}
const docPort = Number(readDotEnv('DOC_PORT')) || 4300;
const base = process.env.BASE_PATH || '/';

export default defineConfig({
site: process.env.SITE || `http://localhost:${docPort}`,
base: process.env.BASE_PATH || '/',
base,
server: { port: docPort },
markdown: {
remarkPlugins: [remarkHttpSnippets],
remarkPlugins: [[remarkBasePath, { base }], remarkHttpSnippets],
},
integrations: [
starlight({
Expand Down
1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"start": "worktree-env && astro dev",
"build": "astro build",
"preview": "worktree-env && astro preview",
"test": "node --test src/plugins/*.test.mjs",
"astro": "astro",
"refresh:openapi": "cd .. && pnpm --filter api generate:openapi"
},
Expand Down
2 changes: 1 addition & 1 deletion website/src/content/docs/guides/prioritizing-requests.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ queue position updates as soon as you save. The Portal exposes

Priority is editable while a request is **pending** or **paused**.
The exact endpoint shape (single vs bulk) is in the
[REST API reference](/reference/api/operations/). At a glance:
[REST API reference](/reference/api/). At a glance:

- Single-request priority change.
- Bulk priority change for a list of request IDs.
Expand Down
4 changes: 2 additions & 2 deletions website/src/content/docs/guides/submitting-requests-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ https://your-scope.example.com/api-docs

An auto-generated reference of every endpoint, built from the same
OpenAPI spec, also lives in this site at
[REST API reference](/reference/api/operations/).
[REST API reference](/reference/api/).

This page covers the common workflows.

Expand Down Expand Up @@ -201,7 +201,7 @@ idempotency on top by caching the returned `id` if you need it.
`profileId`) so a later edit to the profile doesn't change what your
pipeline runs.
- **Poll sparingly**: prefer the SSE log stream to status polling.
- **Use the reference**: the [REST API reference](/reference/api/operations/)
- **Use the reference**: the [REST API reference](/reference/api/)
is the source of truth for exact request and response shapes. Your
deployment may also provide Swagger UI at `/api-docs`.

Expand Down
6 changes: 3 additions & 3 deletions website/src/content/docs/reference/rest-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: Overview of the Scope REST API and pointer to the auto-generated en
The Scope REST API mirrors what you can do in the Portal and the
`scope` CLI. The full per-endpoint reference is **auto-generated from
the committed OpenAPI snapshot** and lives under
[REST API reference](/reference/api/operations/).
[REST API reference](/reference/api/).

For interactive exploration, your deployment may provide Swagger UI and
a raw OpenAPI document:
Expand Down Expand Up @@ -75,7 +75,7 @@ Generate and fetch per-request evaluation reports.

The API also exposes `agents`, `models`, `mcp-servers`, `skills`,
`extensions`, `insights`, and `report-templates`. See the generated
[REST API reference](/reference/api/operations/) for endpoint-level
[REST API reference](/reference/api/) for endpoint-level
details.

## Request status & outcome
Expand Down Expand Up @@ -118,5 +118,5 @@ published reference.

## See also

- [REST API reference (auto-generated)](/reference/api/operations/)
- [REST API reference (auto-generated)](/reference/api/)
- [Submitting requests (REST API)](/guides/submitting-requests-api/)
2 changes: 1 addition & 1 deletion website/src/content/docs/resources/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,6 @@ profiles, and more — all from the terminal. See

## Where's the API reference?

The auto-generated [REST API reference](/reference/api/operations/) is
The auto-generated [REST API reference](/reference/api/) is
built from the committed OpenAPI snapshot. A narrative overview of the
resource groups is at the [REST API overview](/reference/rest-api/).
38 changes: 38 additions & 0 deletions website/src/plugins/remark-base-path.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { visit } from 'unist-util-visit';

export default function remarkBasePath({ base = '/' } = {}) {
const prefix = `/${base.replace(/^\/+|\/+$/g, '')}`;

function withBase(url) {
if (!url.startsWith('/') || url.startsWith('//')) return url;
const pathname = url.split(/[?#]/, 1)[0];
if (pathname === prefix || pathname.startsWith(`${prefix}/`)) return url;
return `${prefix}${url}`;
}

return function transformer(tree) {
if (prefix === '/') return;

visit(tree, (node) => {
if (node.type === 'link' || node.type === 'image' || node.type === 'definition') {
node.url = withBase(node.url);
}

// MDX anchors and images keep literal attributes outside Markdown link nodes.
if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') {
for (const attribute of node.attributes) {
if (
attribute.type === 'mdxJsxAttribute' &&
(attribute.name === 'href' || attribute.name === 'src') &&
typeof attribute.value === 'string'
) {
attribute.value = withBase(attribute.value);
}
}
}
});
};
}
Loading
Loading