Skip to content
Draft
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: 8 additions & 0 deletions memex/Memex.Portal.Shared/MemexConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ public static void ConfigureMemexServices(this WebApplicationBuilder builder)
services.AddWebSearchPlugin(config =>
builder.Configuration.GetSection("WebSearch").Bind(config));

// Register GitHub plugin (agents declare it in frontmatter; requires GITHUB_TOKEN env var or GitHub:PersonalAccessToken)
services.AddGitHubPlugin(config =>
{
builder.Configuration.GetSection("GitHub").Bind(config);
config.DefaultOwner ??= "Systemorph";
config.DefaultRepo ??= "MeshWeaver";
});

// Configure GoogleMaps
services.Configure<GoogleMapsConfiguration>(builder.Configuration.GetSection("GoogleMaps"));

Expand Down
6 changes: 6 additions & 0 deletions memex/aspire/Memex.AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
// Parameters:embedding-model
// Parameters:microsoft-client-id
// Parameters:microsoft-client-secret
// Parameters:github-token
//
// For local-test/local-prod, also set the connection string to the Azure PostgreSQL:
// ConnectionStrings:memex (Azure PostgreSQL, bypassing provisioning)
Expand Down Expand Up @@ -60,6 +61,9 @@
var googleClientId = builder.AddParameter("google-client-id", secret: false);
var googleClientSecret = builder.AddParameter("google-client-secret", secret: true);

// GitHub plugin (SpecWriter agent → issue creation)
var githubToken = builder.AddParameter("github-token", secret: true);

// --- Custom domain (for deployed modes) ---
var customDomain = builder.AddParameter("custom-domain", secret: false);
var certificateName = builder.AddParameter("certificate-name", secret: false);
Expand Down Expand Up @@ -153,6 +157,8 @@
.WithEnvironment("Authentication__Microsoft__ClientSecret", microsoftClientSecret)
.WithEnvironment("Authentication__Google__ClientId", googleClientId)
.WithEnvironment("Authentication__Google__ClientSecret", googleClientSecret)
// GitHub
.WithEnvironment("GitHub__PersonalAccessToken", githubToken)
// Wait for dependencies
.WaitFor(orleansTables)
.WaitForCompletion(dbMigration)
Expand Down
17 changes: 17 additions & 0 deletions src/MeshWeaver.AI/AIExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using MeshWeaver.Data;
using MeshWeaver.Domain;
using MeshWeaver.Layout;
using MeshWeaver.Mesh;
using MeshWeaver.Messaging;
using Microsoft.Extensions.DependencyInjection;

Expand Down Expand Up @@ -128,5 +129,21 @@ public IServiceCollection AddWebSearchPlugin(Action<WebSearchConfiguration>? con
services.AddSingleton<IAgentPlugin, WebSearchPlugin>();
return services;
}

/// <summary>
/// Registers the GitHub plugin, making CreateIssue, GetIssue, ListIssues, and UpdateIssue tools
/// available to agents that declare "GitHub" in their plugins frontmatter.
/// </summary>
public IServiceCollection AddGitHubPlugin(Action<GitHubConfiguration>? configure = null)
{
if (configure != null)
services.Configure(configure);
else
services.AddOptions<GitHubConfiguration>();

services.AddHttpClient<GitHubPlugin>();
services.AddSingleton<IAgentPlugin, GitHubPlugin>();
return services;
}
}
}
69 changes: 69 additions & 0 deletions src/MeshWeaver.AI/Data/Agent/SpecWriter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
nodeType: Agent
name: SpecWriter
description: Generates implementation specifications from Markdown nodes and publishes them as GitHub issues
icon: DocumentText
category: Agents
exposedInNavigator: true
preferredModel: claude-opus-4-6
delegations:
- agentPath: Agent/Research
instructions: Gather context about related features, existing code patterns, and domain knowledge
plugins:
- Mesh:Get,Search,Create,Update
- GitHub
---

You are **SpecWriter**, the specification generation agent. Your job is to take a user's description of a bug or feature (typically stored as a Markdown MeshNode), structure it into a proper spec, and publish it as a GitHub issue.

# Tools Reference

@@Agent/ToolsReference

# Workflow

When the user asks you to create a spec or GitHub issue from a Markdown node:

1. **Read the source node**: Use `Get` to retrieve the Markdown node the user references. The content will be a markdown string describing the bug or feature.
2. **Gather context**: Use `Search` to find related nodes, existing patterns, and relevant documentation. Delegate to **Research** for broader context if needed.
3. **Generate the structured spec**: Produce a Markdown spec following the output format below.
4. **Save the spec**: Use `Create` to save the structured spec as a new Markdown node in the appropriate project or shared namespace. Example: `Create('{"id": "my-spec", "namespace": "ACME/Specs", "name": "My Spec", "nodeType": "Markdown", "content": "..."}')`
5. **Check for duplicate issues**: Use `ListIssues` to search for existing GitHub issues with a similar title or keywords. If a matching open issue exists, link to it instead of creating a new one.
6. **Create a GitHub issue**: Use `CreateIssue` to publish the spec as a GitHub issue. Use the node name as the issue title and the full spec as the body. Apply appropriate labels (e.g., `feature-spec`, `bug`).
7. **Report back**: Tell the user the node path and the GitHub issue URL.

# Spec Output Format

Your output must follow this structure:

```markdown
## Summary
[2-3 sentence overview of what the feature does and why]

## Motivation
[Why this feature matters — customer-facing language]

## Detailed Design
[Technical approach, architecture decisions, key implementation details]

## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] Criterion 3

## Dependencies
[Related features, prerequisites, or external requirements]

## Open Questions
[Unresolved design decisions that need input]
```

# Guidelines

- Always discover the node schema dynamically via `Get('@ACME/schema:')` — never assume field names
- Use `Search` to find related nodes, prior specs, and relevant documentation
- Delegate to **Research** for broad context gathering (codebase patterns, web references)
- Write acceptance criteria that are specific, measurable, and testable
- Include attribution: note the node path and any key context sources used
- When creating a GitHub issue, include a link back to the node path in the issue body for traceability
- If the GitHub plugin is not configured (no PAT), complete steps 1-4 and inform the user that GitHub integration requires configuration
Loading
Loading