@cubis/foundry 0.3.39 → 0.3.41
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.
- package/README.md +64 -0
- package/bin/cubis.js +382 -25
- package/mcp/README.md +72 -8
- package/mcp/config.json +3 -0
- package/mcp/dist/index.js +315 -68
- package/mcp/src/config/index.test.ts +1 -0
- package/mcp/src/config/schema.ts +5 -0
- package/mcp/src/index.ts +40 -9
- package/mcp/src/server.ts +66 -10
- package/mcp/src/telemetry/tokenBudget.ts +114 -0
- package/mcp/src/tools/index.ts +7 -0
- package/mcp/src/tools/skillBrowseCategory.ts +22 -5
- package/mcp/src/tools/skillBudgetReport.ts +128 -0
- package/mcp/src/tools/skillGet.ts +18 -0
- package/mcp/src/tools/skillListCategories.ts +19 -6
- package/mcp/src/tools/skillSearch.ts +22 -5
- package/mcp/src/tools/skillTools.test.ts +61 -9
- package/mcp/src/vault/manifest.test.ts +19 -1
- package/mcp/src/vault/manifest.ts +12 -1
- package/mcp/src/vault/scanner.test.ts +1 -0
- package/mcp/src/vault/scanner.ts +1 -0
- package/mcp/src/vault/types.ts +6 -0
- package/package.json +1 -1
- package/workflows/skills/code-documenter/references/images/create-key.png +0 -0
- package/workflows/skills/code-documenter/references/images/dashboard-annotated.png +0 -0
- package/workflows/skills/documentation-templates/docs/api.md +16 -0
- package/workflows/skills/documentation-templates/docs/architecture.md +23 -0
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/rules/GEMINI.md +35 -1
- package/workflows/workflows/agent-environment-setup/platforms/codex/rules/AGENTS.md +38 -3
- package/workflows/workflows/agent-environment-setup/platforms/copilot/rules/AGENTS.md +35 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/rules/copilot-instructions.md +35 -1
- package/workflows/workflows/agent-environment-setup/platforms/cursor/rules/.cursorrules +28 -0
- package/workflows/workflows/agent-environment-setup/platforms/windsurf/rules/.windsurfrules +28 -0
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import type { VaultManifest } from "../vault/types.js";
|
|
10
10
|
import { enrichWithDescriptions } from "../vault/manifest.js";
|
|
11
|
+
import {
|
|
12
|
+
buildSkillToolMetrics,
|
|
13
|
+
estimateTokensFromBytes,
|
|
14
|
+
estimateTokensFromText,
|
|
15
|
+
} from "../telemetry/tokenBudget.js";
|
|
11
16
|
|
|
12
17
|
export const skillSearchName = "skill_search";
|
|
13
18
|
|
|
@@ -27,6 +32,7 @@ export async function handleSkillSearch(
|
|
|
27
32
|
args: z.infer<typeof skillSearchSchema>,
|
|
28
33
|
manifest: VaultManifest,
|
|
29
34
|
summaryMaxLength: number,
|
|
35
|
+
charsPerToken: number,
|
|
30
36
|
) {
|
|
31
37
|
const { query } = args;
|
|
32
38
|
const lower = query.toLowerCase();
|
|
@@ -56,17 +62,28 @@ export async function handleSkillSearch(
|
|
|
56
62
|
category: s.category,
|
|
57
63
|
description: s.description ?? "(no description)",
|
|
58
64
|
}));
|
|
65
|
+
const payload = { query, results, count: results.length };
|
|
66
|
+
const text = JSON.stringify(payload, null, 2);
|
|
67
|
+
const selectedSkillsEstimatedTokens = matches.reduce(
|
|
68
|
+
(sum, skill) => sum + estimateTokensFromBytes(skill.fileBytes, charsPerToken),
|
|
69
|
+
0,
|
|
70
|
+
);
|
|
71
|
+
const metrics = buildSkillToolMetrics({
|
|
72
|
+
charsPerToken,
|
|
73
|
+
fullCatalogEstimatedTokens: manifest.fullCatalogEstimatedTokens,
|
|
74
|
+
responseEstimatedTokens: estimateTokensFromText(text, charsPerToken),
|
|
75
|
+
selectedSkillsEstimatedTokens,
|
|
76
|
+
});
|
|
59
77
|
|
|
60
78
|
return {
|
|
61
79
|
content: [
|
|
62
80
|
{
|
|
63
81
|
type: "text" as const,
|
|
64
|
-
text
|
|
65
|
-
{ query, results, count: results.length },
|
|
66
|
-
null,
|
|
67
|
-
2,
|
|
68
|
-
),
|
|
82
|
+
text,
|
|
69
83
|
},
|
|
70
84
|
],
|
|
85
|
+
structuredContent: {
|
|
86
|
+
metrics,
|
|
87
|
+
},
|
|
71
88
|
};
|
|
72
89
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { mkdtempSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { mkdtempSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import type { VaultManifest } from "../vault/types.js";
|
|
6
6
|
import { handleSkillBrowseCategory } from "./skillBrowseCategory.js";
|
|
7
|
+
import { handleSkillBudgetReport } from "./skillBudgetReport.js";
|
|
7
8
|
import { handleSkillGet } from "./skillGet.js";
|
|
8
9
|
import { handleSkillListCategories } from "./skillListCategories.js";
|
|
9
10
|
import { handleSkillSearch } from "./skillSearch.js";
|
|
@@ -12,6 +13,10 @@ function payload(result: { content: Array<{ text: string }> }): Record<string, u
|
|
|
12
13
|
return JSON.parse(result.content[0].text) as Record<string, unknown>;
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
function metrics(result: { structuredContent?: Record<string, unknown> }): Record<string, unknown> {
|
|
17
|
+
return (result.structuredContent?.metrics || {}) as Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
function createSkillFile(id: string, description: string, body = "# Content"): string {
|
|
16
21
|
const dir = mkdtempSync(path.join(os.tmpdir(), `mcp-skill-${id}-`));
|
|
17
22
|
const file = path.join(dir, "SKILL.md");
|
|
@@ -32,27 +37,47 @@ function createManifest(): VaultManifest {
|
|
|
32
37
|
"fastapi-expert",
|
|
33
38
|
"FastAPI async backend patterns",
|
|
34
39
|
);
|
|
40
|
+
const reactBytes = statSync(reactFile).size;
|
|
41
|
+
const fastapiBytes = statSync(fastapiFile).size;
|
|
42
|
+
const fullCatalogBytes = reactBytes + fastapiBytes;
|
|
35
43
|
|
|
36
44
|
return {
|
|
37
45
|
categories: ["backend", "frontend"],
|
|
38
46
|
skills: [
|
|
39
|
-
{
|
|
40
|
-
|
|
47
|
+
{
|
|
48
|
+
id: "react-expert",
|
|
49
|
+
category: "frontend",
|
|
50
|
+
path: reactFile,
|
|
51
|
+
fileBytes: reactBytes,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "fastapi-expert",
|
|
55
|
+
category: "backend",
|
|
56
|
+
path: fastapiFile,
|
|
57
|
+
fileBytes: fastapiBytes,
|
|
58
|
+
},
|
|
41
59
|
],
|
|
60
|
+
fullCatalogBytes,
|
|
61
|
+
fullCatalogEstimatedTokens: Math.ceil(fullCatalogBytes / 4),
|
|
42
62
|
};
|
|
43
63
|
}
|
|
44
64
|
|
|
45
65
|
describe("skill tools", () => {
|
|
46
66
|
it("lists categories with skill counts", () => {
|
|
47
67
|
const manifest = createManifest();
|
|
48
|
-
const result = handleSkillListCategories(manifest);
|
|
68
|
+
const result = handleSkillListCategories(manifest, 4);
|
|
49
69
|
const data = payload(result);
|
|
70
|
+
const toolMetrics = metrics(result);
|
|
50
71
|
|
|
51
72
|
expect(data.totalSkills).toBe(2);
|
|
52
73
|
expect(data.categories).toEqual([
|
|
53
74
|
{ category: "backend", skillCount: 1 },
|
|
54
75
|
{ category: "frontend", skillCount: 1 },
|
|
55
76
|
]);
|
|
77
|
+
expect(toolMetrics.estimatorVersion).toBeDefined();
|
|
78
|
+
expect(toolMetrics.fullCatalogEstimatedTokens).toBe(
|
|
79
|
+
manifest.fullCatalogEstimatedTokens,
|
|
80
|
+
);
|
|
56
81
|
});
|
|
57
82
|
|
|
58
83
|
it("browses a category with enriched descriptions", async () => {
|
|
@@ -61,8 +86,10 @@ describe("skill tools", () => {
|
|
|
61
86
|
{ category: "frontend" },
|
|
62
87
|
manifest,
|
|
63
88
|
200,
|
|
89
|
+
4,
|
|
64
90
|
);
|
|
65
91
|
const data = payload(result);
|
|
92
|
+
const toolMetrics = metrics(result);
|
|
66
93
|
|
|
67
94
|
expect(data.category).toBe("frontend");
|
|
68
95
|
expect(data.count).toBe(1);
|
|
@@ -72,12 +99,13 @@ describe("skill tools", () => {
|
|
|
72
99
|
description: "React performance and architecture guidance",
|
|
73
100
|
},
|
|
74
101
|
]);
|
|
102
|
+
expect(toolMetrics.selectedSkillsEstimatedTokens).toBeGreaterThan(0);
|
|
75
103
|
});
|
|
76
104
|
|
|
77
105
|
it("throws when browsing an unknown category", async () => {
|
|
78
106
|
const manifest = createManifest();
|
|
79
107
|
await expect(
|
|
80
|
-
handleSkillBrowseCategory({ category: "mobile" }, manifest, 200),
|
|
108
|
+
handleSkillBrowseCategory({ category: "mobile" }, manifest, 200, 4),
|
|
81
109
|
).rejects.toThrow('Category not found: "mobile"');
|
|
82
110
|
});
|
|
83
111
|
|
|
@@ -85,7 +113,7 @@ describe("skill tools", () => {
|
|
|
85
113
|
const manifest = createManifest();
|
|
86
114
|
|
|
87
115
|
const byId = payload(
|
|
88
|
-
await handleSkillSearch({ query: "react" }, manifest, 200),
|
|
116
|
+
await handleSkillSearch({ query: "react" }, manifest, 200, 4),
|
|
89
117
|
);
|
|
90
118
|
expect(byId.count).toBe(1);
|
|
91
119
|
expect(byId.results).toEqual([
|
|
@@ -97,7 +125,7 @@ describe("skill tools", () => {
|
|
|
97
125
|
]);
|
|
98
126
|
|
|
99
127
|
const byDescription = payload(
|
|
100
|
-
await handleSkillSearch({ query: "async backend" }, manifest, 200),
|
|
128
|
+
await handleSkillSearch({ query: "async backend" }, manifest, 200, 4),
|
|
101
129
|
);
|
|
102
130
|
expect(byDescription.count).toBe(1);
|
|
103
131
|
expect(byDescription.results).toEqual([
|
|
@@ -111,16 +139,40 @@ describe("skill tools", () => {
|
|
|
111
139
|
|
|
112
140
|
it("returns full skill content for skill_get", async () => {
|
|
113
141
|
const manifest = createManifest();
|
|
114
|
-
const result = await handleSkillGet({ id: "react-expert" }, manifest);
|
|
142
|
+
const result = await handleSkillGet({ id: "react-expert" }, manifest, 4);
|
|
143
|
+
const toolMetrics = metrics(result);
|
|
115
144
|
|
|
116
145
|
expect(result.content[0].text).toContain("# Content");
|
|
117
146
|
expect(result.content[0].text).toContain("description: React performance");
|
|
147
|
+
expect(toolMetrics.loadedSkillEstimatedTokens).toBeGreaterThan(0);
|
|
118
148
|
});
|
|
119
149
|
|
|
120
150
|
it("throws when skill_get cannot find the requested skill", async () => {
|
|
121
151
|
const manifest = createManifest();
|
|
122
|
-
await expect(handleSkillGet({ id: "missing" }, manifest)).rejects.toThrow(
|
|
152
|
+
await expect(handleSkillGet({ id: "missing" }, manifest, 4)).rejects.toThrow(
|
|
123
153
|
'Skill not found: "missing"',
|
|
124
154
|
);
|
|
125
155
|
});
|
|
156
|
+
|
|
157
|
+
it("returns consolidated budget rollup for selected and loaded skills", () => {
|
|
158
|
+
const manifest = createManifest();
|
|
159
|
+
const result = handleSkillBudgetReport(
|
|
160
|
+
{
|
|
161
|
+
selectedSkillIds: ["react-expert", "missing-skill"],
|
|
162
|
+
loadedSkillIds: ["react-expert"],
|
|
163
|
+
},
|
|
164
|
+
manifest,
|
|
165
|
+
4,
|
|
166
|
+
);
|
|
167
|
+
const data = payload(result);
|
|
168
|
+
|
|
169
|
+
expect(data.skillLog).toBeDefined();
|
|
170
|
+
expect(data.contextBudget).toMatchObject({
|
|
171
|
+
fullCatalogEstimatedTokens: manifest.fullCatalogEstimatedTokens,
|
|
172
|
+
estimated: true,
|
|
173
|
+
});
|
|
174
|
+
expect(
|
|
175
|
+
(data.skillLog as Record<string, unknown>).unknownSelectedSkillIds,
|
|
176
|
+
).toContain("missing-skill");
|
|
177
|
+
});
|
|
126
178
|
});
|
|
@@ -3,6 +3,7 @@ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import {
|
|
6
|
+
buildManifest,
|
|
6
7
|
enrichWithDescriptions,
|
|
7
8
|
extractDescription,
|
|
8
9
|
parseDescriptionFromFrontmatter,
|
|
@@ -109,11 +110,12 @@ describe("manifest enrichment", () => {
|
|
|
109
110
|
|
|
110
111
|
const enriched = await enrichWithDescriptions(
|
|
111
112
|
[
|
|
112
|
-
{ id: "alpha", category: "general", path: fileA },
|
|
113
|
+
{ id: "alpha", category: "general", path: fileA, fileBytes: 64 },
|
|
113
114
|
{
|
|
114
115
|
id: "beta",
|
|
115
116
|
category: "general",
|
|
116
117
|
path: fileB,
|
|
118
|
+
fileBytes: 64,
|
|
117
119
|
description: "Already populated",
|
|
118
120
|
},
|
|
119
121
|
],
|
|
@@ -124,3 +126,19 @@ describe("manifest enrichment", () => {
|
|
|
124
126
|
expect(enriched[1].description).toBe("Already populated");
|
|
125
127
|
});
|
|
126
128
|
});
|
|
129
|
+
|
|
130
|
+
describe("buildManifest", () => {
|
|
131
|
+
it("computes full catalog byte and token totals", () => {
|
|
132
|
+
const manifest = buildManifest(
|
|
133
|
+
[
|
|
134
|
+
{ id: "a", category: "general", path: "/tmp/a.md", fileBytes: 20 },
|
|
135
|
+
{ id: "b", category: "frontend", path: "/tmp/b.md", fileBytes: 12 },
|
|
136
|
+
],
|
|
137
|
+
4,
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
expect(manifest.categories).toEqual(["frontend", "general"]);
|
|
141
|
+
expect(manifest.fullCatalogBytes).toBe(32);
|
|
142
|
+
expect(manifest.fullCatalogEstimatedTokens).toBe(8);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -8,19 +8,30 @@
|
|
|
8
8
|
import { readFile } from "node:fs/promises";
|
|
9
9
|
import type { SkillPointer, VaultManifest } from "./types.js";
|
|
10
10
|
import { logger } from "../utils/logger.js";
|
|
11
|
+
import { estimateTokensFromBytes } from "../telemetry/tokenBudget.js";
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Build a VaultManifest from scanned skill pointers.
|
|
14
15
|
* Categories are derived from the pointers.
|
|
15
16
|
*/
|
|
16
|
-
export function buildManifest(
|
|
17
|
+
export function buildManifest(
|
|
18
|
+
skills: SkillPointer[],
|
|
19
|
+
charsPerToken: number,
|
|
20
|
+
): VaultManifest {
|
|
17
21
|
const categorySet = new Set<string>();
|
|
22
|
+
let fullCatalogBytes = 0;
|
|
18
23
|
for (const skill of skills) {
|
|
19
24
|
categorySet.add(skill.category);
|
|
25
|
+
fullCatalogBytes += skill.fileBytes;
|
|
20
26
|
}
|
|
21
27
|
return {
|
|
22
28
|
categories: [...categorySet].sort(),
|
|
23
29
|
skills,
|
|
30
|
+
fullCatalogBytes,
|
|
31
|
+
fullCatalogEstimatedTokens: estimateTokensFromBytes(
|
|
32
|
+
fullCatalogBytes,
|
|
33
|
+
charsPerToken,
|
|
34
|
+
),
|
|
24
35
|
};
|
|
25
36
|
}
|
|
26
37
|
|
|
@@ -52,6 +52,7 @@ describe("scanVaultRoots", () => {
|
|
|
52
52
|
expect(byId["react-expert"]).toBe("frontend");
|
|
53
53
|
expect(byId["database-design"]).toBe("data");
|
|
54
54
|
expect(byId["custom-skill"]).toBe("general");
|
|
55
|
+
expect(skills.every((skill) => skill.fileBytes > 0)).toBe(true);
|
|
55
56
|
});
|
|
56
57
|
|
|
57
58
|
it("skips missing roots and continues scanning valid roots", async () => {
|
package/mcp/src/vault/scanner.ts
CHANGED
package/mcp/src/vault/types.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface SkillPointer {
|
|
|
9
9
|
category: string;
|
|
10
10
|
/** Absolute path to the SKILL.md file. */
|
|
11
11
|
path: string;
|
|
12
|
+
/** Skill file size in bytes. */
|
|
13
|
+
fileBytes: number;
|
|
12
14
|
/** Short description extracted from frontmatter (truncated). */
|
|
13
15
|
description?: string;
|
|
14
16
|
}
|
|
@@ -18,4 +20,8 @@ export interface VaultManifest {
|
|
|
18
20
|
categories: string[];
|
|
19
21
|
/** All skill pointers (metadata only – no full content). */
|
|
20
22
|
skills: SkillPointer[];
|
|
23
|
+
/** Total bytes across all discovered SKILL.md files. */
|
|
24
|
+
fullCatalogBytes: number;
|
|
25
|
+
/** Estimated full-catalog token usage (deterministic estimator). */
|
|
26
|
+
fullCatalogEstimatedTokens: number;
|
|
21
27
|
}
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# API Reference Template
|
|
2
|
+
|
|
3
|
+
Use this file as the canonical entry point for API endpoint documentation.
|
|
4
|
+
|
|
5
|
+
## Endpoint Index
|
|
6
|
+
|
|
7
|
+
- `GET /resource`
|
|
8
|
+
- `POST /resource`
|
|
9
|
+
- `PATCH /resource/{id}`
|
|
10
|
+
- `DELETE /resource/{id}`
|
|
11
|
+
|
|
12
|
+
## Conventions
|
|
13
|
+
|
|
14
|
+
- Include auth requirements per endpoint.
|
|
15
|
+
- Include request/response examples.
|
|
16
|
+
- Include error codes and retry guidance.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Architecture Overview Template
|
|
2
|
+
|
|
3
|
+
Use this file to describe system boundaries and data flow.
|
|
4
|
+
|
|
5
|
+
## Components
|
|
6
|
+
|
|
7
|
+
- API layer
|
|
8
|
+
- Domain/service layer
|
|
9
|
+
- Persistence layer
|
|
10
|
+
- External integrations
|
|
11
|
+
|
|
12
|
+
## Runtime Flow
|
|
13
|
+
|
|
14
|
+
1. Request enters API layer
|
|
15
|
+
2. Domain logic validates and processes
|
|
16
|
+
3. Persistence reads/writes state
|
|
17
|
+
4. Response returns with observability metadata
|
|
18
|
+
|
|
19
|
+
## Non-Functional Notes
|
|
20
|
+
|
|
21
|
+
- Reliability/SLOs
|
|
22
|
+
- Security model
|
|
23
|
+
- Scaling strategy
|
|
@@ -68,6 +68,32 @@ Use the best specialist first:
|
|
|
68
68
|
|
|
69
69
|
## 5) Skill Loading Policy
|
|
70
70
|
|
|
71
|
+
## MCP-first Skill Discovery Order (Required)
|
|
72
|
+
|
|
73
|
+
1. Use `skill_search` first to narrow candidate skills.
|
|
74
|
+
2. Use `skill_browse_category` second to inspect category-level candidates.
|
|
75
|
+
3. Use `skill_get` only for final selected skills that must be loaded.
|
|
76
|
+
4. Keep pointer-first flow; avoid loading full skill text prematurely.
|
|
77
|
+
|
|
78
|
+
## Skill Log Completion Block (Required)
|
|
79
|
+
|
|
80
|
+
After finishing skill selection/loading, publish:
|
|
81
|
+
|
|
82
|
+
- `selected_skills`: skill IDs selected for the task
|
|
83
|
+
- `loaded_skills`: skill IDs loaded via `skill_get`
|
|
84
|
+
- `skipped_skills`: considered but not loaded
|
|
85
|
+
|
|
86
|
+
## Context Budget Block (Required, Estimated)
|
|
87
|
+
|
|
88
|
+
Immediately after the Skill Log block, publish estimated budget fields:
|
|
89
|
+
|
|
90
|
+
- `full_catalog_est_tokens`
|
|
91
|
+
- `loaded_est_tokens`
|
|
92
|
+
- `estimated_savings_tokens`
|
|
93
|
+
- `estimated_savings_percent`
|
|
94
|
+
|
|
95
|
+
Mark all context/token values as deterministic estimates (not provider metering).
|
|
96
|
+
|
|
71
97
|
### Smart Skill Selection (Adaptive)
|
|
72
98
|
|
|
73
99
|
Use an adaptive load policy to control context size:
|
|
@@ -85,6 +111,8 @@ Use an adaptive load policy to control context size:
|
|
|
85
111
|
4. If a mapped skill is missing, continue with best fallback and state it.
|
|
86
112
|
5. Keep user-visible decision logs concise: selected skill(s) and one-line rationale.
|
|
87
113
|
|
|
114
|
+
After the skill log is complete, append the Context Budget block in the same response/update.
|
|
115
|
+
|
|
88
116
|
## 6) Socratic Gate (Before Complex Work)
|
|
89
117
|
|
|
90
118
|
Before multi-file or architecture-impacting changes, ask targeted questions when requirements are unclear:
|
|
@@ -110,7 +138,13 @@ If Antigravity script harness exists, prefer:
|
|
|
110
138
|
Use these commands to keep this setup healthy:
|
|
111
139
|
|
|
112
140
|
- Install/update bundle:
|
|
113
|
-
`cbx workflows install --platform antigravity --bundle agent-environment-setup --scope global --overwrite`
|
|
141
|
+
`cbx workflows install --platform antigravity --bundle agent-environment-setup --scope global --overwrite --postman --stitch --mcp-runtime docker --mcp-fallback local --mcp-tool-sync`
|
|
142
|
+
- Start MCP Docker runtime:
|
|
143
|
+
`cbx mcp runtime up --scope global --name cbx-mcp --port 3310 --replace`
|
|
144
|
+
- Check MCP Docker runtime:
|
|
145
|
+
`cbx mcp runtime status --scope global --name cbx-mcp`
|
|
146
|
+
- Stop MCP Docker runtime:
|
|
147
|
+
`cbx mcp runtime down --name cbx-mcp`
|
|
114
148
|
- Rebuild managed routing block:
|
|
115
149
|
`cbx workflows sync-rules --platform antigravity --scope project`
|
|
116
150
|
- Diagnose setup issues:
|
|
@@ -14,12 +14,13 @@ This file defines mandatory behavior for Codex projects installed via `cbx workf
|
|
|
14
14
|
Before executing workflows, agents, or code edits, publish a short `Decision Log` that is visible to the user:
|
|
15
15
|
|
|
16
16
|
1. Rule file(s) read at startup (at minimum `AGENTS.md`, plus any additional rule files loaded).
|
|
17
|
-
2. Workflow decision (
|
|
18
|
-
3. Agent routing decision (
|
|
17
|
+
2. Workflow decision ($workflow-* or direct mode) and why it was chosen.
|
|
18
|
+
3. Agent routing decision ($agent-* or direct mode) and why it was chosen.
|
|
19
19
|
4. Skill loading decision (skill names loaded) and why they were chosen.
|
|
20
20
|
|
|
21
21
|
If routing changes during the task, publish a `Decision Update` before continuing.
|
|
22
22
|
Keep this user-visible summary concise and factual; do not expose private chain-of-thought.
|
|
23
|
+
When mentioning wrappers in user-visible logs, use raw $workflow-* and $agent-* tokens (no backticks) so Codex can render icon/blue mention styling.
|
|
23
24
|
|
|
24
25
|
## 2) Skill-Based Workflow
|
|
25
26
|
|
|
@@ -63,6 +64,32 @@ Use the best specialist first:
|
|
|
63
64
|
|
|
64
65
|
## 5) Skill Loading Policy
|
|
65
66
|
|
|
67
|
+
## MCP-first Skill Discovery Order (Required)
|
|
68
|
+
|
|
69
|
+
1. Use `skill_search` first to narrow candidate skills.
|
|
70
|
+
2. Use `skill_browse_category` second to inspect category-level candidates.
|
|
71
|
+
3. Use `skill_get` only for final selected skills that must be loaded.
|
|
72
|
+
4. Keep pointer-first flow; avoid loading full skill text prematurely.
|
|
73
|
+
|
|
74
|
+
## Skill Log Completion Block (Required)
|
|
75
|
+
|
|
76
|
+
After finishing skill selection/loading, publish:
|
|
77
|
+
|
|
78
|
+
- `selected_skills`: skill IDs selected for the task
|
|
79
|
+
- `loaded_skills`: skill IDs loaded via `skill_get`
|
|
80
|
+
- `skipped_skills`: considered but not loaded
|
|
81
|
+
|
|
82
|
+
## Context Budget Block (Required, Estimated)
|
|
83
|
+
|
|
84
|
+
Immediately after the Skill Log block, publish estimated budget fields:
|
|
85
|
+
|
|
86
|
+
- `full_catalog_est_tokens`
|
|
87
|
+
- `loaded_est_tokens`
|
|
88
|
+
- `estimated_savings_tokens`
|
|
89
|
+
- `estimated_savings_percent`
|
|
90
|
+
|
|
91
|
+
Mark all context/token values as deterministic estimates (not provider metering).
|
|
92
|
+
|
|
66
93
|
### Smart Skill Selection (Adaptive)
|
|
67
94
|
|
|
68
95
|
Use an adaptive load policy to control context size:
|
|
@@ -80,6 +107,8 @@ Use an adaptive load policy to control context size:
|
|
|
80
107
|
4. If a mapped skill is missing, continue with best fallback and state it.
|
|
81
108
|
5. Keep user-visible decision logs concise: selected skill(s) and one-line rationale.
|
|
82
109
|
|
|
110
|
+
After the skill log is complete, append the Context Budget block in the same response/update.
|
|
111
|
+
|
|
83
112
|
## 6) Socratic Gate (Before Complex Work)
|
|
84
113
|
|
|
85
114
|
Before multi-file or architecture-impacting changes, ask targeted questions when requirements are unclear:
|
|
@@ -100,7 +129,13 @@ Before multi-file or architecture-impacting changes, ask targeted questions when
|
|
|
100
129
|
Use these commands to keep this setup healthy:
|
|
101
130
|
|
|
102
131
|
- Install/update bundle:
|
|
103
|
-
`cbx workflows install --platform codex --bundle agent-environment-setup --scope global --overwrite`
|
|
132
|
+
`cbx workflows install --platform codex --bundle agent-environment-setup --scope global --overwrite --postman --stitch --mcp-runtime docker --mcp-fallback local --mcp-tool-sync`
|
|
133
|
+
- Start MCP Docker runtime:
|
|
134
|
+
`cbx mcp runtime up --scope global --name cbx-mcp --port 3310 --replace`
|
|
135
|
+
- Check MCP Docker runtime:
|
|
136
|
+
`cbx mcp runtime status --scope global --name cbx-mcp`
|
|
137
|
+
- Stop MCP Docker runtime:
|
|
138
|
+
`cbx mcp runtime down --name cbx-mcp`
|
|
104
139
|
- Rebuild managed routing block:
|
|
105
140
|
`cbx workflows sync-rules --platform codex --scope project`
|
|
106
141
|
- Diagnose setup issues:
|
|
@@ -72,6 +72,32 @@ When authoring custom Copilot assets, keep frontmatter schema compatible:
|
|
|
72
72
|
|
|
73
73
|
## 6) Skill Loading Policy
|
|
74
74
|
|
|
75
|
+
## MCP-first Skill Discovery Order (Required)
|
|
76
|
+
|
|
77
|
+
1. Use `skill_search` first to narrow candidate skills.
|
|
78
|
+
2. Use `skill_browse_category` second to inspect category-level candidates.
|
|
79
|
+
3. Use `skill_get` only for final selected skills that must be loaded.
|
|
80
|
+
4. Keep pointer-first flow; avoid loading full skill text prematurely.
|
|
81
|
+
|
|
82
|
+
## Skill Log Completion Block (Required)
|
|
83
|
+
|
|
84
|
+
After finishing skill selection/loading, publish:
|
|
85
|
+
|
|
86
|
+
- `selected_skills`: skill IDs selected for the task
|
|
87
|
+
- `loaded_skills`: skill IDs loaded via `skill_get`
|
|
88
|
+
- `skipped_skills`: considered but not loaded
|
|
89
|
+
|
|
90
|
+
## Context Budget Block (Required, Estimated)
|
|
91
|
+
|
|
92
|
+
Immediately after the Skill Log block, publish estimated budget fields:
|
|
93
|
+
|
|
94
|
+
- `full_catalog_est_tokens`
|
|
95
|
+
- `loaded_est_tokens`
|
|
96
|
+
- `estimated_savings_tokens`
|
|
97
|
+
- `estimated_savings_percent`
|
|
98
|
+
|
|
99
|
+
Mark all context/token values as deterministic estimates (not provider metering).
|
|
100
|
+
|
|
75
101
|
### Smart Skill Selection (Adaptive)
|
|
76
102
|
|
|
77
103
|
Use an adaptive load policy to control context size:
|
|
@@ -89,6 +115,8 @@ Use an adaptive load policy to control context size:
|
|
|
89
115
|
4. If a mapped skill is missing, continue with best fallback and state it.
|
|
90
116
|
5. Keep user-visible decision logs concise: selected skill(s) and one-line rationale.
|
|
91
117
|
|
|
118
|
+
After the skill log is complete, append the Context Budget block in the same response/update.
|
|
119
|
+
|
|
92
120
|
## 7) Socratic Gate (Before Complex Work)
|
|
93
121
|
|
|
94
122
|
Before multi-file or architecture-impacting changes, ask targeted questions when requirements are unclear:
|
|
@@ -109,7 +137,13 @@ Before multi-file or architecture-impacting changes, ask targeted questions when
|
|
|
109
137
|
Use these commands to keep this setup healthy:
|
|
110
138
|
|
|
111
139
|
- Install/update bundle:
|
|
112
|
-
`cbx workflows install --platform copilot --bundle agent-environment-setup --scope global --overwrite`
|
|
140
|
+
`cbx workflows install --platform copilot --bundle agent-environment-setup --scope global --overwrite --postman --stitch --mcp-runtime docker --mcp-fallback local --mcp-tool-sync`
|
|
141
|
+
- Start MCP Docker runtime:
|
|
142
|
+
`cbx mcp runtime up --scope global --name cbx-mcp --port 3310 --replace`
|
|
143
|
+
- Check MCP Docker runtime:
|
|
144
|
+
`cbx mcp runtime status --scope global --name cbx-mcp`
|
|
145
|
+
- Stop MCP Docker runtime:
|
|
146
|
+
`cbx mcp runtime down --name cbx-mcp`
|
|
113
147
|
- Rebuild managed routing block:
|
|
114
148
|
`cbx workflows sync-rules --platform copilot --scope project`
|
|
115
149
|
- Diagnose setup issues:
|
package/workflows/workflows/agent-environment-setup/platforms/copilot/rules/copilot-instructions.md
CHANGED
|
@@ -72,6 +72,32 @@ When authoring custom Copilot assets, keep frontmatter schema compatible:
|
|
|
72
72
|
|
|
73
73
|
## 6) Skill Loading Policy
|
|
74
74
|
|
|
75
|
+
## MCP-first Skill Discovery Order (Required)
|
|
76
|
+
|
|
77
|
+
1. Use `skill_search` first to narrow candidate skills.
|
|
78
|
+
2. Use `skill_browse_category` second to inspect category-level candidates.
|
|
79
|
+
3. Use `skill_get` only for final selected skills that must be loaded.
|
|
80
|
+
4. Keep pointer-first flow; avoid loading full skill text prematurely.
|
|
81
|
+
|
|
82
|
+
## Skill Log Completion Block (Required)
|
|
83
|
+
|
|
84
|
+
After finishing skill selection/loading, publish:
|
|
85
|
+
|
|
86
|
+
- `selected_skills`: skill IDs selected for the task
|
|
87
|
+
- `loaded_skills`: skill IDs loaded via `skill_get`
|
|
88
|
+
- `skipped_skills`: considered but not loaded
|
|
89
|
+
|
|
90
|
+
## Context Budget Block (Required, Estimated)
|
|
91
|
+
|
|
92
|
+
Immediately after the Skill Log block, publish estimated budget fields:
|
|
93
|
+
|
|
94
|
+
- `full_catalog_est_tokens`
|
|
95
|
+
- `loaded_est_tokens`
|
|
96
|
+
- `estimated_savings_tokens`
|
|
97
|
+
- `estimated_savings_percent`
|
|
98
|
+
|
|
99
|
+
Mark all context/token values as deterministic estimates (not provider metering).
|
|
100
|
+
|
|
75
101
|
### Smart Skill Selection (TIER 0)
|
|
76
102
|
|
|
77
103
|
Before starting ANY task, the agent MUST:
|
|
@@ -88,6 +114,8 @@ Before starting ANY task, the agent MUST:
|
|
|
88
114
|
3. Keep context lean; avoid loading unrelated skill documents.
|
|
89
115
|
4. If a mapped skill is missing, continue with best fallback and state it.
|
|
90
116
|
|
|
117
|
+
After the skill log is complete, append the Context Budget block in the same response/update.
|
|
118
|
+
|
|
91
119
|
## 7) Socratic Gate (Before Complex Work)
|
|
92
120
|
|
|
93
121
|
Before multi-file or architecture-impacting changes, ask targeted questions when requirements are unclear:
|
|
@@ -108,7 +136,13 @@ Before multi-file or architecture-impacting changes, ask targeted questions when
|
|
|
108
136
|
Use these commands to keep this setup healthy:
|
|
109
137
|
|
|
110
138
|
- Install/update bundle:
|
|
111
|
-
`cbx workflows install --platform copilot --bundle agent-environment-setup --scope global --overwrite`
|
|
139
|
+
`cbx workflows install --platform copilot --bundle agent-environment-setup --scope global --overwrite --postman --stitch --mcp-runtime docker --mcp-fallback local --mcp-tool-sync`
|
|
140
|
+
- Start MCP Docker runtime:
|
|
141
|
+
`cbx mcp runtime up --scope global --name cbx-mcp --port 3310 --replace`
|
|
142
|
+
- Check MCP Docker runtime:
|
|
143
|
+
`cbx mcp runtime status --scope global --name cbx-mcp`
|
|
144
|
+
- Stop MCP Docker runtime:
|
|
145
|
+
`cbx mcp runtime down --name cbx-mcp`
|
|
112
146
|
- Rebuild managed routing block:
|
|
113
147
|
`cbx workflows sync-rules --platform copilot --scope project`
|
|
114
148
|
- Diagnose setup issues:
|
|
@@ -32,11 +32,39 @@ Before starting ANY task, the agent MUST:
|
|
|
32
32
|
|
|
33
33
|
## 3) Skill Loading Policy
|
|
34
34
|
|
|
35
|
+
## MCP-first Skill Discovery Order (Required)
|
|
36
|
+
|
|
37
|
+
1. Use `skill_search` first to narrow candidate skills.
|
|
38
|
+
2. Use `skill_browse_category` second to inspect category-level candidates.
|
|
39
|
+
3. Use `skill_get` only for final selected skills that must be loaded.
|
|
40
|
+
4. Keep pointer-first flow; avoid loading full skill text prematurely.
|
|
41
|
+
|
|
42
|
+
## Skill Log Completion Block (Required)
|
|
43
|
+
|
|
44
|
+
After finishing skill selection/loading, publish:
|
|
45
|
+
|
|
46
|
+
- `selected_skills`: skill IDs selected for the task
|
|
47
|
+
- `loaded_skills`: skill IDs loaded via `skill_get`
|
|
48
|
+
- `skipped_skills`: considered but not loaded
|
|
49
|
+
|
|
50
|
+
## Context Budget Block (Required, Estimated)
|
|
51
|
+
|
|
52
|
+
Immediately after the Skill Log block, publish estimated budget fields:
|
|
53
|
+
|
|
54
|
+
- `full_catalog_est_tokens`
|
|
55
|
+
- `loaded_est_tokens`
|
|
56
|
+
- `estimated_savings_tokens`
|
|
57
|
+
- `estimated_savings_percent`
|
|
58
|
+
|
|
59
|
+
Mark all context/token values as deterministic estimates (not provider metering).
|
|
60
|
+
|
|
35
61
|
1. Load only skills needed for the active request.
|
|
36
62
|
2. Prefer progressive disclosure: start from `SKILL.md`, then specific sections.
|
|
37
63
|
3. Keep context lean; avoid loading unrelated skill documents.
|
|
38
64
|
4. If a mapped skill is missing, continue with best fallback and state it.
|
|
39
65
|
|
|
66
|
+
After the skill log is complete, append the Context Budget block in the same response/update.
|
|
67
|
+
|
|
40
68
|
## 4) Request Classifier
|
|
41
69
|
|
|
42
70
|
1. Question/explanation requests: answer directly.
|