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
28 changes: 28 additions & 0 deletions apps/sarah-s-app-fri-aug-21-11-53-20-am/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# Environment variables
.env
.env.local
.env.*.local
44 changes: 44 additions & 0 deletions apps/sarah-s-app-fri-aug-21-11-53-20-am/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# sarah-s-app-fri-aug-21-11-53-20-am

This is a Datadog App scaffolded with `npm create @datadog/apps`.

Datadog Apps are React + TypeScript applications bundled by Vite and embedded in the Datadog product experience. Frontend code runs in the browser. Backend functions live in `*.backend.*` files and execute through Datadog's managed runtime.

## DRUIDS components

This app uses the published `@datadog/druids` package. In scaffolded apps, import components from `@datadog/druids/[category]/[Component]`; do not import private web-ui paths like `@druids/ui/...`.

- The scaffold already wraps the app in `DruidsEnvironment` and imports `@datadog/druids/styles.css` at the React root. Keep that setup in place if you restructure the root.
- Discover available components by browsing the installed package. Treat the `exports` map in `node_modules/@datadog/druids/package.json` as the source of truth for public entry points, and explore the corresponding category directories under `node_modules/@datadog/druids/dist` instead of relying on a hard-coded component list.
- After choosing an exported component, inspect its TypeScript definitions under `node_modules/@datadog/druids/dist/**/*.d.mts` before inventing props or imports. For icons, only use entry points that are present in the installed package.
- Start with the [DRUIDS docs](https://druids.datadoghq.com/), especially [Foundations](https://druids.datadoghq.com/foundations), [Spacing & Layout](https://druids.datadoghq.com/foundations/spacing-and-layout), [Typography](https://druids.datadoghq.com/foundations/typography), and [Components](https://druids.datadoghq.com/components). The docs cover the full internal DRUIDS library; the public `@datadog/druids` package exposes only a subset for Datadog Apps.
- Use the docs after confirming the local API to understand design intent, layout guidance, examples, and component selection tradeoffs.
- Prefer appropriate DRUIDS layout and typography components over ad hoc HTML wrappers or inline CSS. Use component props and design tokens for spacing, size, and variants.

## Read relevant guides

- For embedded Datadog app context, routing, navigation, browser storage, or parent-page constraints, read `docs/agents/runtime-context.md`.
- For writing backend functions in `*.backend.ts` or `*.backend.js` files, or for calling backend functions from frontend code, read `docs/agents/backend-functions.md`.
- For local development, auth, deploy, publish, `DD_APPS_PUBLISH`, or deploy troubleshooting, read `docs/agents/build-upload-auth.md`.
- For GitHub Actions CI/CD setup, read `docs/agents/cicd.md`.
- For choosing between DDSQL and Action Catalog, configuring Connections, or querying app datastores, read `docs/agents/data.md`.
- For triggering or polling a Workflow Automation workflow from a backend function, read `docs/agents/workflow-automation.md`.
- For upgrading `@datadog/vite-plugin` or `@datadog/action-catalog`, read `docs/agents/upgrading.md`.

## General rules

- Keep privileged Datadog API calls, third-party calls, and secret-dependent work in backend functions.
- Do not hardcode API keys, app keys, OAuth tokens, passwords, or third-party credentials.
- Set the `apps.name` and `apps.description` fields in the `datadogVitePlugin` configuration in `vite.config.ts` to concise, user-facing values that describe the app.
- Prefer the generated npm scripts in `package.json`; this scaffold uses npm.
- Never change `apps.identifier` in `vite.config.ts`. It is this app's permanent identity, not the app's UUID from App Builder — changing it makes the next upload create a duplicate app.
- Before inventing package imports or component props, inspect installed package exports and TypeScript definitions.

## Broader Datadog Apps guidance

- For scaffolding a new app from scratch, use the Datadog Apps agent skill when it is available.
- Use Playwright when available for browser validation, including screenshots for visual design changes.
- Use the Datadog `pup` CLI (https://github.com/DataDog/pup) when available for Datadog API inspection and troubleshooting.
- Use Datadog MCP tools when available for Datadog-specific lookup, diagnostics, or API-backed workflows.

Primary docs: https://docs.datadoghq.com/actions/datadog_apps/
1 change: 1 addition & 0 deletions apps/sarah-s-app-fri-aug-21-11-53-20-am/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Backend Functions

Backend functions are Datadog-managed server-side functions. They do not ship to the browser.

## File and export conventions

- Backend files match `*.backend.ts`, `*.backend.js`, `*.backend.tsx`, or `*.backend.jsx`.
- Export named async functions from backend files.
- Frontend code imports backend functions like normal ES modules.
- The Datadog Vite plugin rewrites backend imports into proxy calls at build time.

## Runtime behavior

- Local development bundles backend functions through Vite middleware and executes them through Datadog preview infrastructure.
- Deployed apps call backend functions through the embedded Datadog runtime bridge.
- Backend functions do not run in the user's local Node.js process.

## Backend helper library

Datadog provides `@datadog/apps-backend`, a library of tools to make backend function development easier. Check it out when working on backend functions.

## Security rules

- Keep privileged Datadog API calls, third-party calls, and secret-dependent work in backend functions.
- Never hardcode API keys, app keys, OAuth tokens, passwords, private keys, or third-party credentials.
- Frontend code should not call Datadog APIs or other privileged services directly.
- Validate frontend inputs before using them in backend function calls.

## Action Catalog

Prefer `@datadog/action-catalog` for supported Datadog, cloud, SaaS, and HTTP workflows. Check the installed package exports before generating imports; do not invent subpaths.

```ts
// src/listHosts.backend.ts
import { listHosts, type ListHostsResponse } from '@datadog/action-catalog/dd/hosts';

export async function getHosts(filter?: string): Promise<ListHostsResponse> {
return listHosts({
inputs: {
filter: filter ?? '*',
count: 10,
include_hosts_metadata: true,
},
});
}
```

```tsx
// src/App.tsx
import { useQuery } from '@tanstack/react-query';

import { getHosts } from './listHosts.backend';

function HostCount() {
const hostsQuery = useQuery({
queryKey: ['hosts', '*'],
queryFn: () => getHosts('*'),
});

if (hostsQuery.isLoading) {
return <span>Loading hosts...</span>;
}

if (hostsQuery.isError) {
return <span>Unable to load hosts.</span>;
}

return <span>{hostsQuery.data?.host_list?.length ?? 0}</span>;
}
```

Always wrap backend function proxies before passing them to React Query or
another framework callback. Do not use `queryFn: getHosts`: React Query calls
its callback with a context object containing an `AbortSignal`, and the
embedded app bridge cannot structured-clone that object for a backend
invocation. Pass only the cloneable arguments the backend function declares:

```tsx
// Correct
queryFn: () => getHosts('*'),

// Incorrect
queryFn: getHosts,
```

The generated app wraps React in `QueryClientProvider` in `src/main.tsx`. Prefer React Query for backend function calls that need loading, error, caching, retry, refetch, or deduplication behavior.

## Broader data workflows

- For choosing between DDSQL and Action Catalog, configuring Connections, or querying app datastores, read `docs/agents/data.md`.
- For triggering or polling a Workflow Automation workflow, read `docs/agents/workflow-automation.md`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Build, Auth, Deploy, And Publish

This scaffold uses npm. Prefer the scripts in `package.json` over ad hoc commands.

## Scripts

- `npm run dev` — start the local Vite dev server.
- `npm run typecheck` — TypeScript check without emitting files. Use this for credential-free validation.
- `npm run lint` / `npm run lint:fix` — run ESLint.
- `npm run build` — production build (does not deploy by default).
- `npm run deploy` — build, upload, and publish the app live.
- `npm run publish` — publish the most recently uploaded version without rebuilding.

## App identity (do not change)

- `apps.identifier` in `vite.config.ts` is this app's permanent identity. It was generated once when the project was scaffolded.
- Every upload updates the app that matches this identifier. **Never change it.** Changing it — including pasting the app's UUID from App Builder into it — makes the next upload create a brand-new duplicate app instead of updating the existing one.
- `apps.identifier` is NOT the app UUID shown in App Builder. The UUID is assigned by Datadog; the identifier is a stable local key. Do not copy one into the other.

## Auth

Apps use **OAuth by default**. On first `npm run dev`, a browser window opens for Datadog login and the token is cached in the system keyring. No credentials needed in advance.

**API key fallback** — use when OAuth isn't available (headless CI, restricted networks):

1. Confirm `.env.local` is gitignored — the scaffold includes `*.local` in `.gitignore` by default.
2. Create `.env.local` at the project root with placeholders:

```
DD_API_KEY=REPLACE_WITH_YOUR_API_KEY
DD_APP_KEY=REPLACE_WITH_YOUR_APP_KEY
```

3. Open the file for editing — do not ask users to paste key values into the conversation:

```bash
cursor .env.local 2>/dev/null || code .env.local 2>/dev/null || open .env.local
```

4. Direct the user to replace the placeholders. Keys are at:
- API keys: `https://app.datadoghq.com/organization-settings/api-keys`
- Application keys: `https://app.datadoghq.com/organization-settings/application-keys` — the key needs **two scopes**: **Actions API Access** and **Apps**

Vite reads `.env.local` automatically once real values are in place.

**`.env.local` not being picked up** — the scaffolded `vite.config.ts` reads credentials via `process.env`, which does not include `.env.local` at config evaluation time. Fix with Vite's `loadEnv`:

```ts
import { defineConfig, loadEnv } from 'vite';

export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
return {
plugins: [datadogVitePlugin({ auth: { apiKey: env.DD_API_KEY, appKey: env.DD_APP_KEY } })],
};
});
```

Restart the dev server after updating `vite.config.ts`.

## Non-US1 site

Set `auth.site` in `vite.config.ts` so local dev and deploys target the right site:

```ts
datadogVitePlugin({ auth: { site: '<YOUR_DATADOG_SITE>' } });
```

## Deploy

Build, upload, and publish in one command:

```bash
npm run deploy
```

With API keys (CI environments):

```bash
export DD_API_KEY="<YOUR_API_KEY>"
export DD_APP_KEY="<YOUR_APPLICATION_KEY>"
npm run deploy
```

A successful deploy prints a Datadog URL for the app.

**Deploy without publishing** — upload as a draft without going live:

```bash
npm run deploy -- --no-publish
# or
DD_APPS_PUBLISH=false npm run deploy
```

`DD_APPS_PUBLISH=false` is useful in CI when publishing is a separate step.

## Publish

Publish the most recently uploaded version without rebuilding:

```bash
npm run publish
```

Publish a specific version by ID:

```bash
npm run publish -- --version <version-id>
```

When using `--version` without a cache file, set `DD_APPS_IDENTIFIER` to the app's identifier.

**Older scaffolded projects** — if `deploy` and `publish` scripts are missing, add them to `package.json` (requires `@datadog/vite-plugin` >= 3.2.0):

```json
{ "scripts": { "deploy": "datadog-apps deploy", "publish": "datadog-apps publish" } }
```

## Troubleshooting

**401 / missing authentication token / credentials not configured**

- OAuth: if the browser window didn't open, the environment may not support it. Fall back to API keys.
- API keys: verify `DD_API_KEY` and `DD_APP_KEY` are set and the application key has both **Actions API Access** and **Apps** scopes.
- Check `auth.site` in `vite.config.ts` matches the credentials' Datadog site.

**403 "you do not have access to this app" on upload**

The application key needs both scopes enabled — not just one:

1. **Actions API Access** — required for backend function execution.
2. **Apps** (or **App Builder**) — required for uploading and publishing.

Go to `https://app.datadoghq.com/organization-settings/application-keys`, confirm both scopes, or create a new key with both.

**Build succeeds but nothing deploys**

- Use `npm run deploy`, not `npm run build`, when the intent is to deploy.
- Check whether `DD_APPS_PUBLISH` is set to `false` in the environment — the app uploads as a draft but does not go live. Unset the variable or run `npm run publish` separately.
- Confirm `dryRun` in `vite.config.ts` is not `true`.
- Confirm `DD_APPS_UPLOAD_ASSETS` is set — `npm run deploy` does this automatically.

**Build fails with missing credentials**

- Current scaffold versions may make `npm run build` exercise Datadog deploy behavior.
- Cache OAuth credentials first (`npm run dev`), or set `DD_API_KEY` and `DD_APP_KEY`.
- For credential-free validation, prefer `npm run typecheck`.

**Node or scaffolding errors**

- Check `package.json` `engines.node` for the supported Node.js versions.
- Use Volta, nvm, or fnm to switch versions. Prefer a current Node 22 release when debugging.

**Datadog site mismatch**

- Inspect `vite.config.ts` for the configured site and confirm CI uses the same value.
42 changes: 42 additions & 0 deletions apps/sarah-s-app-fri-aug-21-11-53-20-am/docs/agents/cicd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# CI/CD

## GitHub Actions

Use `DataDog/apps-github-action` to deploy on pushes to the deployment branch. Keep `app-directory` aligned with the app's path in the repository.

```yaml
name: Continuous Deployment
on:
push:
branches:
- main

permissions:
contents: read

jobs:
deploy-app:
name: Deploy Datadog App
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Node.js
uses: actions/setup-node@v6

- name: Deploy
uses: DataDog/apps-github-action@v0.0.2
with:
datadog-api-key: ${{ secrets.DATADOG_API_KEY }}
datadog-app-key: ${{ secrets.DATADOG_APP_KEY }}
app-directory: .
```

Store `DATADOG_API_KEY` and `DATADOG_APP_KEY` as [encrypted secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions) in the repository or organization settings. The application key needs both **Actions API Access** and **Apps** scopes.

For non-US1 organizations, configure the Datadog site in `vite.config.ts` and ensure CI and local config are aligned.
Loading
Loading