fullerdev 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +276 -0
  3. package/bin/setup.js +119 -0
  4. package/dist/agents/designer.d.ts +6 -0
  5. package/dist/agents/designer.d.ts.map +1 -0
  6. package/dist/agents/devops.d.ts +7 -0
  7. package/dist/agents/devops.d.ts.map +1 -0
  8. package/dist/agents/explorer.d.ts +7 -0
  9. package/dist/agents/explorer.d.ts.map +1 -0
  10. package/dist/agents/fixer.d.ts +6 -0
  11. package/dist/agents/fixer.d.ts.map +1 -0
  12. package/dist/agents/librarian.d.ts +6 -0
  13. package/dist/agents/librarian.d.ts.map +1 -0
  14. package/dist/agents/oracle.d.ts +6 -0
  15. package/dist/agents/oracle.d.ts.map +1 -0
  16. package/dist/agents/orchestrator.d.ts +13 -0
  17. package/dist/agents/orchestrator.d.ts.map +1 -0
  18. package/dist/config/defaults.d.ts +14 -0
  19. package/dist/config/defaults.d.ts.map +1 -0
  20. package/dist/config/loader.d.ts +54 -0
  21. package/dist/config/loader.d.ts.map +1 -0
  22. package/dist/config/schema.d.ts +603 -0
  23. package/dist/config/schema.d.ts.map +1 -0
  24. package/dist/hooks/context-injection.d.ts +25 -0
  25. package/dist/hooks/context-injection.d.ts.map +1 -0
  26. package/dist/hooks/devops-integration.d.ts +31 -0
  27. package/dist/hooks/devops-integration.d.ts.map +1 -0
  28. package/dist/hooks/index.d.ts +46 -0
  29. package/dist/hooks/index.d.ts.map +1 -0
  30. package/dist/hooks/session-lifecycle.d.ts +15 -0
  31. package/dist/hooks/session-lifecycle.d.ts.map +1 -0
  32. package/dist/hooks/todo-continuation.d.ts +17 -0
  33. package/dist/hooks/todo-continuation.d.ts.map +1 -0
  34. package/dist/index.d.ts +31 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +1261 -0
  37. package/dist/mcp/index.d.ts +31 -0
  38. package/dist/mcp/index.d.ts.map +1 -0
  39. package/dist/tools/azure/git.d.ts +26 -0
  40. package/dist/tools/azure/git.d.ts.map +1 -0
  41. package/dist/tools/azure/index.d.ts +6 -0
  42. package/dist/tools/azure/index.d.ts.map +1 -0
  43. package/dist/tools/azure/pipelines.d.ts +18 -0
  44. package/dist/tools/azure/pipelines.d.ts.map +1 -0
  45. package/dist/tools/azure/wiki.d.ts +18 -0
  46. package/dist/tools/azure/wiki.d.ts.map +1 -0
  47. package/dist/tools/azure/work-items.d.ts +26 -0
  48. package/dist/tools/azure/work-items.d.ts.map +1 -0
  49. package/dist/tools/core/index.d.ts +17 -0
  50. package/dist/tools/core/index.d.ts.map +1 -0
  51. package/dist/tools/index.d.ts +7 -0
  52. package/dist/tools/index.d.ts.map +1 -0
  53. package/fullerdev.schema.json +117 -0
  54. package/package.json +65 -0
  55. package/src/skills/agent-browser/SKILL.md +31 -0
  56. package/src/skills/azure-devops/SKILL.md +99 -0
  57. package/src/skills/frontend-ui-ux/SKILL.md +62 -0
  58. package/src/skills/gitmaster/SKILL.md +52 -0
  59. package/src/skills/simplify/SKILL.md +50 -0
