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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
87 changes: 87 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: CI

on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened, labeled, unlabeled]
workflow_dispatch:

permissions:
contents: read

jobs:
build:
name: Validate, test, and build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout pull request branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Run importer tests
run: npm test
- name: Import submissions
if: github.event.pull_request.head.repo.full_name == github.repository
run: npm run import:submissions
- name: Validate submissions from forks
if: github.event.pull_request.head.repo.full_name != github.repository
run: npm run check:submissions
- name: Commit generated content
if: github.event.pull_request.head.repo.full_name == github.repository
run: |
if [ -n "$(git status --porcelain src/content/solutions src/content/guides public/bundles)" ]; then
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add src/content/solutions src/content/guides public/bundles
git commit -m "chore: import solution submissions"
git push
else
echo "Generated content is current."
fi
- name: Type check
run: npm run check
- name: Build site
run: npm run build

guard-scope:
name: Guard pull request scope
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
- name: Reject mixed submission and site changes
env:
GH_TOKEN: ${{ github.token }}
PR: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
set -euo pipefail
if printf '%s' "$LABELS" | grep -q '"allow-mixed-changes"'; then
echo "Scope override label present."
exit 0
fi
FILES="$(gh api --paginate "repos/$REPO/pulls/$PR/files" --jq '.[].filename')"
SUBMISSION="$(printf '%s\n' "$FILES" | grep -E '^submissions/' || true)"
SITE="$(printf '%s\n' "$FILES" \
| grep -vE '^submissions/' \
| grep -vE '^src/content/solutions/' \
| grep -vE '^src/content/guides/' \
| grep -vE '^public/bundles/' \
|| true)"
if [ -n "$SUBMISSION" ] && [ -n "$SITE" ]; then
echo "::error::This pull request mixes submission content with site or repository changes. Split it into separate pull requests or add the allow-mixed-changes label."
exit 1
fi
echo "Pull request scope is valid."
52 changes: 52 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Deploy to GitHub Pages

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Test importer
run: npm test
- name: Regenerate submissions
run: npm run import:submissions
- name: Type check
run: npm run check
- name: Build
run: npm run build
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: dist

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -427,3 +427,14 @@ FodyWeavers.xsd
*.msix
*.msm
*.msp

# Astro and local gallery tooling
dist/
.astro/
.playwright-cli/
.DS_Store
.idea/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
4 changes: 4 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}
11 changes: 11 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}
58 changes: 58 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
## Development

When starting the dev server, use background mode:

```
astro dev --background
```

Manage the background server with `astro dev stop`, `astro dev status`, and `astro dev logs`.

Before building or serving the gallery, generate content from the exploded
submissions:

```bash
npm run import:submissions
npm test
npm run check
npm run build
```

Generated files under `src/content/solutions/`, `src/content/guides/`, and
`public/bundles/` come from `submissions/`; do not hand-edit them.

## Documentation

Full documentation: https://docs.astro.build

Consult these guides before working on related tasks:

- [Adding pages, dynamic routes, or middleware](https://docs.astro.build/en/guides/routing/)
- [Working with Astro components](https://docs.astro.build/en/basics/astro-components/)
- [Using React, Vue, Svelte, or other framework components](https://docs.astro.build/en/guides/framework-components/)
- [Adding or managing content](https://docs.astro.build/en/guides/content-collections/)
- [Adding styles or using Tailwind](https://docs.astro.build/en/guides/styling/)
- [Supporting multiple languages](https://docs.astro.build/en/guides/internationalization/)

## Important Notes

- One gallery entry represents one complete exploded Power Platform solution.
- Each submission lives at `submissions/<slug>/solution/` with gallery-only
`metadata.json` and optional `README.md` beside it.
- Modern workflow exports include their saved canvas under an
`associatedData.graph` object inside each `Workflows/*.json`. It contains the
nodes, edges, handles, and x/y positions needed for an accurate preview.
- The first release rejects workflows without a saved graph rather than guessing
a layout from executable actions.
- Agent architecture is derived from `bots/**` and `botcomponents/**`; component
ownership must be resolved per agent rather than applying every solution
component to every bot.
- Agent previews use a deterministic hub-and-spoke layout: primary agents are
centered, owned agents/tools/skills share radial rings, and straight edges
attach to the nearest node side. Node color is presentation-only and does not
alter the imported topology.
- The browser receives compact allowlisted graph data. Raw schemas, icons,
environment connection identifiers, and source blobs stay out of generated
content.
- Download ZIPs are deterministic rebuilds of the `solution/` contents at archive
root; gallery sidecars are excluded.
1 change: 1 addition & 0 deletions CLAUDE.md
99 changes: 99 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Contributing a solution

Contribute one complete Copilot Studio / Power Platform solution by adding an
exploded solution folder to `submissions/` and opening a pull request.

## Export and unpack

1. Export the solution from Power Platform as an **unmanaged** solution.
2. Unpack the exported ZIP with `pac solution unpack`, Power Platform CLI, or a
standard ZIP tool.
3. Copy the unpacked files into `submissions/<slug>/solution/`.
4. Add the gallery sidecar files described below.

Do not submit a ZIP. Keeping the payload exploded makes agents, workflows,
connectors, and code reviewable in the pull request.

## Submission layout

```text
submissions/<slug>/
├── metadata.json # required gallery metadata
├── README.md # optional human-facing overview
└── solution/ # required exploded payload
├── solution.xml
├── customizations.xml
├── Workflows/*.json
├── bots/*/
├── botcomponents/*/
└── ...other solution files
```

The slug must use lowercase letters, numbers, and single hyphens.

### `metadata.json`

```json
{
"name": "Customer Service Operations",
"description": "Agents and workflows for triage, policy review, and assisted resolution.",
"tags": ["customer-service", "triage", "human-in-the-loop"],
"author": "Your Name",
"authorUrl": "https://github.com/your-login",
"createdAt": "2026-08-12",
"updatedAt": "2026-08-12",
"featured": false
}
```

Required fields: `name`, `description`, `tags`, and `author`. Optional fields:
`authorUrl`, `authorGithub`, `createdAt`, `updatedAt`, and `featured`.

Solution identity, version, publisher, component counts, agents, and workflows
are derived from the exploded payload and cannot be overridden in metadata.

### `README.md`

The optional README is written for gallery visitors. Explain the scenario,
agents, workflows, prerequisites, and import-time configuration. It becomes the
Overview tab and is never included in the downloadable solution ZIP.

## Workflow preview requirement

Each submitted `Workflows/*.json` must include the saved designer graph produced
by the modern workflow designer. The importer reads the graph's nodes, edges,
handles, and positions from the workflow JSON. A workflow without that graph
fails validation.

## Safety and privacy

- Remove secrets, tokens, customer data, tenant-specific email addresses, and
other sensitive content before submitting.
- The repository never executes submitted solution code.
- Symlinks, path escapes, oversized files, and oversized payloads are rejected.
- The browser receives a compact normalized preview, not raw parameter schemas,
icons, connection identifiers, or source blobs.
- The downloadable ZIP contains the submitted `solution/` contents verbatim, so
review those files carefully.

## Validate locally

```bash
npm install
npm test
npm run check:submissions
npm run import:submissions
npm run astro -- check
npm run build
```

Copy [`submissions/_template/`](submissions/_template/) to start.

## Pull-request scope

Keep submission changes separate from site, importer, workflow, or repository
configuration changes. CI rejects mixed-scope pull requests unless maintainers
apply the `allow-mixed-changes` label.

By contributing, you agree that the submitted content is shared under this
repository's [MIT license](LICENSE).
Loading
Loading