Skip to content

Commit 93b6798

Browse files
authored
feat(build-cli): add flub ai command and AI-enabled (Insiders) devcontainer (#27020)
## Summary - Adds a `flub ai` command that launches an interactive Copilot SDK session to help users pick the right agent alias and MCP server configuration - Creates a new **AI-enabled (Insiders)** devcontainer profile that builds the flub CLI from source during prebuild, making `flub ai` available in the codespace - Updates the base **AI-enabled** profile: simplifies lifecycle hook shapes (object → string), adds `COREPACK_ENABLE_DOWNLOAD_PROMPT=0` env var, and removes `postAttachCommand` that opened Getting Started in VS Code (unreliable since `code` is not always on PATH) - Insiders differs from the base by name, `onCreateCommand` chaining `install-flub.sh`, and `openFiles` path - Shared files like `launcher-prompt.md` live in `ai-agent/` only; `flub ai` searches `ai-agent-insiders/` first then falls back to `ai-agent/` - Adds `FLUB_PERF=1` env var support for oclif performance diagnostics
1 parent 5fd4587 commit 93b6798

File tree

16 files changed

+1010
-13
lines changed

16 files changed

+1010
-13
lines changed

.devcontainer/README.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This repo includes multiple Codespaces/devcontainer profiles under `.devcontaine
77
| `Standard` | `.devcontainer/devcontainer.json` | Full-repo development, heavier tasks, and broad day-to-day work. |
88
| `Lightweight (Review/Docs)` | `.devcontainer/lightweight/devcontainer.json` | Docs, API review, and focused edits with lower compute requirements. |
99
| `AI-enabled` | `.devcontainer/ai-agent/devcontainer.json` | AI-agent-assisted workflows with additional default CLI tooling. |
10+
| `AI-enabled (Insiders)` | `.devcontainer/ai-agent-insiders/devcontainer.json` | AI-enabled plus the `flub ai` launcher command (builds the flub CLI from source). |
1011

1112
## Selecting a profile in Codespaces
1213

@@ -33,6 +34,41 @@ The devcontainer lifecycle hooks are structured for prebuild optimization:
3334
| Hook | Purpose | Runs in prebuild? |
3435
| --- | --- | --- |
3536
| `onCreateCommand` | Node.js setup (nvm install, corepack enable) | Yes |
36-
| `postCreateCommand` | Welcome notice (all profiles); AI tooling setup (AI-enabled only) | Yes |
37+
| `postCreateCommand` | Welcome notice (all profiles); AI tooling setup (AI-enabled profiles) | Yes |
3738

3839
Heavy setup work runs in `onCreateCommand` so it is captured by Codespace prebuilds, making the user-connect experience faster.
40+
41+
## AI-enabled vs. AI-enabled (Insiders)
42+
43+
Insiders is a superset of the base AI-enabled profile. The only differences in the insiders `devcontainer.json` are:
44+
45+
- **`name`**`"AI-enabled (Insiders)"`
46+
- **`onCreateCommand`** — chains `install-flub.sh` after `on-create.sh` to build and link the `flub` CLI
47+
- **`codespaces.openFiles`** — points to the insiders copy of `GETTING_STARTED.md`
48+
49+
Everything else (Dockerfile, runArgs, extensions, features, setup scripts, host requirements) is identical.
50+
51+
### Shared vs. duplicated files
52+
53+
The devcontainer spec does not support config inheritance, so `devcontainer.json` is duplicated across the two profiles. Content files use a **fallback** pattern instead: the `flub ai` command searches `ai-agent-insiders/` first, then falls back to `ai-agent/`. This means files can be placed in one of two ways:
54+
55+
| Strategy | Where to put the file | When to use |
56+
| --- | --- | --- |
57+
| **Shared** | `ai-agent/` only | File is identical for both profiles. Insiders inherits it via fallback. |
58+
| **Overridden** | Both `ai-agent/` and `ai-agent-insiders/` | File differs between profiles (e.g. the insiders version mentions `flub ai`). |
59+
60+
Current layout:
61+
62+
| File | `ai-agent/` | `ai-agent-insiders/` | Notes |
63+
| --- | --- | --- | --- |
64+
| `devcontainer.json` | yes | yes | Must exist in both (no inheritance in spec). |
65+
| `launcher-prompt.md` | yes || Shared. Insiders finds it via fallback. |
66+
| `GETTING_STARTED.md` | yes | yes | Overridden. Insiders version adds the `flub ai` section. |
67+
| `first-run-notice.txt` | yes | yes | Overridden. Insiders version adds the `flub ai` line. |
68+
69+
### Maintenance rules
70+
71+
- **Shared config changes** (extensions, features, runArgs, host requirements, etc.) must be applied to both `devcontainer.json` files.
72+
- **Shared content** (like `launcher-prompt.md`) should live in `ai-agent/` only. Do not duplicate it into insiders — the fallback handles it.
73+
- **To promote an insiders feature to the base profile**, copy the relevant lines from the insiders files into the `ai-agent/` versions, then delete the insiders overrides so they fall back to the now-updated shared copy.
74+
- **To remove an insiders override**, just delete the file from `ai-agent-insiders/`. The `flub ai` command will find the `ai-agent/` fallback automatically.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Getting Started with AI-Enabled Codespace
2+
3+
This codespace is pre-configured for AI-agent-assisted development of the Fluid Framework. It includes [agency](https://aka.ms/agency), [repoverlay](https://github.com/tylerbutler/repoverlay), GitHub CLI, and SSH access.
4+
5+
> For full documentation, see the [AI-enabled Codespace wiki page](https://github.com/microsoft/FluidFramework/wiki/AI%E2%80%90enabled-Codespace).
6+
7+
## First-time Setup
8+
9+
Agency is installed automatically the first time you run `dev`, `claude`, or any agent alias - watch for a browser authentication popup.
10+
If automatic installation fails, you can install agency manually via `pnpm install:agency`.
11+
12+
> [!NOTE]
13+
> Agency installation is supported in **VS Code** (desktop or SSH).
14+
> It may not work in a browser-based Codespace because the OAuth redirect requires a local browser and authentication may not complete correctly.
15+
16+
> [!TIP]
17+
> After creating a new AI-enabled Codespace you may be prompted to authenticate several times.
18+
> It may seem excessive, but is expected - just keep clicking through each prompt until they stop.
19+
20+
## Quick Start
21+
22+
If dependencies are not installed yet or you need to reinstall them:
23+
24+
```bash
25+
pnpm install
26+
27+
# Build everything
28+
pnpm build
29+
30+
# Build only a specific package and its dependencies
31+
pnpm fluid-build .
32+
```
33+
34+
## Not sure which agent to use?
35+
36+
Run `flub ai` — an interactive assistant that asks what you want to do and launches the right agent for you.
37+
38+
## AI Agent Aliases
39+
40+
These aliases are available in all terminal sessions (after installing agency):
41+
42+
### Claude
43+
44+
| Alias | Command | Purpose |
45+
|---|---|---|
46+
| `dev` | `repoverlay switch --copy nori && agency claude ... -- --model opus` | Launch Claude optimized for feature work and debugging |
47+
| `claude` | `repoverlay remove --all && agency claude ... -- --model opus` | General purpose Claude Code agent |
48+
49+
### Copilot
50+
51+
| Alias | Command | Purpose |
52+
|---|---|---|
53+
| `copilot` | `agency copilot` | Standard GitHub Copilot |
54+
| `oce` | `repoverlay switch --copy ff-oce && agency copilot -- --agent ff-oce` | On-Call Engineer workflows |
55+
56+
### Custom MCP Servers
57+
58+
The built-in aliases include at least ADO, WorkIQ, and EngHub MCP servers.
59+
You can also launch an agent with your own combination of MCP servers using the `--mcp` flag.
60+
Stack as many as you need (and watch for browser authentication popups).
61+
62+
```bash
63+
# Claude with an additional Kusto MCP server (ADO, WorkIQ, and EngHub are always included)
64+
claude --mcp 'kusto --service-uri https://kusto.aria.microsoft.com'
65+
66+
# Copilot with an additional MCP server
67+
copilot --mcp 'workiq'
68+
```
69+
70+
> Run `agency mcp --help` to see all available MCP servers and their options.
71+
72+
### Utility
73+
74+
| Alias | Command | Purpose |
75+
|---|---|---|
76+
| `ai-reset` | `repoverlay remove --all` | Remove all repoverlay overlays and reset to clean state |
77+
78+
## More Information
79+
80+
- [AI-enabled Codespace wiki](https://github.com/microsoft/FluidFramework/wiki/AI%E2%80%90enabled-Codespace) — Full documentation for this codespace profile
81+
- [DEV.md](../../DEV.md) — Development setup, build commands, and workflow guide
82+
- [CONTRIBUTING.md](../../CONTRIBUTING.md) — Contribution guidelines
83+
- [FluidFramework.com](https://fluidframework.com) — Documentation and API reference
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// AI-enabled (Insiders) — everything in AI-enabled, plus the flub AI launcher command.
2+
{
3+
"name": "AI-enabled (Insiders)",
4+
"build": {
5+
"dockerfile": "../Dockerfile",
6+
"args": {
7+
"NODE_VERSION": "24",
8+
// "INSTALL_AGENCY": "true",
9+
"INSTALL_REPOVERLAY": "true"
10+
// TODO: Figure out the playwright strategy
11+
// "INSTALL_PLAYWRIGHT_CLI": "true"
12+
}
13+
},
14+
"runArgs": [
15+
"--init",
16+
"--security-opt=seccomp=unconfined",
17+
"--security-opt=apparmor=unconfined",
18+
"--cap-add=SYS_ADMIN"
19+
],
20+
"customizations": {
21+
"vscode": {
22+
"extensions": [
23+
"biomejs.biome",
24+
"dbaeumer.vscode-eslint",
25+
"esbenp.prettier-vscode",
26+
"MAI-EngineeringSystems.mai-ai-telemetry",
27+
"ms-azure-devops.azure-pipelines",
28+
"ms-azuretools.vscode-docker",
29+
"mutantdino.resourcemonitor",
30+
"vsls-contrib.codetour"
31+
],
32+
"settings": {
33+
"workbench.startupEditor": "none"
34+
}
35+
},
36+
"codespaces": {
37+
"openFiles": [".devcontainer/ai-agent-insiders/GETTING_STARTED.md"]
38+
}
39+
},
40+
"containerEnv": {
41+
"NODE_VERSION_OVERRIDE": "24",
42+
"COREPACK_ENABLE_DOWNLOAD_PROMPT": "0"
43+
},
44+
"onCreateCommand": "bash scripts/codespace-setup/on-create.sh && bash scripts/codespace-setup/install-flub.sh",
45+
"postCreateCommand": "bash scripts/codespace-setup/ai-setup.sh",
46+
"postStartCommand": {
47+
"bwrap-setup": "sudo mount --make-rshared /",
48+
"sandbox-tmpdir": "mkdir -p /tmp/claude"
49+
},
50+
"postAttachCommand": {},
51+
"remoteUser": "node",
52+
"features": {
53+
// Enables docker CLI inside the container
54+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
55+
"moby": false
56+
},
57+
// Install the github CLI
58+
"ghcr.io/devcontainers/features/github-cli:1": {},
59+
// Install git lfs
60+
"ghcr.io/devcontainers/features/git-lfs:1": {},
61+
// Enables SSH connections into the container using `gh codespace ssh`
62+
"ghcr.io/devcontainers/features/sshd:1": {
63+
"version": "latest"
64+
}
65+
},
66+
// Setting this so Codespaces default settings use it. It's not really *required*, but a clean build
67+
// can be lengthy enough that it's convenient.
68+
"hostRequirements": {
69+
"cpus": 32,
70+
"memory": "64gb"
71+
}
72+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
_________ _____ __ __ _____ ______ ________ ________
2+
(_ _____) (_ _) ) ) ( ( (_ _) (_ __ \ /_______/\ /_______/\
3+
) (___ | | ( ( ) ) | | ) ) \ \ \::: _ \ \ \__.::._\/
4+
( ___) | | ) ) ( ( | | ( ( ) ) \::(_) \ \ \::\ \
5+
) ( | | __ ( ( ) ) | | ) ) ) ) \:: __ \ \ _\::\ \__
6+
( ) __| |___) ) ) \__/ ( _| |__ / /__/ / \:.\ \ \ \/__\::\__/\
7+
\_/ \________/ \______/ /_____( (______/ \__\/\__\/\________\/
8+
9+
GET STARTED: Run one of the commands below:
10+
flub ai Not sure? An AI assistant picks the right agent for you
11+
dev Launch an agent for feature work/testing/debugging
12+
claude Launch an agent for general purpose work
13+
14+
Other agent aliases:
15+
copilot Launch GitHub Copilot via agency
16+
oce Launch Copilot for on-call engineer workflows
17+
18+
Custom MCP servers:
19+
See GETTING_STARTED.md for how to launch agents with your own MCP servers.
20+
21+
Other commands:
22+
pnpm install Install all dependencies
23+
pnpm build Build all packages
24+
pnpm test Run tests
25+
pnpm fluid-build . Build only the current package and its dependencies
26+
27+
More information on this codespace: https://github.com/microsoft/FluidFramework/wiki/AI%E2%80%90enabled-Codespace

.devcontainer/ai-agent/devcontainer.json

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,16 @@
3838
}
3939
},
4040
"containerEnv": {
41-
"NODE_VERSION_OVERRIDE": "24"
42-
},
43-
"onCreateCommand": {
44-
"node-setup": "bash scripts/codespace-setup/on-create.sh"
45-
},
46-
"postCreateCommand": {
47-
"ai-setup": "bash scripts/codespace-setup/ai-setup.sh"
41+
"NODE_VERSION_OVERRIDE": "24",
42+
"COREPACK_ENABLE_DOWNLOAD_PROMPT": "0"
4843
},
44+
"onCreateCommand": "bash scripts/codespace-setup/on-create.sh",
45+
"postCreateCommand": "bash scripts/codespace-setup/ai-setup.sh",
4946
"postStartCommand": {
5047
"bwrap-setup": "sudo mount --make-rshared /",
5148
"sandbox-tmpdir": "mkdir -p /tmp/claude"
5249
},
53-
"postAttachCommand": {
54-
"open-getting-started": "code .devcontainer/ai-agent/GETTING_STARTED.md"
55-
},
50+
"postAttachCommand": {},
5651
"remoteUser": "node",
5752
"features": {
5853
// Enables docker CLI inside the container
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
model: claude-haiku-4-5-20251001
3+
---
4+
5+
You are a launcher assistant for the Fluid Framework. Your job is to help the user pick the right AI agent alias and MCP server configuration for their task.
6+
7+
## Your Behavior
8+
1. Greet the user briefly and ask what they want to accomplish today.
9+
2. Ask clarifying questions if needed to understand their task, one question at a time.
10+
3. Once you know enough, call select_alias with your recommendation.
11+
4. NEVER recommend aliases that don't exist in the alias definitions below.
12+
5. Keep the conversation short — usually 1-2 questions is enough.
13+
14+
## Alias Definitions (source of truth)
15+
16+
The following shell script defines the available aliases. Each shell function IS an alias.
17+
Study the function bodies to understand what each alias does (which agent it launches,
18+
which overlays it applies, which MCP servers it includes by default).
19+
20+
```bash
21+
{{aliasFileContent}}
22+
```
23+
24+
## Getting Started Guide
25+
26+
The following guide is shown to users when they first start working.
27+
Use it to understand the aliases, MCP server options, and recommended workflows.
28+
29+
{{gettingStartedContent}}
30+
31+
## Guidelines
32+
- ONLY recommend aliases that exist as functions in the alias definitions above.
33+
- When calling select_alias, the alias value must exactly match a function name from the script.
34+
- Most developers doing feature work should use `dev`.
35+
- For OCE/incident work, always recommend `oce`.
36+
- For general questions or exploration without a specific workflow, recommend `claude`.
37+
- Only suggest `ai-reset` if the user explicitly mentions overlay problems.
38+
- Don't overload with MCP servers — only suggest extras if the task clearly needs them.
39+
- When in doubt between `dev` and `claude`, prefer `dev` for any coding task.
40+
41+
---
42+
43+
Begin now. Greet the user and ask what they'd like to do today.

build-tools/packages/build-cli/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ USAGE
3232
<!-- commands -->
3333
# Command Topics
3434

35+
* [`flub ai`](docs/ai.md) - AI-powered assistant for launching the right AI agent.
3536
* [`flub autocomplete`](docs/autocomplete.md) - Display autocomplete installation instructions.
3637
* [`flub build-perf`](docs/build-perf.md) - Build performance observability commands for collecting, processing, and analyzing build metrics.
3738
* [`flub bump`](docs/bump.md) - Bump the version of packages, release groups, and their dependencies.

build-tools/packages/build-cli/bin/dev.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
* Licensed under the MIT License.
55
*/
66

7-
import { execute } from "@oclif/core";
7+
import { execute, settings } from "@oclif/core";
8+
9+
if (process.env.FLUB_PERF === "1") {
10+
settings.performanceEnabled = true;
11+
}
812

913
await execute({ development: true, dir: import.meta.url });

build-tools/packages/build-cli/bin/run.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
* Licensed under the MIT License.
55
*/
66

7-
import { execute } from "@oclif/core";
7+
import { execute, settings } from "@oclif/core";
8+
9+
if (process.env.FLUB_PERF === "1") {
10+
settings.performanceEnabled = true;
11+
}
812

913
await execute({ dir: import.meta.url });
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
`flub ai`
2+
=========
3+
4+
AI-powered assistant for launching the right AI agent.
5+
6+
* [`flub ai`](#flub-ai)
7+
8+
## `flub ai`
9+
10+
AI-powered assistant that helps you launch the right AI agent.
11+
12+
```
13+
USAGE
14+
$ flub ai [-v | --quiet] [--aliasFile <value>] [--githubToken <value>] [--model <value>]
15+
16+
FLAGS
17+
--aliasFile=<value> [env: FLUB_AI_ALIAS_FILE] Path to the agent-aliases.sh file. Defaults to the AI-enabled
18+
Codespace locations.
19+
--githubToken=<value> [env: COPILOT_GITHUB_TOKEN] GitHub token for the launcher assistant. Defaults to
20+
COPILOT_GITHUB_TOKEN, GH_TOKEN, or GITHUB_TOKEN.
21+
--model=<value> The AI model to use for the launcher assistant. Defaults to the model specified in
22+
launcher-prompt.md frontmatter.
23+
24+
LOGGING FLAGS
25+
-v, --verbose Enable verbose logging.
26+
--quiet Disable all logging.
27+
28+
DESCRIPTION
29+
AI-powered assistant that helps you launch the right AI agent.
30+
31+
EXAMPLES
32+
Launch the AI assistant to help pick the right agent.
33+
34+
$ flub ai
35+
36+
Use a specific model for the launcher assistant.
37+
38+
$ flub ai --model claude-sonnet-4.5
39+
```
40+
41+
_See code: [src/commands/ai.ts](https://github.com/microsoft/FluidFramework/blob/main/build-tools/packages/build-cli/src/commands/ai.ts)_

0 commit comments

Comments
 (0)