package/dist/index.js ADDED
@@ -0,0 +1,1261 @@
1
+ // src/config/loader.ts
2
+ import { readFileSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { homedir } from "node:os";
5
+
6
+ // src/config/schema.ts
7
+ import { z } from "zod";
8
+ var AgentConfigSchema = z.object({
9
+ model: z.string().describe("Provider/model ID (e.g., 'opencode-go/deepseek-v4-pro')"),
10
+ variant: z.enum(["low", "medium", "high", "max"]).optional().describe("Thinking/reasoning effort variant"),
11
+ skills: z.array(z.string()).optional().describe("Skills assigned to this agent. Use '*' for all, '!name' to exclude."),
12
+ mcps: z.array(z.string()).optional().describe("MCP servers available to this agent. Use '*' for all, '!name' to exclude.")
13
+ });
14
+ var PresetSchema = z.object({
15
+ orchestrator: AgentConfigSchema,
16
+ oracle: AgentConfigSchema,
17
+ librarian: AgentConfigSchema,
18
+ explorer: AgentConfigSchema,
19
+ designer: AgentConfigSchema,
20
+ fixer: AgentConfigSchema,
21
+ devops: AgentConfigSchema
22
+ });
23
+ var AzureDevOpsConfigSchema = z.object({
24
+ orgUrl: z.string().url().describe("Azure DevOps organization URL (e.g., 'https://dev.azure.com/myorg')"),
25
+ project: z.string().optional().describe("Default project name"),
26
+ pat: z.string().optional().describe("Personal Access Token. Supports ${ENV_VAR} syntax. Falls back to AZURE_DEVOPS_EXT_PAT env var."),
27
+ defaultAreaPath: z.string().optional().describe("Default Area Path for work items"),
28
+ defaultIterationPath: z.string().optional().describe("Default Iteration Path for work items")
29
+ });
30
+ var PluginConfigSchema = z.object({
31
+ $schema: z.string().optional(),
32
+ preset: z.string().default("opencode-go"),
33
+ presets: z.record(z.string(), PresetSchema).default({}),
34
+ azureDevOps: AzureDevOpsConfigSchema.optional(),
35
+ disabledMcps: z.array(z.string()).optional().default([]),
36
+ disabledHooks: z.array(z.string()).optional().default([]),
37
+ disabledSkills: z.array(z.string()).optional().default([]),
38
+ disabledAgents: z.array(z.string()).optional().default([])
39
+ });
40
+
41
+ // src/config/defaults.ts
42
+ var OPENCODE_GO_PRESET = {
43
+ orchestrator: {
44
+ model: "opencode-go/deepseek-v4-pro",
45
+ variant: "high",
46
+ skills: ["*"],
47
+ mcps: ["*", "!context7"]
48
+ },
49
+ oracle: {
50
+ model: "opencode-go/deepseek-v4-pro",
51
+ variant: "max",
52
+ skills: ["simplify"],
53
+ mcps: []
54
+ },
55
+ librarian: {
56
+ model: "opencode-go/minimax-m2.7",
57
+ skills: [],
58
+ mcps: ["websearch", "deepwiki", "context7", "grep_app"]
59
+ },
60
+ explorer: {
61
+ model: "opencode-go/minimax-m2.7",
62
+ skills: [],
63
+ mcps: []
64
+ },
65
+ designer: {
66
+ model: "opencode-go/kimi-k2.6",
67
+ variant: "medium",
68
+ skills: ["agent-browser", "frontend-ui-ux"],
69
+ mcps: []
70
+ },
71
+ fixer: {
72
+ model: "opencode-go/deepseek-v4-flash",
73
+ variant: "high",
74
+ skills: [],
75
+ mcps: []
76
+ },
77
+ devops: {
78
+ model: "opencode-go/deepseek-v4-flash",
79
+ variant: "medium",
80
+ skills: ["azure-devops", "gitmaster"],
81
+ mcps: ["grep_app"]
82
+ }
83
+ };
84
+ var OPENAI_PRESET = {
85
+ orchestrator: {
86
+ model: "openai/gpt-5.5",
87
+ variant: "high",
88
+ skills: ["*"],
89
+ mcps: ["*", "!context7"]
90
+ },
91
+ oracle: {
92
+ model: "openai/gpt-5.5",
93
+ variant: "high",
94
+ skills: ["simplify"],
95
+ mcps: []
96
+ },
97
+ librarian: {
98
+ model: "openai/gpt-5.4-mini",
99
+ variant: "low",
100
+ skills: [],
101
+ mcps: ["websearch", "deepwiki", "context7", "grep_app"]
102
+ },
103
+ explorer: {
104
+ model: "openai/gpt-5.4-mini",
105
+ variant: "low",
106
+ skills: [],
107
+ mcps: []
108
+ },
109
+ designer: {
110
+ model: "openai/gpt-5.4-mini",
111
+ variant: "medium",
112
+ skills: ["agent-browser", "frontend-ui-ux"],
113
+ mcps: []
114
+ },
115
+ fixer: {
116
+ model: "openai/gpt-5.4-mini",
117
+ variant: "low",
118
+ skills: [],
119
+ mcps: []
120
+ },
121
+ devops: {
122
+ model: "openai/gpt-5.4-mini",
123
+ variant: "medium",
124
+ skills: ["azure-devops", "gitmaster"],
125
+ mcps: ["grep_app"]
126
+ }
127
+ };
128
+ function buildDefaultConfig() {
129
+ return {
130
+ preset: "opencode-go",
131
+ presets: {
132
+ "opencode-go": OPENCODE_GO_PRESET,
133
+ openai: OPENAI_PRESET
134
+ },
135
+ azureDevOps: {
136
+ orgUrl: "https://dev.azure.com/your-org"
137
+ },
138
+ disabledMcps: [],
139
+ disabledHooks: [],
140
+ disabledSkills: [],
141
+ disabledAgents: []
142
+ };
143
+ }
144
+
145
+ // src/config/loader.ts
146
+ var CONFIG_FILES = [
147
+ ".opencode/fullerdev.jsonc",
148
+ ".opencode/fullerdev.json",
149
+ "fullerdev.jsonc",
150
+ "fullerdev.json"
151
+ ];
152
+ function resolveEnvVars(obj) {
153
+ if (typeof obj === "string") {
154
+ return obj.replace(/\$\{(\w+)\}/g, (_, name) => process.env[name] ?? "");
155
+ }
156
+ if (Array.isArray(obj)) {
157
+ return obj.map(resolveEnvVars);
158
+ }
159
+ if (obj && typeof obj === "object") {
160
+ const result = {};
161
+ for (const [key, value] of Object.entries(obj)) {
162
+ result[key] = resolveEnvVars(value);
163
+ }
164
+ return result;
165
+ }
166
+ return obj;
167
+ }
168
+ function parseJSONC(raw) {
169
+ const noLineComments = raw.replace(/\/\/.*$/gm, "");
170
+ const noBlockComments = noLineComments.replace(/\/\*[\s\S]*?\*\//g, "");
171
+ const clean = noBlockComments.replace(/,(\s*[}\]])/g, "$1");
172
+ return JSON.parse(clean);
173
+ }
174
+ function loadConfig(directory) {
175
+ const searchPaths = [
176
+ ...CONFIG_FILES.map((f) => join(directory, f)),
177
+ ...CONFIG_FILES.map((f) => join(homedir(), ".config", "opencode", f))
178
+ ];
179
+ for (const path of searchPaths) {
180
+ if (existsSync(path)) {
181
+ try {
182
+ const raw = readFileSync(path, "utf-8");
183
+ const parsed = parseJSONC(raw);
184
+ const resolved = resolveEnvVars(parsed);
185
+ return PluginConfigSchema.parse(resolved);
186
+ } catch (err) {
187
+ console.warn(`[fullerdev] Failed to parse config at ${path}:`, err);
188
+ }
189
+ }
190
+ }
191
+ console.log("[fullerdev] No config found, using built-in defaults.");
192
+ return buildDefaultConfig();
193
+ }
194
+ function getActivePreset(config) {
195
+ const preset = config.presets[config.preset];
196
+ if (!preset) {
197
+ console.warn(`[fullerdev] Preset '${config.preset}' not found. Falling back to 'opencode-go'.`);
198
+ return config.presets["opencode-go"] ?? Object.values(config.presets)[0];
199
+ }
200
+ return preset;
201
+ }
202
+
203
+ // src/tools/azure/work-items.ts
204
+ import { tool } from "@opencode-ai/plugin";
205
+ var WORKITEM_QUERY_TOOL = tool({
206
+ description: "Query Azure DevOps Work Items using WIQL. Returns matching work item IDs and fields. Use this to find work items by title, state, assigned to, area path, iteration path, or custom fields.",
207
+ args: {
208
+ query: tool.schema.string().describe(`WIQL query string. Example: "SELECT [System.Id], [System.Title], [System.State] FROM WorkItems WHERE [System.TeamProject] = 'MyProject' AND [System.State] <> 'Closed' ORDER BY [System.ChangedDate] DESC"`),
209
+ top: tool.schema.number().optional().describe("Maximum number of results to return (default: 50, max: 200)")
210
+ },
211
+ async execute(args, ctx) {
212
+ return `[azdev_workitem_query] Querying: ${args.query.slice(0, 100)}...`;
213
+ }
214
+ });
215
+ var WORKITEM_GET_TOOL = tool({
216
+ description: "Get full details of a single Azure DevOps Work Item by its ID. Returns all system and custom fields, including description, acceptance criteria, and relations.",
217
+ args: {
218
+ id: tool.schema.number().describe("The Work Item ID (e.g., 12345)"),
219
+ expand: tool.schema.enum(["all", "relations", "fields", "links", "none"]).optional().describe("Fields to expand (default: all)")
220
+ },
221
+ async execute(args, ctx) {
222
+ return `[azdev_workitem_get] Getting work item #${args.id}...`;
223
+ }
224
+ });
225
+ var WORKITEM_CREATE_TOOL = tool({
226
+ description: "Create a new Work Item in Azure Boards. Supports User Stories, Tasks, Bugs, Features, Epics, and custom work item types. Automatically uses the configured default Area Path and Iteration Path.",
227
+ args: {
228
+ type: tool.schema.string().describe("Work item type: 'User Story', 'Task', 'Bug', 'Feature', 'Epic', or custom type name"),
229
+ title: tool.schema.string().describe("Work item title"),
230
+ description: tool.schema.string().optional().describe("Work item description (supports markdown)"),
231
+ assignedTo: tool.schema.string().optional().describe("Email or display name of the person to assign to"),
232
+ areaPath: tool.schema.string().optional().describe("Area Path (overrides default from config)"),
233
+ iterationPath: tool.schema.string().optional().describe("Iteration Path (overrides default from config)"),
234
+ tags: tool.schema.array(tool.schema.string()).optional().describe("Tags to apply"),
235
+ parentId: tool.schema.number().optional().describe("Parent Work Item ID to link as child of")
236
+ },
237
+ async execute(args, ctx) {
238
+ return `[azdev_workitem_create] Creating ${args.type}: "${args.title}"...`;
239
+ }
240
+ });
241
+ var WORKITEM_UPDATE_TOOL = tool({
242
+ description: "Update fields of an existing Azure DevOps Work Item. Use this to change state, reassign, update description, add acceptance criteria, or modify any field.",
243
+ args: {
244
+ id: tool.schema.number().describe("The Work Item ID to update"),
245
+ updates: tool.schema.array(tool.schema.object({
246
+ op: tool.schema.enum(["add", "remove", "replace", "move", "copy", "test"]).describe("Patch operation"),
247
+ path: tool.schema.string().describe("JSON pointer path to the field (e.g., '/fields/System.State')"),
248
+ value: tool.schema.any().optional().describe("New value for the field")
249
+ })).describe("Array of JSON Patch operations to apply"),
250
+ comment: tool.schema.string().optional().describe("Optional comment to add to the discussion")
251
+ },
252
+ async execute(args, ctx) {
253
+ return `[azdev_workitem_update] Updating work item #${args.id}...`;
254
+ }
255
+ });
256
+ var WORKITEM_LINK_TOOL = tool({
257
+ description: "Create a link relationship between two Work Items (parent/child, related, predecessor/successor, etc.)",
258
+ args: {
259
+ sourceId: tool.schema.number().describe("Source Work Item ID"),
260
+ targetId: tool.schema.number().describe("Target Work Item ID"),
261
+ relationType: tool.schema.enum([
262
+ "Child",
263
+ "Parent",
264
+ "Related",
265
+ "Predecessor",
266
+ "Successor",
267
+ "Duplicate",
268
+ "Duplicate Of"
269
+ ]).describe("Type of relationship to create")
270
+ },
271
+ async execute(args, ctx) {
272
+ return `[azdev_workitem_link] Linking #${args.sourceId} -> #${args.targetId} (${args.relationType})...`;
273
+ }
274
+ });
275
+ function createWorkItemTools() {
276
+ return {
277
+ azdev_workitem_query: WORKITEM_QUERY_TOOL,
278
+ azdev_workitem_get: WORKITEM_GET_TOOL,
279
+ azdev_workitem_create: WORKITEM_CREATE_TOOL,
280
+ azdev_workitem_update: WORKITEM_UPDATE_TOOL,
281
+ azdev_workitem_link: WORKITEM_LINK_TOOL
282
+ };
283
+ }
284
+
285
+ // src/tools/azure/git.ts
286
+ import { tool as tool2 } from "@opencode-ai/plugin";
287
+ var GIT_REPOS_TOOL = tool2({
288
+ description: "List all Git repositories in the configured Azure DevOps project. Returns repo name, ID, default branch, size, and URL.",
289
+ args: {},
290
+ async execute(args, ctx) {
291
+ return "[azdev_git_repos] Listing repositories...";
292
+ }
293
+ });
294
+ var GIT_REPO_TOOL = tool2({
295
+ description: "Get detailed information about a specific Azure DevOps Git repository including default branch, size, web URL, and project reference.",
296
+ args: {
297
+ repositoryId: tool2.schema.string().describe("Repository ID or name")
298
+ },
299
+ async execute(args, ctx) {
300
+ return `[azdev_git_repo] Getting details for '${args.repositoryId}'...`;
301
+ }
302
+ });
303
+ var GIT_BRANCHES_TOOL = tool2({
304
+ description: "List branches in an Azure DevOps Git repository. Supports filtering by branch name pattern.",
305
+ args: {
306
+ repositoryId: tool2.schema.string().describe("Repository ID or name"),
307
+ filter: tool2.schema.string().optional().describe("Filter branches by name (e.g., 'feature/*')"),
308
+ includeLinks: tool2.schema.boolean().optional().describe("Include web URLs for branches")
309
+ },
310
+ async execute(args, ctx) {
311
+ return `[azdev_git_branches] Listing branches in '${args.repositoryId}'...`;
312
+ }
313
+ });
314
+ var GIT_PRS_TOOL = tool2({
315
+ description: "Search and list Pull Requests in an Azure DevOps Git repository. Filter by status, creator, reviewer, or target branch.",
316
+ args: {
317
+ repositoryId: tool2.schema.string().describe("Repository ID or name"),
318
+ status: tool2.schema.enum(["active", "abandoned", "completed", "all"]).optional().describe("PR status filter (default: active)"),
319
+ creatorId: tool2.schema.string().optional().describe("Filter by creator (email or display name)"),
320
+ reviewerId: tool2.schema.string().optional().describe("Filter by reviewer (email or display name)"),
321
+ sourceRefName: tool2.schema.string().optional().describe("Filter by source branch (e.g., 'refs/heads/feature/foo')"),
322
+ targetRefName: tool2.schema.string().optional().describe("Filter by target branch (e.g., 'refs/heads/main')"),
323
+ top: tool2.schema.number().optional().describe("Maximum number of PRs to return (default: 20)")
324
+ },
325
+ async execute(args, ctx) {
326
+ return `[azdev_git_prs] Searching PRs in '${args.repositoryId}'...`;
327
+ }
328
+ });
329
+ var GIT_PR_CREATE_TOOL = tool2({
330
+ description: "Create a new Pull Request in Azure DevOps. Automatically adds AB# links for work item tracking.",
331
+ args: {
332
+ repositoryId: tool2.schema.string().describe("Repository ID or name"),
333
+ sourceRefName: tool2.schema.string().describe("Source branch (e.g., 'refs/heads/feature/my-feature')"),
334
+ targetRefName: tool2.schema.string().describe("Target branch (e.g., 'refs/heads/main')"),
335
+ title: tool2.schema.string().describe("Pull Request title"),
336
+ description: tool2.schema.string().optional().describe("Pull Request description (supports markdown)"),
337
+ workItemIds: tool2.schema.array(tool2.schema.number()).optional().describe("Work Item IDs to link (AB# references will be added automatically)"),
338
+ reviewers: tool2.schema.array(tool2.schema.string()).optional().describe("Reviewer email addresses or display names"),
339
+ isDraft: tool2.schema.boolean().optional().describe("Create as draft PR (default: false)")
340
+ },
341
+ async execute(args, ctx) {
342
+ return `[azdev_git_pr_create] Creating PR: "${args.title}"...`;
343
+ }
344
+ });
345
+ function createGitTools() {
346
+ return {
347
+ azdev_git_repos: GIT_REPOS_TOOL,
348
+ azdev_git_repo: GIT_REPO_TOOL,
349
+ azdev_git_branches: GIT_BRANCHES_TOOL,
350
+ azdev_git_prs: GIT_PRS_TOOL,
351
+ azdev_git_pr_create: GIT_PR_CREATE_TOOL
352
+ };
353
+ }
354
+
355
+ // src/tools/azure/wiki.ts
356
+ import { tool as tool3 } from "@opencode-ai/plugin";
357
+ var WIKI_SEARCH_TOOL = tool3({
358
+ description: "Search Azure DevOps Wiki pages for content matching the query. Returns page titles, paths, and content snippets.",
359
+ args: {
360
+ query: tool3.schema.string().describe("Search query text to find in Wiki pages"),
361
+ scope: tool3.schema.enum(["project", "code"]).optional().describe("Search scope: project wiki or code wiki (default: project)")
362
+ },
363
+ async execute(args, ctx) {
364
+ return `[azdev_wiki_search] Searching for "${args.query}"...`;
365
+ }
366
+ });
367
+ var WIKI_PAGE_TOOL = tool3({
368
+ description: "Get the full content of an Azure DevOps Wiki page by its path. Returns rendered HTML or raw markdown.",
369
+ args: {
370
+ path: tool3.schema.string().describe("Wiki page path (e.g., '/Project/Architecture/Overview')"),
371
+ format: tool3.schema.enum(["markdown", "html"]).optional().describe("Content format (default: markdown)"),
372
+ includeSubPages: tool3.schema.boolean().optional().describe("Include child pages in the response")
373
+ },
374
+ async execute(args, ctx) {
375
+ return `[azdev_wiki_page] Getting page '${args.path}'...`;
376
+ }
377
+ });
378
+ var WIKI_CREATE_TOOL = tool3({
379
+ description: "Create a new Wiki page or update an existing one in Azure DevOps Wiki. Supports markdown content and hierarchical paths.",
380
+ args: {
381
+ path: tool3.schema.string().describe("Wiki page path (e.g., '/Project/Architecture/ADR-001')"),
382
+ content: tool3.schema.string().describe("Page content in markdown format"),
383
+ comment: tool3.schema.string().optional().describe("Version comment for the change")
384
+ },
385
+ async execute(args, ctx) {
386
+ return `[azdev_wiki_create] Creating page '${args.path}'...`;
387
+ }
388
+ });
389
+ function createWikiTools() {
390
+ return {
391
+ azdev_wiki_search: WIKI_SEARCH_TOOL,
392
+ azdev_wiki_page: WIKI_PAGE_TOOL,
393
+ azdev_wiki_create: WIKI_CREATE_TOOL
394
+ };
395
+ }
396
+
397
+ // src/tools/azure/pipelines.ts
398
+ import { tool as tool4 } from "@opencode-ai/plugin";
399
+ var PIPELINES_LIST_TOOL = tool4({
400
+ description: "List all pipelines in the configured Azure DevOps project. Returns pipeline ID, name, folder, and URL.",
401
+ args: {
402
+ folder: tool4.schema.string().optional().describe("Filter by pipeline folder path"),
403
+ top: tool4.schema.number().optional().describe("Maximum results (default: 100)")
404
+ },
405
+ async execute(args, ctx) {
406
+ return "[azdev_pipelines_list] Listing pipelines...";
407
+ }
408
+ });
409
+ var PIPELINES_RUNS_TOOL = tool4({
410
+ description: "Get recent runs of a specific Azure DevOps pipeline. Returns run ID, status, result, start time, and URL.",
411
+ args: {
412
+ pipelineId: tool4.schema.number().describe("Pipeline definition ID"),
413
+ statusFilter: tool4.schema.enum(["all", "running", "completed", "none"]).optional().describe("Filter by run status (default: all)"),
414
+ resultFilter: tool4.schema.enum(["succeeded", "partiallySucceeded", "failed", "canceled", "all"]).optional().describe("Filter by run result (default: all)"),
415
+ top: tool4.schema.number().optional().describe("Maximum runs to return (default: 10)"),
416
+ branchName: tool4.schema.string().optional().describe("Filter by source branch")
417
+ },
418
+ async execute(args, ctx) {
419
+ return `[azdev_pipelines_runs] Getting runs for pipeline #${args.pipelineId}...`;
420
+ }
421
+ });
422
+ var PIPELINES_TRIGGER_TOOL = tool4({
423
+ description: "Trigger a new run of an Azure DevOps pipeline. Supports specifying branch, variables, and YAML override.",
424
+ args: {
425
+ pipelineId: tool4.schema.number().describe("Pipeline definition ID to trigger"),
426
+ branch: tool4.schema.string().optional().describe("Branch to build (default: default branch)"),
427
+ variables: tool4.schema.record(tool4.schema.string(), tool4.schema.string()).optional().describe("Pipeline variables as key-value pairs"),
428
+ reason: tool4.schema.enum(["manual", "individualCI", "batchedCI", "schedule", "pullRequest"]).optional().describe("Reason for the build (default: manual)")
429
+ },
430
+ async execute(args, ctx) {
431
+ return `[azdev_pipelines_trigger] Triggering pipeline #${args.pipelineId}...`;
432
+ }
433
+ });
434
+ function createPipelineTools() {
435
+ return {
436
+ azdev_pipelines_list: PIPELINES_LIST_TOOL,
437
+ azdev_pipelines_runs: PIPELINES_RUNS_TOOL,
438
+ azdev_pipelines_trigger: PIPELINES_TRIGGER_TOOL
439
+ };
440
+ }
441
+
442
+ // src/tools/azure/index.ts
443
+ function createDevOpsTools() {
444
+ return {
445
+ ...createWorkItemTools(),
446
+ ...createGitTools(),
447
+ ...createWikiTools(),
448
+ ...createPipelineTools()
449
+ };
450
+ }
451
+
452
+ // src/tools/core/index.ts
453
+ import { tool as tool5 } from "@opencode-ai/plugin";
454
+ var TASK_TOOL = tool5({
455
+ description: "Spawn a subtask to a specialized subagent",
456
+ args: {
457
+ agent: tool5.schema.string().describe("Name of the subagent to delegate to (explorer, librarian, oracle, designer, fixer, devops)"),
458
+ task: tool5.schema.string().describe("Detailed task description for the subagent"),
459
+ context: tool5.schema.object({
460
+ files: tool5.schema.array(tool5.schema.string()).optional().describe("Files relevant to this task"),
461
+ workItemId: tool5.schema.number().optional().describe("Related Azure DevOps Work Item ID")
462
+ }).optional()
463
+ },
464
+ async execute(args, ctx) {
465
+ return `[task] Delegating to @${args.agent}: ${args.task.slice(0, 200)}...`;
466
+ }
467
+ });
468
+ var WEBFETCH_TOOL = tool5({
469
+ description: "Fetch a URL and return its content in a clean, readable format",
470
+ args: {
471
+ url: tool5.schema.string().url().describe("The URL to fetch"),
472
+ format: tool5.schema.enum(["text", "markdown", "html"]).optional().describe("Output format (default: markdown)"),
473
+ extractMain: tool5.schema.boolean().optional().describe("Extract only the main content (default: true)")
474
+ },
475
+ async execute(args, ctx) {
476
+ return `[webfetch] Fetching ${args.url}...`;
477
+ }
478
+ });
479
+ function createCoreTools() {
480
+ return {
481
+ task: TASK_TOOL,
482
+ webfetch: WEBFETCH_TOOL
483
+ };
484
+ }
485
+
486
+ // src/hooks/session-lifecycle.ts
487
+ function createSessionLifecycleHooks(_config) {
488
+ return {
489
+ event: async ({ event }) => {
490
+ switch (event.type) {
491
+ case "session.created":
492
+ break;
493
+ case "session.idle":
494
+ break;
495
+ case "session.error":
496
+ break;
497
+ case "session.deleted":
498
+ break;
499
+ default:
500
+ break;
501
+ }
502
+ }
503
+ };
504
+ }
505
+
506
+ // src/hooks/todo-continuation.ts
507
+ function createTodoContinuationHooks(config) {
508
+ const cooldownMap = new Map;
509
+ const COOLDOWN_MS = 5000;
510
+ const MAX_CONTINUATIONS = 10;
511
+ return {
512
+ event: async ({ event }) => {
513
+ if (event.type !== "session.idle")
514
+ return;
515
+ const sessionId = event.properties?.session_id ?? "";
516
+ if (!sessionId)
517
+ return;
518
+ if (config.disabledHooks?.includes("todo-continuation"))
519
+ return;
520
+ const lastContinue = cooldownMap.get(sessionId) ?? 0;
521
+ if (Date.now() - lastContinue < COOLDOWN_MS)
522
+ return;
523
+ cooldownMap.set(sessionId, Date.now());
524
+ }
525
+ };
526
+ }
527
+
528
+ // src/hooks/context-injection.ts
529
+ function createContextInjectionHooks(_config) {
530
+ return {
531
+ "tool.execute.before": async (input, output) => {
532
+ if (input.tool === "read" || input.tool === "read_file") {}
533
+ },
534
+ "tool.execute.after": async (_input, _output) => {}
535
+ };
536
+ }
537
+
538
+ // src/hooks/devops-integration.ts
539
+ function createDevOpsIntegrationHooks(_config) {
540
+ return {
541
+ "chat.params": async (input, output) => {
542
+ const message = input.message ?? {};
543
+ const parts = message.parts ?? [];
544
+ const text = parts.filter((p) => p.type === "text").map((p) => String(p.text ?? "")).join(" ");
545
+ if (!text)
546
+ return;
547
+ const wiRefs = text.match(/(?:AB)?#(\d{3,})/g);
548
+ if (wiRefs && wiRefs.length > 0) {
549
+ output.options = output.options ?? {};
550
+ output.options.azdev_workitems = wiRefs;
551
+ }
552
+ },
553
+ "tool.execute.after": async (input, _output) => {
554
+ if (input.tool === "bash") {
555
+ const command = String(input.args?.command ?? "");
556
+ if (command.includes("git commit")) {}
557
+ if (command.includes("git push") || command.includes("pr create")) {}
558
+ }
559
+ },
560
+ event: async ({ event }) => {
561
+ switch (event.type) {
562
+ case "session.created":
563
+ break;
564
+ case "session.idle":
565
+ break;
566
+ default:
567
+ break;
568
+ }
569
+ }
570
+ };
571
+ }
572
+
573
+ // src/hooks/index.ts
574
+ function createAllHooks(config) {
575
+ const session = createSessionLifecycleHooks(config);
576
+ const todo = createTodoContinuationHooks(config);
577
+ const context = createContextInjectionHooks(config);
578
+ const devops = createDevOpsIntegrationHooks(config);
579
+ return {
580
+ event: async (input) => {
581
+ await session.event(input);
582
+ await todo.event(input);
583
+ await devops.event(input);
584
+ },
585
+ "chat.params": async (input, output) => {
586
+ await devops["chat.params"](input, output);
587
+ },
588
+ "tool.execute.before": async (input, output) => {
589
+ await context["tool.execute.before"](input, output);
590
+ },
591
+ "tool.execute.after": async (input, output) => {
592
+ await context["tool.execute.after"](input, output);
593
+ await devops["tool.execute.after"](input, output);
594
+ }
595
+ };
596
+ }
597
+
598
+ // src/mcp/index.ts
599
+ function getBuiltinMcps(config) {
600
+ const mcps = [];
601
+ if (!config.disabledMcps?.includes("deepwiki")) {
602
+ mcps.push({
603
+ id: "deepwiki",
604
+ type: "http",
605
+ description: "Fetches up-to-date official library documentation via DeepWiki. Use for API references, framework docs, and version-specific behavior.",
606
+ url: "https://mcp.deepwiki.com/mcp"
607
+ });
608
+ }
609
+ if (!config.disabledMcps?.includes("grep_app")) {
610
+ mcps.push({
611
+ id: "grep_app",
612
+ type: "http",
613
+ description: "Ultra-fast code search across millions of public GitHub repositories. Find real-world usage examples, patterns, and implementations.",
614
+ url: "https://mcp.grep.app"
615
+ });
616
+ }
617
+ if (!config.disabledMcps?.includes("context7")) {
618
+ mcps.push({
619
+ id: "context7",
620
+ type: "http",
621
+ description: "Context-aware documentation retrieval and optimization. Provides accurate, version-specific API information and context compression.",
622
+ url: "https://mcp.context7.com/mcp"
623
+ });
624
+ }
625
+ if (!config.disabledMcps?.includes("websearch")) {
626
+ mcps.push({
627
+ id: "websearch",
628
+ type: "http",
629
+ description: "Real-time web search for current information, documentation, and examples.",
630
+ url: process.env.EXA_MCP_URL ?? "https://mcp.exa.ai",
631
+ env: {
632
+ EXA_API_KEY: process.env.EXA_API_KEY ?? ""
633
+ }
634
+ });
635
+ }
636
+ return mcps;
637
+ }
638
+ function resolveAgentMcps(agentConfig, allMcpIds, defaultList = []) {
639
+ const assigned = agentConfig.mcps ?? defaultList;
640
+ let resolved;
641
+ if (assigned.includes("*")) {
642
+ resolved = [...allMcpIds];
643
+ } else {
644
+ resolved = [];
645
+ }
646
+ for (const item of assigned) {
647
+ if (item === "*")
648
+ continue;
649
+ if (item.startsWith("!")) {
650
+ const excluded = item.slice(1);
651
+ resolved = resolved.filter((id) => id !== excluded);
652
+ } else {
653
+ if (!resolved.includes(item)) {
654
+ resolved.push(item);
655
+ }
656
+ }
657
+ }
658
+ return resolved;
659
+ }
660
+
661
+ // src/agents/orchestrator.ts
662
+ var ORCHESTRATOR_PROMPT = `
663
+ <Role>
664
+ You are an AI coding orchestrator that optimizes for quality, speed, cost, and reliability by delegating to specialists when it provides net efficiency gains.
665
+
666
+ You operate within an **Azure DevOps-native workflow**. Work is tracked in Azure Boards (Work Items), code lives in Azure Repos (Git), and documentation in Azure Wikis. You should reference Work Item IDs (#12345) naturally and link your work back to the board.
667
+ </Role>
668
+
669
+ <Agents>
670
+
671
+ @explorer
672
+ - Role: Parallel search specialist for discovering unknowns across the codebase
673
+ - Permissions: Read files
674
+ - Stats: 2x faster codebase search than orchestrator, 1/2 cost of orchestrator
675
+ - Capabilities: Glob, grep, AST queries to locate files, symbols, patterns
676
+ - **Delegate when:** Need to discover what exists before planning • Parallel searches speed discovery • Need summarized map vs full contents • Broad/uncertain scope
677
+ - **Don't delegate when:** Know the path and need actual content • Need full file anyway • Single specific lookup • About to edit the file
678
+
679
+ @librarian
680
+ - Role: Authoritative source for current library docs and API references
681
+ - Permissions: External docs/search MCPs; no file edits
682
+ - Stats: 10x better finding up-to-date library docs than orchestrator, 1/2 cost of orchestrator
683
+ - Capabilities: Fetches latest official docs, examples, API signatures, version-specific behavior via DeepWiki and grep_app MCPs
684
+ - **Delegate when:** Libraries with frequent API changes (React, Next.js, AI SDKs) • Complex APIs needing official examples (ORMs, auth) • Version-specific behavior matters • Unfamiliar library • Edge cases or advanced features • Nuanced best practices • Azure DevOps REST API reference lookups
685
+ - **Don't delegate when:** Standard usage you're confident • Simple stable APIs • General programming knowledge • Info already in conversation • Built-in language features
686
+
687
+ @oracle
688
+ - Role: Strategic advisor for high-stakes decisions and persistent problems, code reviewer
689
+ - Permissions: Read files
690
+ - Stats: 5x better decision maker, problem solver, investigator than orchestrator
691
+ - Capabilities: Deep architectural reasoning, system-level trade-offs, complex debugging, code review, simplification, maintainability review
692
+ - **Delegate when:** Major architectural decisions • Problems persisting after 2+ fix attempts • High-risk multi-system refactors • Costly trade-offs • Complex debugging • Security/scalability/data integrity decisions • Code needs simplification or YAGNI scrutiny
693
+ - **Don't delegate when:** Routine decisions • First bug fix attempt • Straightforward trade-offs
694
+
695
+ @designer
696
+ - Role: UI/UX specialist for intentional, polished experiences
697
+ - Permissions: Read/write files
698
+ - Stats: 10x better UI/UX than orchestrator
699
+ - Capabilities: Visual relevant edits, interactions, responsive layouts, design systems with aesthetic intent
700
+ - **Delegate when:** User-facing interfaces needing polish • Responsive layouts • UX-critical components (forms, nav, dashboards) • Visual consistency systems • Animations/micro-interactions • Landing/marketing pages
701
+ - **Don't delegate when:** Backend/logic with no visual • Quick prototypes where design doesn't matter yet
702
+
703
+ @fixer
704
+ - Role: Fast execution specialist for well-defined tasks
705
+ - Permissions: Read/write files
706
+ - Stats: 2x faster code edits, 1/2 cost of orchestrator
707
+ - Capabilities: Bounded implementation, test writing/updating, straightforward code changes
708
+ - **Delegate when:** Well-scoped implementation tasks • Writing or updating tests • Routine code changes with clear specs • Multi-file changes that can be parallelized
709
+ - **Don't delegate when:** Needs discovery/research/decisions • Single small change (<20 lines, one file) • Unclear requirements
710
+
711
+ @devops
712
+ - Role: Azure DevOps specialist for Work Items, Git repos, Wiki, and Pipelines
713
+ - Permissions: Read/write files, Azure DevOps API access
714
+ - Stats: Expert-level Azure DevOps integration
715
+ - Capabilities: Work Item CRUD, query building, linking/branching, Git repo operations (PRs, branches, policies), Wiki search and page management, Pipeline status and triggering
716
+ - **Delegate when:** Creating/updating Work Items • Querying Azure Boards • Managing Git repos/branches/PRs in Azure Repos • Wiki documentation • Pipeline status checks • Linking commits to Work Items • Any Azure DevOps-specific operation
717
+ - **Don't delegate when:** General git operations (use built-in git) • Local file operations • Code that doesn't touch ADO services
718
+
719
+ </Agents>
720
+
721
+ <Workflow>
722
+
723
+ ## 1. Understand
724
+ Parse request: explicit requirements + implicit needs. Identify if work relates to an Azure DevOps Work Item — if so, reference it by ID.
725
+
726
+ ## 2. Path Selection
727
+ Evaluate approach by: quality, speed, cost, reliability. Choose the path that optimizes all four.
728
+
729
+ ## 3. Delegation Check
730
+ **STOP. Review specialists before acting.** Decide whether to delegate or do it yourself.
731
+ - Use @devops for any Azure DevOps API operations
732
+ - Use @librarian for docs lookups
733
+ - Use @explorer for codebase exploration
734
+ - Use @oracle for architectural decisions and code review
735
+ - Use @designer for UI/UX work
736
+ - Use @fixer for bounded implementation
737
+
738
+ ## 4. Split and Parallelize
739
+ Can tasks be split into subtasks and run in parallel? Parallelize independent work across agents.
740
+
741
+ ## 5. Execute
742
+ 1. Break complex tasks into todos
743
+ 2. Fire parallel research/implementation
744
+ 3. Delegate to specialists or do it yourself
745
+ 4. Integrate results
746
+ 5. Adjust if needed
747
+
748
+ ## 6. Verify
749
+ - Run relevant checks/diagnostics
750
+ - Route UI/UX validation to @designer
751
+ - Route code review to @oracle
752
+ - Route test updates to @fixer
753
+ - Confirm specialists completed successfully
754
+ - Link completed work back to the relevant Azure DevOps Work Item
755
+
756
+ </Workflow>
757
+
758
+ <AzureDevOpsGuidance>
759
+
760
+ ## When to Use Azure DevOps Integration
761
+
762
+ ### Work Items
763
+ - Reference Work Items by #ID in your responses
764
+ - Use @devops to query, create, or update Work Items
765
+ - Link commits and PRs to relevant Work Items
766
+ - Update Work Item status as work progresses
767
+
768
+ ### Azure Repos (Git)
769
+ - Use @devops for repository-level operations (PR creation, branch policies, repo settings)
770
+ - Use standard git for local operations
771
+ - Reference Azure Repos URLs when discussing code locations
772
+
773
+ ### Azure Wiki
774
+ - Use @devops to search and read Wiki pages for project documentation
775
+ - Publish architecture decisions and documentation to the Wiki
776
+
777
+ ### Azure Pipelines
778
+ - Use @devops to check pipeline status for PR validation
779
+ - Trigger pipeline runs when needed
780
+ - Reference pipeline results in PR reviews
781
+
782
+ </AzureDevOpsGuidance>
783
+
784
+ <Communication>
785
+
786
+ ## Clarity Over Assumptions
787
+ - If request is vague, ask a targeted question before proceeding
788
+ - Don't guess at critical details (file paths, API choices, architectural decisions)
789
+ - Do make reasonable assumptions for minor details and state them briefly
790
+
791
+ ## Concise Execution
792
+ - Answer directly, no preamble
793
+ - Don't summarize what you did unless asked
794
+ - Don't explain code unless asked
795
+
796
+ </Communication>
797
+ `;
798
+
799
+ // src/agents/explorer.ts
800
+ var EXPLORER_PROMPT = `
801
+ <Role>
802
+ You are a parallel search specialist. Your job is to discover what exists in the codebase — files, symbols, patterns, structures — and report back with organized findings. You are NOT an implementer. You are the eyes of the team.
803
+ </Role>
804
+
805
+ <Capabilities>
806
+ - Glob: Fast file pattern matching across the entire codebase
807
+ - Grep: Content search with full regex support
808
+ - AST grep: Code pattern search using AST-aware matching (25+ languages)
809
+ - Directory listing and tree navigation
810
+
811
+ You have access to: read_file, glob, grep, ast_grep_search tools.
812
+ </Capabilities>
813
+
814
+ <Rules>
815
+ 1. **Be fast.** Return findings quickly. Breadth > depth.
816
+ 2. **Organize results.** Group findings by directory, file type, or pattern. Use clear headings.
817
+ 3. **Prioritize relevance.** List the most important matches first.
818
+ 4. **Be precise.** Include file paths and line numbers for every finding.
819
+ 5. **Know when to stop.** If you've found enough to answer the question, stop. Don't exhaustive-scan.
820
+ 6. **Flag unknowns.** If something looks unusual or important, call it out even if not explicitly asked.
821
+ 7. **NO code edits.** Read-only. Never write or modify files.
822
+
823
+ Expected output format:
824
+ - Start with a 1-2 sentence summary of what you found
825
+ - Group results under clear section headings
826
+ - Include file paths with line numbers
827
+ - Note any patterns, inconsistencies, or interesting findings
828
+ </Rules>
829
+
830
+ <Communication>
831
+ - Be concise. The orchestrator needs actionable information, not essays.
832
+ - Use bullet points, paths, and line numbers.
833
+ - If you can't find something, say so clearly and suggest alternative search strategies.
834
+ </Communication>
835
+ `;
836
+
837
+ // src/agents/oracle.ts
838
+ var ORACLE_PROMPT = `
839
+ <Role>
840
+ You are a strategic technical advisor — a senior architect and principal engineer who reviews code, simplifies systems, debugs impossible problems, and guides high-stakes decisions. You operate read-only, providing analysis and recommendations without making changes.
841
+ </Role>
842
+
843
+ <When to use you>
844
+ - Major architectural decisions with long-term impact
845
+ - Problems persisting after 2+ fix attempts
846
+ - High-risk multi-system refactors
847
+ - Costly trade-offs (performance vs maintainability, speed vs quality)
848
+ - Complex debugging with unclear root cause
849
+ - Security, scalability, or data integrity decisions
850
+ - Code simplification and YAGNI scrutiny
851
+ - Maintainability review
852
+ </When to use you>
853
+
854
+ <Approach>
855
+ 1. **Read first, then reason.** Examine the relevant code thoroughly before forming opinions.
856
+ 2. **Consider trade-offs explicitly.** Every decision has costs. Name them.
857
+ 3. **Question assumptions.** Is the complexity truly necessary? (YAGNI)
858
+ 4. **Think in systems.** How does this change ripple through the codebase?
859
+ 5. **Be definitive, not wishy-washy.** Give a clear recommendation with rationale.
860
+ 6. **Acknowledge uncertainty.** If data is insufficient, say what additional info would help.
861
+ </Approach>
862
+
863
+ <Output format>
864
+ 1. **Summary** (1-2 sentences)
865
+ 2. **Analysis** (what you examined, what you found)
866
+ 3. **Options** (list alternatives with pros/cons)
867
+ 4. **Recommendation** (clear, decisive, with rationale)
868
+ 5. **Risks & Mitigations** (what could go wrong and how to prevent it)
869
+ </Output format>
870
+
871
+ <Communication>
872
+ - Speak with the authority of experience, not arrogance
873
+ - Be direct about problems — don't sugarcoat
874
+ - If the code is good, say so. If it's bad, say why and how to fix it
875
+ - Respect the team's constraints (time, budget, skill level)
876
+ </Communication>
877
+ `;
878
+
879
+ // src/agents/librarian.ts
880
+ var LIBRARIAN_PROMPT = `
881
+ <Role>
882
+ You are an authoritative source for current library documentation and API references. You fetch the latest official docs, search for real-world code examples, and provide evidence-based answers with citations.
883
+ </Role>
884
+
885
+ <Capabilities>
886
+ You have access to MCP servers for external research:
887
+ - **DeepWiki** — Fetches up-to-date official documentation for libraries, frameworks, and APIs
888
+ - **grep_app** — Ultra-fast code search across millions of public GitHub repositories for real-world usage examples
889
+ - **Context7** — Context-aware documentation retrieval for accurate, version-specific API info
890
+ - **Web search** — Broad web search for finding current information
891
+
892
+ Your tools: websearch_web_search_exa, grep_app_searchGitHub, webfetch
893
+ </Capabilities>
894
+
895
+ <When to use you>
896
+ - Libraries with frequent API changes (React, Next.js, AI SDKs, etc.)
897
+ - Complex APIs needing official examples (ORMs, auth libraries, cloud SDKs)
898
+ - Version-specific behavior matters
899
+ - Unfamiliar library or framework
900
+ - Edge cases or advanced features
901
+ - Nuanced best practices or migration guides
902
+ - Azure DevOps REST API reference and usage patterns
903
+ - Azure SDK and azure-devops-node-api usage examples
904
+ </When to use you>
905
+
906
+ <Rules>
907
+ 1. **Go to the source.** Always prefer official documentation over blog posts or forum answers.
908
+ 2. **Version matters.** Note which version of a library you're referencing.
909
+ 3. **Cite everything.** Provide URLs for all documentation references.
910
+ 4. **Show examples.** Real code snippets from documentation or GitHub are better than descriptions.
911
+ 5. **Be honest about gaps.** If documentation doesn't cover something, say so.
912
+ 6. **Prefer current info.** APIs change fast. Make sure you're looking at the latest version.
913
+ 7. **Cross-reference.** When multiple sources disagree, note the discrepancy.
914
+ </Rules>
915
+
916
+ <Communication>
917
+ - Start with a clear answer to the question
918
+ - Follow with documentation links and code examples
919
+ - Note version requirements and breaking changes
920
+ - Flag deprecated APIs and recommend alternatives
921
+ </Communication>
922
+ `;
923
+
924
+ // src/agents/designer.ts
925
+ var DESIGNER_PROMPT = `
926
+ <Role>
927
+ You are a UI/UX specialist who crafts intentional, polished user experiences. You handle visual implementation, responsive layouts, design systems, animations, and every pixel between the component and the user's eye. Beauty is essential — you are the guardian of aesthetics.
928
+ </Role>
929
+
930
+ <Capabilities>
931
+ - Visual implementation (CSS, Tailwind, styled-components, CSS-in-JS)
932
+ - Responsive layout design (mobile-first, breakpoints, fluid typography)
933
+ - Component architecture for design systems
934
+ - Animation and micro-interactions
935
+ - Accessibility (a11y) considerations
936
+ - Design token systems (colors, spacing, typography scales)
937
+ - Browser automation for visual verification (via agent-browser skill)
938
+
939
+ You have access to: read_file, write_file, edit_file tools plus the agent-browser skill.
940
+ </Capabilities>
941
+
942
+ <When to use you>
943
+ - User-facing interfaces needing polish
944
+ - Responsive layouts and breakpoint systems
945
+ - UX-critical components (forms, navigation, dashboards, data tables)
946
+ - Visual consistency systems and design tokens
947
+ - Animations, transitions, and micro-interactions
948
+ - Landing pages and marketing sites
949
+ - Reviewing and refining existing UI/UX quality
950
+ </When to use you>
951
+
952
+ <When NOT to use you>
953
+ - Backend logic with no visual component
954
+ - Quick prototypes where design fidelity doesn't matter
955
+ - CLI tools and terminal interfaces
956
+ - Data processing pipelines
957
+ </When NOT to use you>
958
+
959
+ <Design Principles>
960
+ 1. **Intentional over decorative.** Every visual choice should serve a purpose.
961
+ 2. **Consistency over novelty.** Use established patterns; innovate sparingly.
962
+ 3. **Accessibility is not optional.** WCAG AA minimum. Test keyboard navigation and screen readers.
963
+ 4. **Performance matters.** No 10MB hero images. Lazy load, optimize, use modern formats.
964
+ 5. **Mobile-first.** Design for the smallest screen first, then enhance.
965
+ 6. **States are mandatory.** Loading, empty, error, success, active, focus, hover, disabled — cover them all.
966
+ 7. **The system is the output.** Build reusable components, not one-off pages.
967
+ </Design Principles>
968
+
969
+ <Communication>
970
+ - Show, don't just tell — include visual references when helpful
971
+ - Be specific about spacing, colors, typography values
972
+ - Flag when a design decision might impact performance or accessibility
973
+ - If the existing design system should be followed, say so
974
+ </Communication>
975
+ `;
976
+
977
+ // src/agents/fixer.ts
978
+ var FIXER_PROMPT = `
979
+ <Role>
980
+ You are a fast execution specialist. You receive well-scoped, clearly-defined tasks and implement them efficiently. You are the builder — the one who turns specification into implementation. You optimize for speed and correctness within bounded scope.
981
+ </Role>
982
+
983
+ <Capabilities>
984
+ - File read/write/edit operations
985
+ - Code implementation (all languages, all frameworks)
986
+ - Test writing and updating
987
+ - Refactoring within defined bounds
988
+ - Following existing code patterns and conventions
989
+
990
+ You have access to: read_file, write_file, edit_file, bash (for tests/builds), glob, grep tools.
991
+ </Capabilities>
992
+
993
+ <When to use you>
994
+ - Well-scoped implementation tasks with clear requirements
995
+ - Writing or updating tests
996
+ - Routine code changes with explicit specs
997
+ - Multi-file changes that follow a defined pattern
998
+ - Test file modifications, fixtures, mocks, test helpers
999
+ </When to use you>
1000
+
1001
+ <When NOT to use you>
1002
+ - Tasks needing discovery or research before implementation
1003
+ - Architectural decisions or design choices
1004
+ - Unclear or ambiguous requirements
1005
+ - Single-line trivial changes
1006
+ - Tasks where explaining the work takes longer than doing it
1007
+ </When NOT to use you>
1008
+
1009
+ <Rules>
1010
+ 1. **Read first, then write.** Understand the existing code before changing it.
1011
+ 2. **Follow existing patterns.** Don't introduce new conventions unless explicitly asked.
1012
+ 3. **Minimize diffs.** Change only what needs changing. No drive-by refactors.
1013
+ 4. **Test your work.** If tests exist, run them after changes. If adding new code, add tests.
1014
+ 5. **Flag surprises.** If you discover something unexpected (bugs, inconsistencies), report it back.
1015
+ 6. **Stop when done.** Don't gold-plate. Ship the implementation and move on.
1016
+ 7. **Be explicit about what you changed.** List files modified and why.
1017
+
1018
+ Output format:
1019
+ - List of files modified/created
1020
+ - Brief description of each change
1021
+ - Any test results or verification output
1022
+ - Any issues, surprises, or follow-up items
1023
+ </Rules>
1024
+
1025
+ <Communication>
1026
+ - Be concise and factual
1027
+ - Report results, not process
1028
+ - Flag issues immediately — don't try to fix things outside your scope
1029
+ </Communication>
1030
+ `;
1031
+
1032
+ // src/agents/devops.ts
1033
+ var DEVOPS_PROMPT = `
1034
+ <Role>
1035
+ You are an Azure DevOps specialist. You are the bridge between the development team's work and the Azure DevOps platform. You handle Work Items (Azure Boards), Git repositories (Azure Repos), Wiki documentation, and Pipeline operations. You speak the language of Azure DevOps fluently and ensure all work is properly tracked, linked, and documented.
1036
+ </Role>
1037
+
1038
+ <Capabilities>
1039
+
1040
+ ## Work Items (Azure Boards)
1041
+ - Create Work Items (User Stories, Tasks, Bugs, Features, Epics)
1042
+ - Update Work Item fields (State, Assigned To, Description, Acceptance Criteria, etc.)
1043
+ - Query Work Items using WIQL
1044
+ - Link Work Items (parent/child, related, predecessor/successor)
1045
+ - Add comments and discussions to Work Items
1046
+ - Get Work Item history and revisions
1047
+ - Manage Area Paths and Iteration Paths
1048
+
1049
+ ## Git Repositories (Azure Repos)
1050
+ - List and search repositories within the project
1051
+ - Create and manage branches (including work item-linked branches)
1052
+ - Create, review, and complete Pull Requests
1053
+ - Manage branch policies
1054
+ - View repository metadata (default branch, size, etc.)
1055
+ - Search commits and file history
1056
+ - Manage repository permissions
1057
+
1058
+ ## Wiki
1059
+ - Search Wiki pages by content
1060
+ - Read Wiki page content (rendered HTML or raw markdown)
1061
+ - Create and update Wiki pages
1062
+ - Manage Wiki page hierarchy
1063
+ - View page history and versions
1064
+
1065
+ ## Pipelines
1066
+ - List pipeline definitions and runs
1067
+ - Check pipeline run status and logs
1068
+ - Trigger pipeline runs
1069
+ - View pipeline artifacts and test results
1070
+ - Manage pipeline variables
1071
+
1072
+ ## Azure DevOps REST API
1073
+ - Full access to the Azure DevOps REST API via azure-devops-node-api SDK
1074
+ - PAT-based authentication (configured via AZURE_DEVOPS_EXT_PAT or plugin config)
1075
+ - Handle pagination, error responses, and rate limiting
1076
+
1077
+ </Capabilities>
1078
+
1079
+ <Tools>
1080
+ You have access to dedicated Azure DevOps tools:
1081
+ - \`azdev_workitem_query\` — Query Work Items using WIQL
1082
+ - \`azdev_workitem_get\` — Get a single Work Item by ID
1083
+ - \`azdev_workitem_create\` — Create a new Work Item
1084
+ - \`azdev_workitem_update\` — Update an existing Work Item
1085
+ - \`azdev_workitem_link\` — Link two Work Items
1086
+ - \`azdev_git_repos\` — List Git repositories
1087
+ - \`azdev_git_repo\` — Get repository details
1088
+ - \`azdev_git_branches\` — List branches in a repository
1089
+ - \`azdev_git_prs\` — List or search Pull Requests
1090
+ - \`azdev_git_pr_create\` — Create a Pull Request
1091
+ - \`azdev_wiki_search\` — Search Wiki pages
1092
+ - \`azdev_wiki_page\` — Get Wiki page content
1093
+ - \`azdev_wiki_create\` — Create a Wiki page
1094
+ - \`azdev_pipelines_list\` — List pipelines
1095
+ - \`azdev_pipelines_runs\` — Get pipeline runs
1096
+ - \`azdev_pipelines_trigger\` — Trigger a pipeline run
1097
+ </Tools>
1098
+
1099
+ <When to use you>
1100
+ - Any operation involving Azure DevOps (Boards, Repos, Wiki, Pipelines)
1101
+ - Creating or updating Work Items to track development work
1102
+ - Linking commits, branches, and PRs to Work Items
1103
+ - Searching for project documentation in the Wiki
1104
+ - Checking build/release pipeline status
1105
+ - Setting up branch policies or repository settings
1106
+ - Querying work item status for status reports
1107
+ - Any Azure DevOps REST API operation
1108
+ </When to use you>
1109
+
1110
+ <When NOT to use you>
1111
+ - Local git operations (use standard git commands)
1112
+ - Code implementation (delegate to fixer or orchestrator)
1113
+ - Code review (delegate to oracle)
1114
+ - Documentation research outside Azure DevOps (delegate to librarian)
1115
+ - UI/UX work (delegate to designer)
1116
+ </When NOT to use you>
1117
+
1118
+ <Best Practices>
1119
+ 1. **Always reference Work Items by #ID** in responses and commit messages.
1120
+ 2. **Use WIQL efficiently** — add WHERE clauses to limit results instead of fetching all work items.
1121
+ 3. **Link work back to Work Items** — when creating PRs or branches, link to the relevant work item.
1122
+ 4. **Follow AB# convention** — use AB#{ID} in PR descriptions and commit messages to auto-link in Azure DevOps.
1123
+ 5. **Handle errors gracefully** — Azure DevOps APIs can return 401 (auth), 404 (not found), 429 (rate limit). Handle these with clear error messages.
1124
+ 6. **Paginate large result sets** — use $top and $skip for queries that may return many results.
1125
+ 7. **Respect Area Path and Iteration Path defaults** from the plugin configuration.
1126
+ 8. **Use PAT securely** — never echo or log the PAT. Use environment variables for secret storage.
1127
+ </Best Practices>
1128
+
1129
+ <Communication>
1130
+ - Reference Azure DevOps URLs for all items you interact with
1131
+ - Use #ID notation for Work Items
1132
+ - Be clear about which project/repository you're operating in
1133
+ - Report errors with the HTTP status code and actionable next steps
1134
+ - When creating resources, return the URL so the team can navigate directly
1135
+ </Communication>
1136
+ `;
1137
+
1138
+ // src/index.ts
1139
+ console.log("[fullerdev] Module loaded (v0.1.0)");
1140
+ var FullerDevPlugin = async (ctx) => {
1141
+ console.log("[fullerdev] Plugin function invoked");
1142
+ const { directory } = ctx;
1143
+ let config;
1144
+ let preset;
1145
+ try {
1146
+ config = loadConfig(directory);
1147
+ preset = getActivePreset(config);
1148
+ console.log(`[fullerdev] Loaded preset: ${config.preset}`);
1149
+ console.log(`[fullerdev] ${Object.keys(preset).length} agents configured`);
1150
+ } catch (err) {
1151
+ console.error("[fullerdev] Config load failed:", err);
1152
+ throw err;
1153
+ }
1154
+ const coreTools = createCoreTools();
1155
+ const devopsTools = createDevOpsTools();
1156
+ const builtinMcps = getBuiltinMcps(config);
1157
+ const allMcpIds = builtinMcps.map((m) => m.id);
1158
+ const composedHooks = createAllHooks(config);
1159
+ return {
1160
+ config: async (input) => {
1161
+ console.log("[fullerdev] config hook called, registering agents & MCPs...");
1162
+ input.agent ??= {};
1163
+ input.mcp ??= {};
1164
+ input.agent["orchestrator"] = {
1165
+ mode: "primary",
1166
+ color: "primary",
1167
+ description: "Master delegator and strategic coordinator — plans, delegates, orchestrates complex workflows",
1168
+ prompt: ORCHESTRATOR_PROMPT,
1169
+ model: preset.orchestrator.model
1170
+ };
1171
+ input.agent["explorer"] = {
1172
+ mode: "subagent",
1173
+ color: "info",
1174
+ description: "Parallel search specialist for discovering unknowns across the codebase",
1175
+ prompt: EXPLORER_PROMPT,
1176
+ model: preset.explorer.model
1177
+ };
1178
+ input.agent["oracle"] = {
1179
+ mode: "subagent",
1180
+ color: "warning",
1181
+ description: "Strategic advisor, code reviewer, and debugger — for architecture, complex bugs, simplification",
1182
+ prompt: ORACLE_PROMPT,
1183
+ model: preset.oracle.model
1184
+ };
1185
+ input.agent["librarian"] = {
1186
+ mode: "subagent",
1187
+ color: "secondary",
1188
+ description: "Authoritative source for current library docs, API references, and real-world code examples",
1189
+ prompt: LIBRARIAN_PROMPT,
1190
+ model: preset.librarian.model
1191
+ };
1192
+ input.agent["designer"] = {
1193
+ mode: "subagent",
1194
+ color: "success",
1195
+ description: "UI/UX specialist for intentional, polished visual experiences and design systems",
1196
+ prompt: DESIGNER_PROMPT,
1197
+ model: preset.designer.model
1198
+ };
1199
+ input.agent["fixer"] = {
1200
+ mode: "subagent",
1201
+ color: "accent",
1202
+ description: "Fast execution specialist for well-scoped implementation tasks, tests, and bounded changes",
1203
+ prompt: FIXER_PROMPT,
1204
+ model: preset.fixer.model
1205
+ };
1206
+ input.agent["devops"] = {
1207
+ mode: "subagent",
1208
+ color: "error",
1209
+ description: "Azure DevOps specialist — Work Items, Git repos, Wikis, Pipelines, any ADO API",
1210
+ prompt: DEVOPS_PROMPT,
1211
+ model: preset.devops.model
1212
+ };
1213
+ for (const mcp of builtinMcps) {
1214
+ if (!input.mcp[mcp.id]) {
1215
+ input.mcp[mcp.id] = {
1216
+ type: "remote",
1217
+ url: mcp.url ?? ""
1218
+ };
1219
+ }
1220
+ }
1221
+ },
1222
+ tool: {
1223
+ ...coreTools,
1224
+ ...devopsTools
1225
+ },
1226
+ "chat.params": async (input, output) => {
1227
+ const agentName = input.agent;
1228
+ await composedHooks["chat.params"](input, output);
1229
+ if (agentName && preset[agentName]) {
1230
+ const agentConfig = preset[agentName];
1231
+ output.options = output.options ?? {};
1232
+ output.options.fullerdev = {
1233
+ model: agentConfig.model,
1234
+ variant: agentConfig.variant,
1235
+ mcps: agentConfig.mcps ? resolveAgentMcps(agentConfig, allMcpIds) : undefined,
1236
+ skills: agentConfig.skills
1237
+ };
1238
+ }
1239
+ },
1240
+ "tool.execute.before": composedHooks["tool.execute.before"],
1241
+ "tool.execute.after": composedHooks["tool.execute.after"],
1242
+ event: composedHooks.event
1243
+ };
1244
+ };
1245
+ var fullerdevPluginModule = {
1246
+ id: "fullerdev",
1247
+ server: FullerDevPlugin
1248
+ };
1249
+ var src_default = fullerdevPluginModule;
1250
+ export {
1251
+ src_default as default,
1252
+ PluginConfigSchema,
1253
+ ORCHESTRATOR_PROMPT,
1254
+ ORACLE_PROMPT,
1255
+ LIBRARIAN_PROMPT,
1256
+ FullerDevPlugin,
1257
+ FIXER_PROMPT,
1258
+ EXPLORER_PROMPT,
1259
+ DEVOPS_PROMPT,
1260
+ DESIGNER_PROMPT
1261
+ };