@squadrules/mcp 5.10.1 → 5.12.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.
- package/README.md +15 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/embed-docs/mem/README.md +34 -37
- package/dist/embed-docs/mem/adapter-migration.md +31 -40
- package/dist/embed-docs/mem/author-adapter.md +91 -229
- package/dist/embed-docs/mem/bulk-insert-adapters-via-cli.md +28 -44
- package/dist/embed-docs/mem/challenge-type-guide.md +89 -205
- package/dist/embed-docs/mem/critic-loop-guide.md +10 -8
- package/dist/embed-docs/mem/critic-loop.md +20 -41
- package/dist/embed-docs/mem/protocol-linking-guide.md +36 -81
- package/dist/embed-docs/mem/refine-search.md +10 -33
- package/dist/resources/embedded-mcp-resources.d.ts +0 -4
- package/dist/resources/embedded-mcp-resources.d.ts.map +1 -1
- package/dist/resources/embedded-mcp-resources.js +10 -14
- package/dist/resources/embedded-mcp-resources.js.map +1 -1
- package/dist/resources/mem-resources-boot.d.ts.map +1 -1
- package/dist/resources/mem-resources-boot.js +6 -1
- package/dist/resources/mem-resources-boot.js.map +1 -1
- package/dist/runtime/boot-local-runtime.d.ts.map +1 -1
- package/dist/runtime/boot-local-runtime.js +9 -0
- package/dist/runtime/boot-local-runtime.js.map +1 -1
- package/dist/services/forward-runtime-store.d.ts +1 -5
- package/dist/services/forward-runtime-store.d.ts.map +1 -1
- package/dist/services/forward-runtime-store.js +1 -35
- package/dist/services/forward-runtime-store.js.map +1 -1
- package/dist/services/memory/validate-protocol-structure.d.ts.map +1 -1
- package/dist/services/memory/validate-protocol-structure.js +73 -4
- package/dist/services/memory/validate-protocol-structure.js.map +1 -1
- package/dist/services/qdrant/memory-retrieval.d.ts.map +1 -1
- package/dist/services/qdrant/memory-retrieval.js +1 -2
- package/dist/services/qdrant/memory-retrieval.js.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-engine.d.ts +7 -0
- package/dist/services/vector-store/lancedb/lance-records-engine.d.ts.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-engine.js +30 -1
- package/dist/services/vector-store/lancedb/lance-records-engine.js.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-mutations.d.ts.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-mutations.js +4 -1
- package/dist/services/vector-store/lancedb/lance-records-mutations.js.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-reads.d.ts.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-reads.js +1 -2
- package/dist/services/vector-store/lancedb/lance-records-reads.js.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-search.d.ts.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-search.js +8 -4
- package/dist/services/vector-store/lancedb/lance-records-search.js.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-write-artifact.d.ts.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-write-artifact.js +3 -1
- package/dist/services/vector-store/lancedb/lance-records-write-artifact.js.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-writes.d.ts.map +1 -1
- package/dist/services/vector-store/lancedb/lance-records-writes.js +6 -4
- package/dist/services/vector-store/lancedb/lance-records-writes.js.map +1 -1
- package/dist/services/vector-store/lancedb/lance-store-metadata.d.ts +21 -0
- package/dist/services/vector-store/lancedb/lance-store-metadata.d.ts.map +1 -0
- package/dist/services/vector-store/lancedb/lance-store-metadata.js +69 -0
- package/dist/services/vector-store/lancedb/lance-store-metadata.js.map +1 -0
- package/dist/stdio/stdio-banner.d.ts.map +1 -1
- package/dist/stdio/stdio-banner.js +1 -3
- package/dist/stdio/stdio-banner.js.map +1 -1
- package/dist/tools/export.d.ts.map +1 -1
- package/dist/tools/export.js +39 -0
- package/dist/tools/export.js.map +1 -1
- package/dist/tools/export_schema.d.ts +12 -0
- package/dist/tools/export_schema.d.ts.map +1 -1
- package/dist/tools/export_schema.js +11 -2
- package/dist/tools/export_schema.js.map +1 -1
- package/dist/tools/forward-trace.d.ts +1 -4
- package/dist/tools/forward-trace.d.ts.map +1 -1
- package/dist/tools/forward-trace.js +1 -111
- package/dist/tools/forward-trace.js.map +1 -1
- package/dist/tools/forward-view.d.ts +0 -1
- package/dist/tools/forward-view.d.ts.map +1 -1
- package/dist/tools/forward-view.js +4 -44
- package/dist/tools/forward-view.js.map +1 -1
- package/dist/tools/forward.d.ts.map +1 -1
- package/dist/tools/forward.js +1 -4
- package/dist/tools/forward.js.map +1 -1
- package/dist/tools/forward_schema.d.ts +0 -46
- package/dist/tools/forward_schema.d.ts.map +1 -1
- package/dist/tools/forward_schema.js +7 -32
- package/dist/tools/forward_schema.js.map +1 -1
- package/dist/tools/next-pow-challenge-shape.d.ts.map +1 -1
- package/dist/tools/next-pow-challenge-shape.js +0 -7
- package/dist/tools/next-pow-challenge-shape.js.map +1 -1
- package/dist/tools/next-pow-helpers.d.ts.map +1 -1
- package/dist/tools/next-pow-helpers.js +0 -3
- package/dist/tools/next-pow-helpers.js.map +1 -1
- package/dist/tools/next_schema.d.ts +4 -4
- package/dist/tools/next_schema.js +2 -2
- package/dist/tools/next_schema.js.map +1 -1
- package/dist/tools/search_output.d.ts.map +1 -1
- package/dist/tools/search_output.js +0 -5
- package/dist/tools/search_output.js.map +1 -1
- package/dist/tools/shell-challenge-invocation.d.ts +8 -2
- package/dist/tools/shell-challenge-invocation.d.ts.map +1 -1
- package/dist/tools/shell-challenge-invocation.js +18 -7
- package/dist/tools/shell-challenge-invocation.js.map +1 -1
- package/dist/tools/squadrules-challenge-display.d.ts.map +1 -1
- package/dist/tools/squadrules-challenge-display.js +7 -9
- package/dist/tools/squadrules-challenge-display.js.map +1 -1
- package/dist/tools/tool-registry.d.ts +23 -22
- package/dist/tools/tool-registry.d.ts.map +1 -1
- package/dist/tools/train.d.ts.map +1 -1
- package/dist/tools/train.js +31 -0
- package/dist/tools/train.js.map +1 -1
- package/dist/tools/train_schema.d.ts +11 -0
- package/dist/tools/train_schema.d.ts.map +1 -1
- package/dist/tools/train_schema.js +13 -4
- package/dist/tools/train_schema.js.map +1 -1
- package/dist/types/memory.d.ts +4 -18
- package/dist/types/memory.d.ts.map +1 -1
- package/dist/ui/assets/{AccountPage-BpPby8tL.js → AccountPage-rmFJddfQ.js} +1 -1
- package/dist/ui/assets/{ProtocolDetailPage-DFe_JOr3.js → ProtocolDetailPage-kPGgNobg.js} +1 -1
- package/dist/ui/assets/{ProtocolEditPage-HAcAGXw7.js → ProtocolEditPage-IvFbUiUS.js} +2 -2
- package/dist/ui/assets/RunGuidedPage-Db_CQ-9q.js +1 -0
- package/dist/ui/assets/{SkillBundlePage-CiMQN0nf.js → SkillBundlePage-DV9CXjfI.js} +1 -1
- package/dist/ui/assets/{export-skill-zip-D8iQY1Dl.js → export-skill-zip-seCWjJSV.js} +1 -1
- package/dist/ui/assets/{index-cB_UoTxa.css → index-BGjXjHf7.css} +1 -1
- package/dist/ui/assets/{index-DLLKkKKa.js → index-D_BmxEln.js} +3 -3
- package/dist/ui/index.html +2 -2
- package/dist/utils/adapter-alias.d.ts +1 -11
- package/dist/utils/adapter-alias.d.ts.map +1 -1
- package/dist/utils/adapter-alias.js +2 -20
- package/dist/utils/adapter-alias.js.map +1 -1
- package/dist/utils/directory-access.d.ts +26 -0
- package/dist/utils/directory-access.d.ts.map +1 -0
- package/dist/utils/directory-access.js +153 -0
- package/dist/utils/directory-access.js.map +1 -0
- package/package.json +1 -3
- package/dist/embed-docs/mem/create-new-protocol.md +0 -44
- package/dist/embed-docs/mem/phase-critic-guide.md +0 -42
- package/dist/embed-docs/mem/phase-critic.md +0 -46
- package/dist/embed-docs/mem/skill-format-guide.md +0 -280
- package/dist/ui/assets/RunGuidedPage-Bewi7Wsx.js +0 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Maximum directory depth for batch operations. */
|
|
2
|
+
export declare const MAX_DIRECTORY_DEPTH = 8;
|
|
3
|
+
/** Maximum adapter count per batch directory operation. */
|
|
4
|
+
export declare const MAX_BATCH_ADAPTERS = 256;
|
|
5
|
+
/**
|
|
6
|
+
* Resolve and validate a directory path for MCP batch operations.
|
|
7
|
+
*
|
|
8
|
+
* Security checks (in order):
|
|
9
|
+
* 1. SIMPLE/stdio-only gate — rejects when transport is HTTP or auth is enabled.
|
|
10
|
+
* 2. Absolute path required.
|
|
11
|
+
* 3. No `..` segments after splitting.
|
|
12
|
+
* 4. Symlink resolution via `fs.realpathSync`.
|
|
13
|
+
* 5. Allowlist prefix check (env-configured or default fallback).
|
|
14
|
+
* 6. Must be an existing directory.
|
|
15
|
+
* 7. Depth cap.
|
|
16
|
+
*
|
|
17
|
+
* @throws Error with a clear message when any check fails.
|
|
18
|
+
* @returns The resolved absolute real path.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveAndValidateDirectory(directory: string, operation: 'export' | 'train'): string;
|
|
21
|
+
/**
|
|
22
|
+
* Scan a directory for `.md` files, optionally recursively.
|
|
23
|
+
* Returns absolute paths sorted alphabetically.
|
|
24
|
+
*/
|
|
25
|
+
export declare function scanMarkdownFiles(directory: string, recursive: boolean): string[];
|
|
26
|
+
//# sourceMappingURL=directory-access.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory-access.d.ts","sourceRoot":"","sources":["../../src/utils/directory-access.ts"],"names":[],"mappings":"AAWA,oDAAoD;AACpD,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,2DAA2D;AAC3D,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,QAAQ,GAAG,OAAO,GAC5B,MAAM,CA2FR;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,OAAO,GACjB,MAAM,EAAE,CAsBV"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security-hardened directory access for MCP `directory` parameter.
|
|
3
|
+
*
|
|
4
|
+
* Only accepted in SIMPLE/stdio mode. Rejects symlink escapes, path traversal,
|
|
5
|
+
* and paths outside the configured allowlist. Every access is audit-logged.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { TRANSPORT_TYPE, AUTH_ENABLED } from '../config/runtime-mode.js';
|
|
10
|
+
import { structuredLogger } from './structured-logger.js';
|
|
11
|
+
/** Maximum directory depth for batch operations. */
|
|
12
|
+
export const MAX_DIRECTORY_DEPTH = 8;
|
|
13
|
+
/** Maximum adapter count per batch directory operation. */
|
|
14
|
+
export const MAX_BATCH_ADAPTERS = 256;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve and validate a directory path for MCP batch operations.
|
|
17
|
+
*
|
|
18
|
+
* Security checks (in order):
|
|
19
|
+
* 1. SIMPLE/stdio-only gate — rejects when transport is HTTP or auth is enabled.
|
|
20
|
+
* 2. Absolute path required.
|
|
21
|
+
* 3. No `..` segments after splitting.
|
|
22
|
+
* 4. Symlink resolution via `fs.realpathSync`.
|
|
23
|
+
* 5. Allowlist prefix check (env-configured or default fallback).
|
|
24
|
+
* 6. Must be an existing directory.
|
|
25
|
+
* 7. Depth cap.
|
|
26
|
+
*
|
|
27
|
+
* @throws Error with a clear message when any check fails.
|
|
28
|
+
* @returns The resolved absolute real path.
|
|
29
|
+
*/
|
|
30
|
+
export function resolveAndValidateDirectory(directory, operation) {
|
|
31
|
+
// 1. SIMPLE/stdio-only gate
|
|
32
|
+
if (TRANSPORT_TYPE !== 'stdio' || AUTH_ENABLED) {
|
|
33
|
+
throw new Error(`The "directory" parameter is only available in SIMPLE/stdio mode. ` +
|
|
34
|
+
`Current transport: ${TRANSPORT_TYPE}, auth: ${AUTH_ENABLED ? 'enabled' : 'disabled'}. ` +
|
|
35
|
+
`Remove the "directory" parameter and use inline content/URI arguments instead.`);
|
|
36
|
+
}
|
|
37
|
+
const trimmed = directory.trim();
|
|
38
|
+
if (!trimmed) {
|
|
39
|
+
throw new Error('"directory" must be a non-empty absolute path.');
|
|
40
|
+
}
|
|
41
|
+
// 2. Absolute path required
|
|
42
|
+
if (!path.isAbsolute(trimmed)) {
|
|
43
|
+
throw new Error(`"directory" must be an absolute path (got: "${trimmed}").`);
|
|
44
|
+
}
|
|
45
|
+
// 3. No .. segments
|
|
46
|
+
const segments = trimmed.split(path.sep).filter(Boolean);
|
|
47
|
+
if (segments.includes('..')) {
|
|
48
|
+
throw new Error(`"directory" must not contain ".." path segments.`);
|
|
49
|
+
}
|
|
50
|
+
// 4. Symlink resolution (only if path exists)
|
|
51
|
+
let resolved;
|
|
52
|
+
try {
|
|
53
|
+
resolved = fs.realpathSync(trimmed);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Path doesn't exist yet — for export, the directory may need to be created.
|
|
57
|
+
// Resolve the parent to check for symlink escapes on the existing portion.
|
|
58
|
+
const parent = path.dirname(trimmed);
|
|
59
|
+
try {
|
|
60
|
+
const realParent = fs.realpathSync(parent);
|
|
61
|
+
resolved = path.join(realParent, path.basename(trimmed));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
throw new Error(`"directory" parent path does not exist: "${parent}".`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// 5. Allowlist prefix check
|
|
68
|
+
const allowlistEnvKey = operation === 'export'
|
|
69
|
+
? 'SQUADRULES_ALLOWED_EXPORT_DIRS'
|
|
70
|
+
: 'SQUADRULES_ALLOWED_TRAIN_DIRS';
|
|
71
|
+
const allowlistRaw = process.env[allowlistEnvKey];
|
|
72
|
+
const allowedPrefixes = allowlistRaw
|
|
73
|
+
? allowlistRaw.split(',').map((p) => p.trim()).filter(Boolean)
|
|
74
|
+
: getDefaultAllowedPrefixes();
|
|
75
|
+
const permitted = allowedPrefixes.some((prefix) => {
|
|
76
|
+
const realPrefix = safeRealpath(prefix);
|
|
77
|
+
const checkPrefix = realPrefix ?? prefix;
|
|
78
|
+
return resolved === checkPrefix || resolved.startsWith(checkPrefix + path.sep);
|
|
79
|
+
});
|
|
80
|
+
if (!permitted) {
|
|
81
|
+
throw new Error(`"directory" path "${resolved}" is not within the allowed directories. ` +
|
|
82
|
+
`Set ${allowlistEnvKey} to a comma-separated list of allowed absolute prefixes, ` +
|
|
83
|
+
`or use a path under the default locations.`);
|
|
84
|
+
}
|
|
85
|
+
// 6. Must be a directory (if it exists)
|
|
86
|
+
try {
|
|
87
|
+
const stat = fs.statSync(resolved);
|
|
88
|
+
if (!stat.isDirectory()) {
|
|
89
|
+
throw new Error(`"directory" path is not a directory: "${resolved}".`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (error instanceof Error && error.message.startsWith('"directory" path is not')) {
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
// Stat failed but realpath succeeded — directory may not exist yet (export case)
|
|
97
|
+
}
|
|
98
|
+
// 7. Depth cap
|
|
99
|
+
const depth = resolved.split(path.sep).filter(Boolean).length;
|
|
100
|
+
if (depth > MAX_DIRECTORY_DEPTH) {
|
|
101
|
+
throw new Error(`"directory" depth ${depth} exceeds maximum ${MAX_DIRECTORY_DEPTH}.`);
|
|
102
|
+
}
|
|
103
|
+
// Audit log
|
|
104
|
+
structuredLogger.getPinoLogger().info({ event: 'directory_access', operation, resolved_path: resolved, allowlist: allowedPrefixes }, `directory access: ${operation} → ${resolved}`);
|
|
105
|
+
return resolved;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Scan a directory for `.md` files, optionally recursively.
|
|
109
|
+
* Returns absolute paths sorted alphabetically.
|
|
110
|
+
*/
|
|
111
|
+
export function scanMarkdownFiles(directory, recursive) {
|
|
112
|
+
const results = [];
|
|
113
|
+
function walk(dir, currentDepth) {
|
|
114
|
+
if (currentDepth > MAX_DIRECTORY_DEPTH)
|
|
115
|
+
return;
|
|
116
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
117
|
+
for (const entry of entries) {
|
|
118
|
+
if (entry.name.startsWith('.'))
|
|
119
|
+
continue;
|
|
120
|
+
const fullPath = path.join(dir, entry.name);
|
|
121
|
+
if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
122
|
+
results.push(fullPath);
|
|
123
|
+
if (results.length > MAX_BATCH_ADAPTERS) {
|
|
124
|
+
throw new Error(`Directory contains more than ${MAX_BATCH_ADAPTERS} .md files.`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else if (entry.isDirectory() && recursive) {
|
|
128
|
+
walk(fullPath, currentDepth + 1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
walk(directory, 0);
|
|
133
|
+
return results.sort();
|
|
134
|
+
}
|
|
135
|
+
function getDefaultAllowedPrefixes() {
|
|
136
|
+
const prefixes = [];
|
|
137
|
+
const xdgConfig = process.env['XDG_CONFIG_HOME'] || path.join(process.env['HOME'] || '', '.config');
|
|
138
|
+
if (xdgConfig) {
|
|
139
|
+
prefixes.push(path.join(xdgConfig, 'squadrules'));
|
|
140
|
+
}
|
|
141
|
+
// Allow CWD project tree
|
|
142
|
+
prefixes.push(process.cwd());
|
|
143
|
+
return prefixes;
|
|
144
|
+
}
|
|
145
|
+
function safeRealpath(p) {
|
|
146
|
+
try {
|
|
147
|
+
return fs.realpathSync(p);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=directory-access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory-access.js","sourceRoot":"","sources":["../../src/utils/directory-access.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squadrules/mcp",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.12.0",
|
|
4
4
|
"description": "SquadRules MCP server for agent automation: persistent memory and deterministic workflow execution for AI agents and chats",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,9 +50,7 @@
|
|
|
50
50
|
"test:audit-fix-workflow": "bash tests/scripts/npm-audit-fix.test.sh",
|
|
51
51
|
"test:automation": "node --test tests/scripts/*.test.mjs",
|
|
52
52
|
"lint:workflows": "node scripts/lint-workflows.mjs",
|
|
53
|
-
"lint:renovate": "node scripts/ci-renovate.mjs validate",
|
|
54
53
|
"ci:controller": "node scripts/ci-automation.mjs",
|
|
55
|
-
"ci:renovate": "node scripts/ci-renovate.mjs",
|
|
56
54
|
"ci:audit": "node scripts/ci-audit.mjs",
|
|
57
55
|
"ci:health": "node scripts/ci-health.mjs",
|
|
58
56
|
"test:spec-parity": "NODE_OPTIONS=--experimental-vm-modules jest --runInBand --testPathPatterns tests/unit/spec-parity.test.ts",
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
version: "5.10.1"
|
|
3
|
-
slug: create-new-protocol
|
|
4
|
-
title: Create New Protocol (Redirect to Author Adapter)
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Create New Protocol (Redirect to Author Adapter)
|
|
8
|
-
|
|
9
|
-
`create-new-protocol` was renamed to **`author-adapter`** in 5.6.0. This adapter
|
|
10
|
-
is a redirect tombstone: it exists only so a stored adapter that still chains to
|
|
11
|
-
`squadrules://adapter/create-new-protocol` resolves and is sent to the replacement
|
|
12
|
-
instead of dangling. It carries no authoring logic. Do not author new adapters
|
|
13
|
-
against this slug — use `squadrules://adapter/author-adapter`.
|
|
14
|
-
|
|
15
|
-
## Activation Patterns
|
|
16
|
-
|
|
17
|
-
**Typically invoked by:** a stored adapter that still forwards to the retired
|
|
18
|
-
`create-new-protocol` slug.
|
|
19
|
-
|
|
20
|
-
**Can be invoked directly when agent needs:**
|
|
21
|
-
- "create new protocol" — the retired name for the author adapter
|
|
22
|
-
|
|
23
|
-
**Must Never:**
|
|
24
|
-
- Perform any authoring itself; this tombstone only redirects.
|
|
25
|
-
- Be used as the target of a new adapter chain.
|
|
26
|
-
|
|
27
|
-
**Must Always:**
|
|
28
|
-
- Send the caller to `squadrules://adapter/author-adapter`, forwarding the same
|
|
29
|
-
context it received.
|
|
30
|
-
|
|
31
|
-
## Redirect
|
|
32
|
-
|
|
33
|
-
Forward to the replacement and continue the run there. `author-adapter` is the
|
|
34
|
-
create / review / update lifecycle that replaced `create-new-protocol`; its
|
|
35
|
-
integration rules live in the adapter itself. See ADR 0016 (the rename).
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{"contract":{"type":"mcp","mcp":{"tool_name":"forward","arguments":{"uri":"squadrules://adapter/author-adapter"}},"required":true}}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Reward Signal
|
|
42
|
-
|
|
43
|
-
The caller reached `squadrules://adapter/author-adapter`, so the retired slug
|
|
44
|
-
resolved and redirected instead of dangling.
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
version: "5.10.1"
|
|
3
|
-
slug: phase-critic-guide
|
|
4
|
-
title: Phase Critic Guide (Redirect to Critic Loop Guide)
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Phase Critic Guide (Redirect to Critic Loop Guide)
|
|
8
|
-
|
|
9
|
-
`phase-critic-guide` was renamed to **`critic-loop-guide`** in 5.4.0. This is a
|
|
10
|
-
redirect tombstone kept so the retired slug still resolves. It carries no rules
|
|
11
|
-
of its own — read **`squadrules://adapter/critic-loop-guide`** for the current
|
|
12
|
-
critic-loop integration, the solution-check-vs-critic decision table, and the
|
|
13
|
-
proof-splitting rules. Do not author against this slug.
|
|
14
|
-
|
|
15
|
-
## Activation Patterns
|
|
16
|
-
|
|
17
|
-
**Typically invoked by:** an agent or adapter that still references the retired
|
|
18
|
-
`phase-critic-guide` slug.
|
|
19
|
-
|
|
20
|
-
**Can be invoked directly when agent needs:**
|
|
21
|
-
- "phase critic guide" — the retired name for the critic-loop guide
|
|
22
|
-
|
|
23
|
-
**Must Never:**
|
|
24
|
-
- Restate the integration rules here; they live in `critic-loop-guide`.
|
|
25
|
-
|
|
26
|
-
**Must Always:**
|
|
27
|
-
- Point the reader to `squadrules://adapter/critic-loop-guide`.
|
|
28
|
-
|
|
29
|
-
## Redirect
|
|
30
|
-
|
|
31
|
-
`critic-loop-guide` is the single home for critic-loop integration and mutation
|
|
32
|
-
gate placement. Activate `squadrules://adapter/critic-loop-guide` and read it
|
|
33
|
-
there. See ADR 0010 (the rename) and ADR 0012 (why the tombstone is kept).
|
|
34
|
-
|
|
35
|
-
```json
|
|
36
|
-
{"contract":{"type":"comment","comment":{"min_length":40},"required":true}}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Reward Signal
|
|
40
|
-
|
|
41
|
-
The reader was directed to `squadrules://adapter/critic-loop-guide`, so the
|
|
42
|
-
retired slug resolved instead of dangling.
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
version: "5.10.1"
|
|
3
|
-
slug: phase-critic
|
|
4
|
-
title: Phase Critic (Redirect to Critic Loop)
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Phase Critic (Redirect to Critic Loop)
|
|
8
|
-
|
|
9
|
-
`phase-critic` was renamed to **`critic-loop`** in 5.4.0. This adapter is a
|
|
10
|
-
redirect tombstone: it exists only so a stored adapter that still chains to
|
|
11
|
-
`squadrules://adapter/phase-critic` resolves and is sent to the replacement
|
|
12
|
-
instead of dangling. It carries no review logic. Do not author new adapters
|
|
13
|
-
against this slug — use `squadrules://adapter/critic-loop`.
|
|
14
|
-
|
|
15
|
-
## Activation Patterns
|
|
16
|
-
|
|
17
|
-
**Typically invoked by:** a stored adapter that still forwards to the retired
|
|
18
|
-
`phase-critic` slug.
|
|
19
|
-
|
|
20
|
-
**Can be invoked directly when agent needs:**
|
|
21
|
-
- "phase critic" — the retired name for the critic loop
|
|
22
|
-
|
|
23
|
-
**Must Never:**
|
|
24
|
-
- Perform a review itself; this tombstone only redirects.
|
|
25
|
-
- Be used as the target of a new adapter chain.
|
|
26
|
-
|
|
27
|
-
**Must Always:**
|
|
28
|
-
- Send the caller to `squadrules://adapter/critic-loop`, forwarding the same
|
|
29
|
-
`work` submission (or the older-spelling `input_file`), `requirements`, and
|
|
30
|
-
`context` it received.
|
|
31
|
-
|
|
32
|
-
## Redirect
|
|
33
|
-
|
|
34
|
-
Forward to the replacement and continue the run there. `critic-loop` is the
|
|
35
|
-
bounded, requirement-aware review that replaced `phase-critic`; its integration
|
|
36
|
-
rules live in `critic-loop-guide`. See ADR 0010 (the rename) and ADR 0012 (why
|
|
37
|
-
the tombstone is kept).
|
|
38
|
-
|
|
39
|
-
```json
|
|
40
|
-
{"contract":{"type":"mcp","mcp":{"tool_name":"forward","arguments":{"uri":"squadrules://adapter/critic-loop"}},"required":true}}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Reward Signal
|
|
44
|
-
|
|
45
|
-
The caller reached `squadrules://adapter/critic-loop`, so the retired slug
|
|
46
|
-
resolved and redirected instead of dangling.
|
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
version: "5.10.1"
|
|
3
|
-
slug: skill-format-guide
|
|
4
|
-
title: Skill Format and Local Authoring Guide
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# Skill Format and Local Authoring Guide
|
|
10
|
-
|
|
11
|
-
Decision rules for authoring SKILL.md files, choosing between local (git) and
|
|
12
|
-
server (SQUADRULES) storage, and quality gates for skill content. Fetches the
|
|
13
|
-
current Agent Skills format spec (Context7 or agentskills.io) as the
|
|
14
|
-
authoritative generic format, then layers SQUADRULES customizations on top. Loaded
|
|
15
|
-
by protocol-authoring agents during drafting and review when the output format
|
|
16
|
-
is `skill`.
|
|
17
|
-
|
|
18
|
-
## Activation Patterns
|
|
19
|
-
|
|
20
|
-
**Typically invoked by:** `author-adapter` and
|
|
21
|
-
`critic-loop`.
|
|
22
|
-
|
|
23
|
-
**Can be invoked directly when agent needs:**
|
|
24
|
-
- "SKILL.md format reference" / "how to write a skill"
|
|
25
|
-
- "latest SKILL.md spec" / "current agentskills format"
|
|
26
|
-
- "skill vs adapter" / "local skill or SQUADRULES adapter"
|
|
27
|
-
- "skill quality gates" / "SKILL.md structure"
|
|
28
|
-
- "project-level skill" / "where to put a skill"
|
|
29
|
-
|
|
30
|
-
**Trigger pattern:** **skill** + (format | structure | guide | quality | local | spec).
|
|
31
|
-
|
|
32
|
-
**Must Never:**
|
|
33
|
-
- Be used as an execution protocol.
|
|
34
|
-
- Recommend storing a skill in both git AND SQUADRULES server simultaneously.
|
|
35
|
-
- Confuse SKILL.md (agent instruction file) with protocol markdown (adapter).
|
|
36
|
-
- Hardcode the generic SKILL.md format from memory when the current spec is
|
|
37
|
-
reachable via Context7 or agentskills.io.
|
|
38
|
-
|
|
39
|
-
**Must Always:**
|
|
40
|
-
- Be consulted before writing any SKILL.md file.
|
|
41
|
-
- Fetch the current Agent Skills spec before authoring or reviewing generic
|
|
42
|
-
format, and apply SQUADRULES customizations after it.
|
|
43
|
-
- Enforce single source of truth: each skill lives in exactly one place.
|
|
44
|
-
- Match storage location to the skill's scope and discoverability needs.
|
|
45
|
-
|
|
46
|
-
**Good trigger examples:**
|
|
47
|
-
- drafting a new skill and need format rules → load this
|
|
48
|
-
- reviewing a SKILL.md for quality → load this
|
|
49
|
-
- deciding local vs server for a skill → load this
|
|
50
|
-
|
|
51
|
-
**Bad trigger examples:**
|
|
52
|
-
- "which challenge type for this step?" → use `challenge-type-guide`
|
|
53
|
-
- "create a new protocol" → use `author-adapter`
|
|
54
|
-
|
|
55
|
-
## Storage Decision
|
|
56
|
-
|
|
57
|
-
Every skill has ONE home. Choose at authoring time. Never both.
|
|
58
|
-
|
|
59
|
-
| Scope | Storage | Discovery | Source of Truth |
|
|
60
|
-
|---|---|---|---|
|
|
61
|
-
| Project-specific (deploy, test, release) | Git: `.agents/skills/{name}/` or `.cursor/skills/{name}/` | IDE host scans description field | Git repo |
|
|
62
|
-
| Personal cross-project (universal) | SQUADRULES server via `train` | `activate` embedding search | SQUADRULES server |
|
|
63
|
-
| Team/group shared | SQUADRULES server (group space) | `activate` | SQUADRULES server |
|
|
64
|
-
|
|
65
|
-
### Decision Tree
|
|
66
|
-
|
|
67
|
-
```
|
|
68
|
-
Is this skill specific to ONE project's codebase?
|
|
69
|
-
├─ YES → Does it reference repo files, paths, or project-specific tools?
|
|
70
|
-
│ ├─ YES → LOCAL (git)
|
|
71
|
-
│ └─ NO → Could it help in other projects?
|
|
72
|
-
│ ├─ YES → SERVER (SQUADRULES)
|
|
73
|
-
│ └─ NO → LOCAL (git)
|
|
74
|
-
└─ NO → SERVER (SQUADRULES)
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Local Storage Paths
|
|
78
|
-
|
|
79
|
-
| Host | Path | Scope |
|
|
80
|
-
|---|---|---|
|
|
81
|
-
| Cursor IDE (project) | `.cursor/skills/{name}/SKILL.md` | Repo-scoped, git-controlled |
|
|
82
|
-
| Cursor IDE (personal) | `~/.cursor/skills/{name}/SKILL.md` | User-wide, all projects |
|
|
83
|
-
| Claude Code (project) | `.agents/skills/{name}/SKILL.md` | Repo-scoped, git-controlled |
|
|
84
|
-
| Claude Code (personal) | `~/.agents/skills/{name}/SKILL.md` | User-wide, all projects |
|
|
85
|
-
|
|
86
|
-
**Never** create skills in `~/.cursor/skills-cursor/` — reserved for system.
|
|
87
|
-
|
|
88
|
-
### Promotion and Demotion
|
|
89
|
-
|
|
90
|
-
**Local → Server (skill graduates to universal):**
|
|
91
|
-
1. Read existing SKILL.md
|
|
92
|
-
2. Optionally wrap in protocol structure (Activation Patterns, contracts)
|
|
93
|
-
3. `train` to SQUADRULES server
|
|
94
|
-
4. Delete local copy or mark deprecated
|
|
95
|
-
5. Git commit the deletion
|
|
96
|
-
|
|
97
|
-
**Server → Local (adapter becomes project-specific):**
|
|
98
|
-
1. `export` with `format: skill_zip` or `format: markdown`
|
|
99
|
-
2. Write to `.agents/skills/{slug}/SKILL.md`
|
|
100
|
-
3. Optionally `delete` from server
|
|
101
|
-
|
|
102
|
-
```json
|
|
103
|
-
{"contract":{"type":"comment","comment":{"min_length":30},"required":true}}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Fetch the Current Skill Format Spec
|
|
107
|
-
|
|
108
|
-
Do NOT rely on a frozen copy of the SKILL.md format. The Agent Skills format
|
|
109
|
-
evolves (new frontmatter fields, directory conventions, size guidance). Before
|
|
110
|
-
authoring or reviewing a SKILL.md, fetch the **current** specification and treat
|
|
111
|
-
it as authoritative for the generic format. The SQUADRULES customizations in the
|
|
112
|
-
sections *after* this one layer on top of that generic spec.
|
|
113
|
-
|
|
114
|
-
**Authoritative source (fetch fresh — do not guess):**
|
|
115
|
-
|
|
116
|
-
1. **Context7 (preferred):** query the Agent Skills docs library for the
|
|
117
|
-
SKILL.md format. Use one of these library IDs directly (skip
|
|
118
|
-
`resolve-library-id`):
|
|
119
|
-
- `/llmstxt/agentskills_io_llms-full_txt` — full spec text (best coverage)
|
|
120
|
-
- `/websites/agentskills_io` — the agentskills.io site docs
|
|
121
|
-
Example query: "SKILL.md frontmatter fields, directory structure, size limits".
|
|
122
|
-
2. **URL fallback:** if Context7 is unavailable or returns nothing usable,
|
|
123
|
-
fetch `https://agentskills.io/specification`. Use
|
|
124
|
-
`https://agentskills.io/llms.txt` as the documentation index to discover
|
|
125
|
-
related pages.
|
|
126
|
-
|
|
127
|
-
**What to extract from the fetched spec (do not hardcode from memory):**
|
|
128
|
-
- Required and optional YAML frontmatter fields and their constraints
|
|
129
|
-
(for example `name`, `description`, and any newer fields such as `license`,
|
|
130
|
-
`compatibility`, `metadata`, `allowed-tools`).
|
|
131
|
-
- Directory structure and conventional subdirectory names
|
|
132
|
-
(for example `scripts/`, `references/`, `assets/`).
|
|
133
|
-
- Body content recommendations and section guidance.
|
|
134
|
-
- Size / progressive-disclosure guidance (line and token targets).
|
|
135
|
-
- Any spec-provided validation tooling (for example `skills-ref validate`).
|
|
136
|
-
|
|
137
|
-
**Rules:**
|
|
138
|
-
- Apply the fetched spec's constraints exactly for the generic format.
|
|
139
|
-
- If the fetch fails on BOTH Context7 and the URL, STOP and tell the user the
|
|
140
|
-
spec is unreachable — do not fabricate field lists or limits from memory.
|
|
141
|
-
- Record which source and (if available) which version/date you fetched, so the
|
|
142
|
-
authoring decision is auditable.
|
|
143
|
-
|
|
144
|
-
```json
|
|
145
|
-
{"contract":{"type":"comment","comment":{"min_length":30},"required":true}}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## SQUADRULES Customizations (apply after the generic spec)
|
|
149
|
-
|
|
150
|
-
Everything below is SQUADRULES-specific and layers on top of the fetched Agent
|
|
151
|
-
Skills spec. When the generic spec and these rules disagree on generic format,
|
|
152
|
-
follow the spec; these rules add SQUADRULES storage, integrity, and routing
|
|
153
|
-
behavior the generic spec does not cover.
|
|
154
|
-
|
|
155
|
-
### SQUADRULES additions to structure
|
|
156
|
-
|
|
157
|
-
- **`SHA256SUMS`** — required for SQUADRULES-exported skill bundles (GNU
|
|
158
|
-
`sha256sum` format, paths relative to the skill dir). This is a SQUADRULES
|
|
159
|
-
integrity requirement, not part of the generic Agent Skills spec.
|
|
160
|
-
- **`disable-model-invocation`** — when the host supports it, SQUADRULES-authored
|
|
161
|
-
skills default this to `true` (explicit load only) unless the skill is meant
|
|
162
|
-
to auto-trigger. Only add fields the fetched spec actually recognizes.
|
|
163
|
-
- **Reference depth** — keep references one level deep (SKILL.md → reference
|
|
164
|
-
file, never deeper), consistent with the spec's progressive-disclosure model.
|
|
165
|
-
|
|
166
|
-
```json
|
|
167
|
-
{"contract":{"type":"comment","comment":{"min_length":30},"required":true}}
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
## Quality Gates
|
|
171
|
-
|
|
172
|
-
### Description Quality
|
|
173
|
-
|
|
174
|
-
The description is the primary discovery mechanism. It must:
|
|
175
|
-
|
|
176
|
-
1. Be written in **third person** (not "I can help" or "you can use")
|
|
177
|
-
2. State **WHAT** the skill does (specific capabilities)
|
|
178
|
-
3. State **WHEN** to use it (trigger scenarios, file patterns, keywords)
|
|
179
|
-
4. Include **trigger terms** that match real user language
|
|
180
|
-
5. Avoid vague words: "helps with", "assists", "various"
|
|
181
|
-
|
|
182
|
-
**Good:**
|
|
183
|
-
```yaml
|
|
184
|
-
description: >-
|
|
185
|
-
Validate and publish Confluence pages managed as local markdown via Mark CLI.
|
|
186
|
-
Use when the user asks to dry-run, validate, publish, or sync a Confluence
|
|
187
|
-
page, or when working with files under confluence/ that have Mark metadata.
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
**Bad:**
|
|
191
|
-
```yaml
|
|
192
|
-
description: Helps with Confluence stuff.
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Content Quality
|
|
196
|
-
|
|
197
|
-
| Check | Rule |
|
|
198
|
-
|---|---|
|
|
199
|
-
| Consistent terminology | One term per concept throughout |
|
|
200
|
-
| No time-sensitive info | No "before August 2025" conditions |
|
|
201
|
-
| Concrete examples | Real inputs/outputs, not abstract |
|
|
202
|
-
| Actionable instructions | Agent knows what to DO, not just what exists |
|
|
203
|
-
| Default tool choice | One recommended tool, escape hatch for alternatives |
|
|
204
|
-
| No Windows paths | Forward slashes only |
|
|
205
|
-
|
|
206
|
-
### Degree of Freedom
|
|
207
|
-
|
|
208
|
-
Match instruction specificity to the task's fragility:
|
|
209
|
-
|
|
210
|
-
| Level | When | Example |
|
|
211
|
-
|---|---|---|
|
|
212
|
-
| High (text guidelines) | Multiple valid approaches | Code review guidelines |
|
|
213
|
-
| Medium (templates/pseudocode) | Preferred pattern, acceptable variation | Report generation |
|
|
214
|
-
| Low (exact scripts) | Fragile operations, consistency critical | DB migrations |
|
|
215
|
-
|
|
216
|
-
```json
|
|
217
|
-
{"contract":{"type":"comment","comment":{"min_length":30},"required":true}}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## Finalisation Paths
|
|
221
|
-
|
|
222
|
-
### Path A: Local Write (project-level skill)
|
|
223
|
-
|
|
224
|
-
When `{target}=local`:
|
|
225
|
-
|
|
226
|
-
1. Determine output path from scope:
|
|
227
|
-
- Project Cursor: `.cursor/skills/{name}/SKILL.md`
|
|
228
|
-
- Project Claude: `.agents/skills/{name}/SKILL.md`
|
|
229
|
-
- Personal: `~/.cursor/skills/{name}/SKILL.md` or `~/.agents/skills/{name}/`
|
|
230
|
-
2. Create directory if needed
|
|
231
|
-
3. Write SKILL.md with frontmatter and body
|
|
232
|
-
4. Generate `SHA256SUMS` (GNU sha256sum format, paths relative to skill dir)
|
|
233
|
-
5. Write any reference files and scripts
|
|
234
|
-
6. Verify: `test -f "{path}/SKILL.md" && wc -l "{path}/SKILL.md"`
|
|
235
|
-
7. Report path and line count to user
|
|
236
|
-
|
|
237
|
-
Do NOT call `train`. The skill lives only in git.
|
|
238
|
-
|
|
239
|
-
### Path B: Server Train (SQUADRULES-routable adapter)
|
|
240
|
-
|
|
241
|
-
When `{target}=server`:
|
|
242
|
-
|
|
243
|
-
1. Wrap skill content in protocol markdown if needed:
|
|
244
|
-
- Add Activation Patterns (first H2)
|
|
245
|
-
- Add contract blocks per layer
|
|
246
|
-
- Add Reward Signal (last H2)
|
|
247
|
-
2. Call `train` with full markdown
|
|
248
|
-
3. Verify adapter URI returned
|
|
249
|
-
4. Report URI and slug to user
|
|
250
|
-
|
|
251
|
-
Do NOT write to local disk. The adapter lives only in SQUADRULES.
|
|
252
|
-
|
|
253
|
-
### Path C: Hybrid Authoring (skill that is also an adapter)
|
|
254
|
-
|
|
255
|
-
When `{target}=hybrid` (rare — use only when explicitly requested):
|
|
256
|
-
|
|
257
|
-
1. Author as a SQUADRULES protocol (Activation Patterns, contracts, Reward Signal)
|
|
258
|
-
2. `train` to server
|
|
259
|
-
3. `export` with `format: skill_zip` to produce local SKILL.md bundle
|
|
260
|
-
4. The exported SKILL.md is a **read-only derived artifact**, not a source of truth
|
|
261
|
-
5. Document in the SKILL.md header that it was exported from SQUADRULES
|
|
262
|
-
|
|
263
|
-
```json
|
|
264
|
-
{"contract":{"type":"comment","comment":{"min_length":30},"required":true}}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Reward Signal
|
|
268
|
-
|
|
269
|
-
Only reachable after all prior steps are solved.
|
|
270
|
-
|
|
271
|
-
The agent can now:
|
|
272
|
-
1. Fetch the current Agent Skills spec (Context7 or agentskills.io) instead of
|
|
273
|
-
relying on a frozen copy, and apply it as the authoritative generic format
|
|
274
|
-
2. Layer the SQUADRULES customizations (storage, `SHA256SUMS`, routing) on top of
|
|
275
|
-
that fetched spec
|
|
276
|
-
3. Choose the correct storage location for a skill
|
|
277
|
-
4. Author SKILL.md with valid frontmatter and structure per the current spec
|
|
278
|
-
5. Apply quality gates to descriptions and content
|
|
279
|
-
6. Finalize via local write OR server train (never both)
|
|
280
|
-
7. Produce SHA256SUMS for integrity verification
|