soturail 0.2.3 → 0.3.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 +43 -10
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/bench.d.ts +1 -1
- package/dist/commands/bench.js +126 -2
- package/dist/commands/bench.js.map +1 -1
- package/dist/commands/context.d.ts +2 -0
- package/dist/commands/context.js +27 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/hooks.d.ts +3 -0
- package/dist/commands/hooks.js +32 -8
- package/dist/commands/hooks.js.map +1 -1
- package/dist/commands/mcp.d.ts +2 -0
- package/dist/commands/mcp.js +21 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/memory.d.ts +1 -0
- package/dist/commands/memory.js +2 -1
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/release.js +175 -7
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/skills.d.ts +2 -0
- package/dist/commands/skills.js +43 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/core/config.d.ts +5 -0
- package/dist/core/config.js +12 -2
- package/dist/core/config.js.map +1 -1
- package/dist/core/context-pack.d.ts +13 -0
- package/dist/core/context-pack.js +102 -0
- package/dist/core/context-pack.js.map +1 -0
- package/dist/core/mcp-resources.d.ts +13 -0
- package/dist/core/mcp-resources.js +46 -0
- package/dist/core/mcp-resources.js.map +1 -0
- package/dist/core/mcp-server.d.ts +14 -0
- package/dist/core/mcp-server.js +81 -0
- package/dist/core/mcp-server.js.map +1 -0
- package/dist/core/mcp-tools.d.ts +7 -0
- package/dist/core/mcp-tools.js +73 -0
- package/dist/core/mcp-tools.js.map +1 -0
- package/dist/core/release-preflight.js +2 -0
- package/dist/core/release-preflight.js.map +1 -1
- package/dist/core/skill-exporter.d.ts +3 -0
- package/dist/core/skill-exporter.js +72 -0
- package/dist/core/skill-exporter.js.map +1 -0
- package/dist/core/skill-schema.d.ts +55 -0
- package/dist/core/skill-schema.js +84 -0
- package/dist/core/skill-schema.js.map +1 -0
- package/dist/core/skill-store.d.ts +4 -0
- package/dist/core/skill-store.js +92 -0
- package/dist/core/skill-store.js.map +1 -0
- package/dist/core/skill-validator.d.ts +12 -0
- package/dist/core/skill-validator.js +94 -0
- package/dist/core/skill-validator.js.map +1 -0
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/docs/benchmarking.md +6 -1
- package/docs/comparisons.md +35 -0
- package/docs/context-packs.md +29 -0
- package/docs/examples/skills/README.md +11 -0
- package/docs/hooks/claude.md +6 -4
- package/docs/hooks/codex.md +4 -3
- package/docs/hooks/cursor.md +4 -3
- package/docs/hooks/gemini.md +4 -3
- package/docs/hooks/mcp.md +10 -0
- package/docs/hooks.md +12 -16
- package/docs/mcp.md +18 -0
- package/docs/release-checklist.md +3 -0
- package/docs/release-workflow.md +15 -22
- package/docs/security-model.md +6 -0
- package/docs/skill-rail.md +14 -20
- package/docs/usage.md +15 -0
- package/docs/windows.md +1 -1
- package/docs/workflow-rail.md +1 -1
- package/package.json +6 -5
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { ensureWorkspace, getWorkspacePaths } from "./config.js";
|
|
4
|
+
import { defaultForbiddenPatterns, defaultHumanApprovals, parseSkillYaml, SkillMetadataSchema, slugifySkillName, stableSkillHash, stringifySkillYaml } from "./skill-schema.js";
|
|
5
|
+
export async function createSkill(name, root = process.cwd()) {
|
|
6
|
+
await ensureWorkspace(root);
|
|
7
|
+
const paths = getWorkspacePaths(root);
|
|
8
|
+
const id = slugifySkillName(name);
|
|
9
|
+
const dir = path.join(paths.skillsDir, id);
|
|
10
|
+
const markdown = [
|
|
11
|
+
`# ${name}`,
|
|
12
|
+
"",
|
|
13
|
+
"Use this skill when the task matches the description and the repository owner has approved it.",
|
|
14
|
+
"",
|
|
15
|
+
"## Safety",
|
|
16
|
+
"",
|
|
17
|
+
"- Do not run destructive shell commands.",
|
|
18
|
+
"- Do not exfiltrate secrets.",
|
|
19
|
+
"- Ask for human approval before remote writes or destructive actions.",
|
|
20
|
+
""
|
|
21
|
+
].join("\n");
|
|
22
|
+
const base = {
|
|
23
|
+
id,
|
|
24
|
+
name,
|
|
25
|
+
description: `Safe local-first workflow skill for ${name}.`,
|
|
26
|
+
version: "0.1.0",
|
|
27
|
+
author: "Rafael Ryan Ramos de Souza",
|
|
28
|
+
risk_level: "low",
|
|
29
|
+
targets: ["claude", "codex", "gemini", "cursor"],
|
|
30
|
+
allowed_tools: ["read", "search"],
|
|
31
|
+
forbidden_patterns: defaultForbiddenPatterns,
|
|
32
|
+
requires_human_approval: defaultHumanApprovals,
|
|
33
|
+
created_at: new Date().toISOString()
|
|
34
|
+
};
|
|
35
|
+
const metadata = { ...base, content_hash: stableSkillHash(base, markdown) };
|
|
36
|
+
await fs.mkdir(path.join(dir, "examples"), { recursive: true });
|
|
37
|
+
await fs.mkdir(path.join(dir, "validators"), { recursive: true });
|
|
38
|
+
await fs.writeFile(path.join(dir, "skill.yml"), stringifySkillYaml(metadata), "utf8");
|
|
39
|
+
await fs.writeFile(path.join(dir, "SKILL.md"), markdown, "utf8");
|
|
40
|
+
return { metadata, markdown, dir };
|
|
41
|
+
}
|
|
42
|
+
export async function readSkills(root = process.cwd()) {
|
|
43
|
+
const paths = getWorkspacePaths(root);
|
|
44
|
+
let entries = [];
|
|
45
|
+
try {
|
|
46
|
+
entries = await fs.readdir(paths.skillsDir);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
const skills = [];
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
const dir = path.join(paths.skillsDir, entry);
|
|
54
|
+
const stat = await fs.stat(dir).catch(() => null);
|
|
55
|
+
if (!stat?.isDirectory())
|
|
56
|
+
continue;
|
|
57
|
+
const yaml = await fs.readFile(path.join(dir, "skill.yml"), "utf8").catch(() => "");
|
|
58
|
+
const markdown = await fs.readFile(path.join(dir, "SKILL.md"), "utf8").catch(() => "");
|
|
59
|
+
const parsed = parseSkillYaml(yaml);
|
|
60
|
+
const result = SkillMetadataSchema.safeParse(parsed);
|
|
61
|
+
if (result.success) {
|
|
62
|
+
skills.push({ metadata: result.data, markdown, dir });
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
skills.push({
|
|
66
|
+
metadata: {
|
|
67
|
+
id: entry,
|
|
68
|
+
name: entry,
|
|
69
|
+
description: "Invalid skill metadata",
|
|
70
|
+
version: "0.0.0",
|
|
71
|
+
author: "unknown",
|
|
72
|
+
risk_level: "high",
|
|
73
|
+
targets: ["generic"],
|
|
74
|
+
allowed_tools: [],
|
|
75
|
+
forbidden_patterns: [],
|
|
76
|
+
requires_human_approval: [],
|
|
77
|
+
created_at: "invalid",
|
|
78
|
+
content_hash: "0".repeat(64)
|
|
79
|
+
},
|
|
80
|
+
markdown,
|
|
81
|
+
dir
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return skills.sort((left, right) => left.metadata.id.localeCompare(right.metadata.id));
|
|
86
|
+
}
|
|
87
|
+
export function renderSkillList(skills) {
|
|
88
|
+
if (skills.length === 0)
|
|
89
|
+
return "No skills found. Run soturail skills init <name> first.\n";
|
|
90
|
+
return skills.map((skill) => `${skill.metadata.id} [${skill.metadata.risk_level}] ${skill.metadata.name}`).join("\n") + "\n";
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=skill-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-store.js","sourceRoot":"","sources":["../../src/core/skill-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface SkillValidationIssue {
|
|
2
|
+
skill_id: string;
|
|
3
|
+
severity: "error" | "warning";
|
|
4
|
+
message: string;
|
|
5
|
+
}
|
|
6
|
+
export interface SkillValidationResult {
|
|
7
|
+
ok: boolean;
|
|
8
|
+
skills_count: number;
|
|
9
|
+
issues: SkillValidationIssue[];
|
|
10
|
+
}
|
|
11
|
+
export declare function validateSkills(root?: string): Promise<SkillValidationResult>;
|
|
12
|
+
export declare function formatSkillValidation(result: SkillValidationResult): string;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseSkillYaml, SkillMetadataSchema, stableSkillHash } from "./skill-schema.js";
|
|
4
|
+
import { readSkills } from "./skill-store.js";
|
|
5
|
+
const destructivePatterns = [
|
|
6
|
+
/\brm\s+-[^"\n]*r[^"\n]*f\b/i,
|
|
7
|
+
/\bcurl\b[^|\n]*\|\s*(sh|bash)\b/i,
|
|
8
|
+
/\bwget\b[^|\n]*\|\s*(sh|bash)\b/i,
|
|
9
|
+
/\bgit\s+push\b/i,
|
|
10
|
+
/\bdd\s+[^"\n]*\bif=/i,
|
|
11
|
+
/\bdel\s+\/s\b/i
|
|
12
|
+
];
|
|
13
|
+
const promptInjectionPatterns = [
|
|
14
|
+
/ignore (all )?(previous|prior) instructions/i,
|
|
15
|
+
/disregard (all )?(previous|prior) instructions/i,
|
|
16
|
+
/you are no longer bound/i
|
|
17
|
+
];
|
|
18
|
+
const secretPatterns = [
|
|
19
|
+
/sk-[A-Za-z0-9_-]{20,}/,
|
|
20
|
+
/AKIA[0-9A-Z]{16}/,
|
|
21
|
+
/-----BEGIN (RSA |OPENSSH |EC )?PRIVATE KEY-----/,
|
|
22
|
+
/(password|api[_-]?key|secret)\s*[:=]\s*["']?[A-Za-z0-9_\-]{16,}/i
|
|
23
|
+
];
|
|
24
|
+
export async function validateSkills(root = process.cwd()) {
|
|
25
|
+
const skills = await readSkills(root);
|
|
26
|
+
const issues = [];
|
|
27
|
+
const seen = new Set();
|
|
28
|
+
for (const skill of skills) {
|
|
29
|
+
await validateSkillFiles(skill, issues);
|
|
30
|
+
if (seen.has(skill.metadata.id)) {
|
|
31
|
+
issues.push({ skill_id: skill.metadata.id, severity: "error", message: "Duplicate skill id." });
|
|
32
|
+
}
|
|
33
|
+
seen.add(skill.metadata.id);
|
|
34
|
+
const combined = `${skill.markdown}\n${JSON.stringify({ ...skill.metadata, forbidden_patterns: [] })}`;
|
|
35
|
+
for (const pattern of destructivePatterns) {
|
|
36
|
+
if (pattern.test(skill.markdown)) {
|
|
37
|
+
issues.push({ skill_id: skill.metadata.id, severity: "error", message: `Hidden destructive command pattern detected: ${pattern}` });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (const pattern of promptInjectionPatterns) {
|
|
41
|
+
if (pattern.test(combined)) {
|
|
42
|
+
issues.push({ skill_id: skill.metadata.id, severity: "error", message: `Prompt-injection style instruction detected: ${pattern}` });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const pattern of secretPatterns) {
|
|
46
|
+
if (pattern.test(combined)) {
|
|
47
|
+
issues.push({ skill_id: skill.metadata.id, severity: "error", message: "Probable embedded secret detected." });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const { content_hash: _hash, ...withoutHash } = skill.metadata;
|
|
51
|
+
const actual = stableSkillHash(withoutHash, skill.markdown);
|
|
52
|
+
if (actual !== skill.metadata.content_hash) {
|
|
53
|
+
issues.push({ skill_id: skill.metadata.id, severity: "error", message: "content_hash does not match skill.yml and SKILL.md content." });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
ok: issues.every((issue) => issue.severity !== "error"),
|
|
58
|
+
skills_count: skills.length,
|
|
59
|
+
issues
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function formatSkillValidation(result) {
|
|
63
|
+
const lines = [
|
|
64
|
+
`Skill validation: ${result.ok ? "passed" : "failed"}`,
|
|
65
|
+
`skills_count: ${result.skills_count}`
|
|
66
|
+
];
|
|
67
|
+
if (result.issues.length === 0) {
|
|
68
|
+
lines.push("issues: none");
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
for (const issue of result.issues) {
|
|
72
|
+
lines.push(`- ${issue.severity.toUpperCase()} ${issue.skill_id}: ${issue.message}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return `${lines.join("\n")}\n`;
|
|
76
|
+
}
|
|
77
|
+
async function validateSkillFiles(skill, issues) {
|
|
78
|
+
const yamlPath = path.join(skill.dir, "skill.yml");
|
|
79
|
+
const markdownPath = path.join(skill.dir, "SKILL.md");
|
|
80
|
+
const rawYaml = await fs.readFile(yamlPath, "utf8").catch(() => "");
|
|
81
|
+
const parsed = parseSkillYaml(rawYaml);
|
|
82
|
+
const result = SkillMetadataSchema.safeParse(parsed);
|
|
83
|
+
if (!result.success) {
|
|
84
|
+
issues.push({
|
|
85
|
+
skill_id: skill.metadata.id,
|
|
86
|
+
severity: "error",
|
|
87
|
+
message: `Invalid skill.yml: ${result.error.issues.map((issue) => issue.path.join(".")).join(", ")}`
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (!await fs.access(markdownPath).then(() => true).catch(() => false)) {
|
|
91
|
+
issues.push({ skill_id: skill.metadata.id, severity: "error", message: "Missing SKILL.md." });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=skill-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-validator.js","sourceRoot":"","sources":["../../src/core/skill-validator.ts"],"names":[],"mappings":"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"}
|
package/dist/core/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SOTURAIL_VERSION = "0.
|
|
1
|
+
export declare const SOTURAIL_VERSION = "0.3.0";
|
package/dist/core/version.js
CHANGED
package/docs/benchmarking.md
CHANGED
|
@@ -20,7 +20,12 @@ The suite groups results as:
|
|
|
20
20
|
- agent response compression;
|
|
21
21
|
- knowledge structuring;
|
|
22
22
|
- cache stability;
|
|
23
|
-
- native engine availability/performance when available
|
|
23
|
+
- native engine availability/performance when available;
|
|
24
|
+
- skill rail validation/export;
|
|
25
|
+
- MCP resource listing/reading;
|
|
26
|
+
- context pack generation;
|
|
27
|
+
- agent hook export;
|
|
28
|
+
- memory approval workflow.
|
|
24
29
|
|
|
25
30
|
Terminal compression includes npm install noise, Vitest failures, TypeScript diagnostics, git diff/status noise and JSON/tool payload output.
|
|
26
31
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Comparison Philosophy
|
|
2
|
+
|
|
3
|
+
SotuRail aims to unify these workflow ideas into one local-first, auditable, cache-friendly developer tool.
|
|
4
|
+
|
|
5
|
+
SotuRail is an independent implementation. It does not vendor or depend on RTK, Squeez, Caveman, MemPalace, Spec Kit, agent-skills, SkillsMP, Compozy, Superpowers, OpenSpec or Istara.
|
|
6
|
+
|
|
7
|
+
## Terminal Compression
|
|
8
|
+
|
|
9
|
+
RTK-like terminal compression is conceptually related. SotuRail focuses on reversible raw logs, `raw_id` recovery and local safety policy. It does not claim to outperform RTK without reproducible benchmark evidence.
|
|
10
|
+
|
|
11
|
+
## Hooks And Dedupe
|
|
12
|
+
|
|
13
|
+
Squeez-like hooks and dedupe are adjacent ideas. SotuRail has prompt-only fallbacks, conservative Claude hooks, context packs and local dedupe as an independent implementation.
|
|
14
|
+
|
|
15
|
+
## Response Compression
|
|
16
|
+
|
|
17
|
+
Caveman-like response compression inspired the idea of shorter agent output. SotuRail implements professional deterministic modes that preserve code blocks, commands, paths and warnings.
|
|
18
|
+
|
|
19
|
+
## Spec Workflows
|
|
20
|
+
|
|
21
|
+
Spec Kit-like workflows are related to SotuRail specs. SotuRail integrates specs with logs, metrics, memory and context packs.
|
|
22
|
+
|
|
23
|
+
## Local Memory
|
|
24
|
+
|
|
25
|
+
MemPalace-like memory/evidence ideas are related. SotuRail uses local JSONL memory with approval workflow and stale marking, not full semantic memory yet.
|
|
26
|
+
|
|
27
|
+
## Knowledge To Rules
|
|
28
|
+
|
|
29
|
+
Nicole-style knowledge-to-rules workflows are related. SotuRail has `ingest` and `rules` with future hardened PDF extraction.
|
|
30
|
+
|
|
31
|
+
## Skills And Workflow Orchestration
|
|
32
|
+
|
|
33
|
+
Agent-skills and SkillsMP-like ecosystems are related to Skill Rail exports. Compozy, Superpowers and OpenSpec-style orchestration are future Workflow Rail territory.
|
|
34
|
+
|
|
35
|
+
SotuRail should not be described as better than these projects unless a specific local benchmark proves a specific metric.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Context Packs
|
|
2
|
+
|
|
3
|
+
Context packs are target-aware Markdown payloads for AI coding agents.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
soturail context pack --target claude
|
|
7
|
+
soturail context pack --target codex
|
|
8
|
+
soturail context pack --target gemini
|
|
9
|
+
soturail context pack --target cursor
|
|
10
|
+
soturail context pack --target generic
|
|
11
|
+
soturail context explain
|
|
12
|
+
soturail context doctor
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Generated files live in `.soturail/context/`.
|
|
16
|
+
|
|
17
|
+
Stable-cache order:
|
|
18
|
+
|
|
19
|
+
1. Static SotuRail header.
|
|
20
|
+
2. Governance files summary.
|
|
21
|
+
3. Project config.
|
|
22
|
+
4. Repo map summary.
|
|
23
|
+
5. Approved rules.
|
|
24
|
+
6. Approved specs.
|
|
25
|
+
7. Approved memory.
|
|
26
|
+
8. Skills summary.
|
|
27
|
+
9. Dynamic footer with timestamps, current commit, raw IDs and recent command notes.
|
|
28
|
+
|
|
29
|
+
Dynamic data never appears before stable blocks.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Skill Examples
|
|
2
|
+
|
|
3
|
+
Generate local examples with:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
soturail skills init demo-skill
|
|
7
|
+
soturail skills validate
|
|
8
|
+
soturail skills export --target generic
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Generated skills live in `.soturail/skills/` and exports live in `.soturail/exports/skills/`.
|
package/docs/hooks/claude.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# Claude Hooks
|
|
2
2
|
|
|
3
|
-
SotuRail v0.
|
|
3
|
+
SotuRail v0.3.0 includes conservative Claude safe-hooks and MCP guidance.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
soturail hooks install claude --dry-run
|
|
7
|
-
soturail hooks install claude
|
|
8
|
-
soturail hooks
|
|
6
|
+
soturail hooks install --agent claude --mode safe-hooks --dry-run
|
|
7
|
+
soturail hooks install --agent claude --mode safe-hooks
|
|
8
|
+
soturail hooks install --agent claude --mode mcp
|
|
9
|
+
soturail hooks uninstall --agent claude
|
|
10
|
+
soturail hooks export --agent claude
|
|
9
11
|
soturail hooks prompt-only claude
|
|
10
12
|
```
|
|
11
13
|
|
package/docs/hooks/codex.md
CHANGED
|
@@ -7,9 +7,10 @@ SotuRail does not assume private Codex host hook APIs. The fallback rules descri
|
|
|
7
7
|
Useful commands:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
soturail hooks install codex --dry-run
|
|
11
|
-
soturail hooks install codex
|
|
12
|
-
soturail hooks uninstall codex
|
|
10
|
+
soturail hooks install --agent codex --mode prompt-only --dry-run
|
|
11
|
+
soturail hooks install --agent codex --mode prompt-only
|
|
12
|
+
soturail hooks uninstall --agent codex
|
|
13
|
+
soturail hooks export --agent codex
|
|
13
14
|
soturail hooks prompt-only codex
|
|
14
15
|
```
|
|
15
16
|
|
package/docs/hooks/cursor.md
CHANGED
|
@@ -7,9 +7,10 @@ Existing files are backed up before SotuRail adds its rules.
|
|
|
7
7
|
Useful commands:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
soturail hooks install cursor --dry-run
|
|
11
|
-
soturail hooks install cursor
|
|
12
|
-
soturail hooks uninstall cursor
|
|
10
|
+
soturail hooks install --agent cursor --mode prompt-only --dry-run
|
|
11
|
+
soturail hooks install --agent cursor --mode prompt-only
|
|
12
|
+
soturail hooks uninstall --agent cursor
|
|
13
|
+
soturail hooks export --agent cursor
|
|
13
14
|
soturail hooks prompt-only cursor
|
|
14
15
|
```
|
|
15
16
|
|
package/docs/hooks/gemini.md
CHANGED
|
@@ -7,9 +7,10 @@ The generated rules keep repository scans, progressive file reads and raw log re
|
|
|
7
7
|
Useful commands:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
soturail hooks install gemini --dry-run
|
|
11
|
-
soturail hooks install gemini
|
|
12
|
-
soturail hooks uninstall gemini
|
|
10
|
+
soturail hooks install --agent gemini --mode prompt-only --dry-run
|
|
11
|
+
soturail hooks install --agent gemini --mode prompt-only
|
|
12
|
+
soturail hooks uninstall --agent gemini
|
|
13
|
+
soturail hooks export --agent gemini
|
|
13
14
|
soturail hooks prompt-only gemini
|
|
14
15
|
```
|
|
15
16
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# MCP Hook Integration
|
|
2
|
+
|
|
3
|
+
Use MCP mode when an agent host supports reviewed local MCP server configuration.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
soturail hooks install --agent claude --mode mcp --dry-run
|
|
7
|
+
soturail mcp serve --transport stdio
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Review generated instructions before enabling. SotuRail's MCP server exposes read-only resources and safe tools; it does not expose arbitrary shell execution in v0.3.0.
|
package/docs/hooks.md
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
# Agent Hooks
|
|
2
2
|
|
|
3
|
-
SotuRail hook support is cautious. Claude gets
|
|
3
|
+
SotuRail hook support is cautious. Claude gets conservative safe-hooks and MCP guidance first; Codex, Gemini and Cursor use prompt-only fallbacks when stable native hook APIs are unavailable.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
soturail hooks list
|
|
7
7
|
soturail hooks doctor
|
|
8
|
-
soturail hooks install claude --dry-run
|
|
9
|
-
soturail hooks install claude
|
|
10
|
-
soturail hooks
|
|
11
|
-
soturail hooks install
|
|
12
|
-
soturail hooks prompt-only
|
|
8
|
+
soturail hooks install --agent claude --mode safe-hooks --dry-run
|
|
9
|
+
soturail hooks install --agent claude --mode mcp
|
|
10
|
+
soturail hooks install --agent codex --mode prompt-only
|
|
11
|
+
soturail hooks install --agent gemini --mode prompt-only
|
|
12
|
+
soturail hooks install --agent cursor --mode prompt-only
|
|
13
|
+
soturail hooks uninstall --agent claude
|
|
14
|
+
soturail hooks export --agent claude
|
|
15
|
+
soturail hooks export --agent codex
|
|
13
16
|
```
|
|
14
17
|
|
|
15
|
-
Installers create backups before modifying existing files. If a host config location is uncertain, SotuRail generates prompt-only guidance instead of guessing.
|
|
18
|
+
Installers create backups before modifying existing files. Dry-run prints every file that would change. If a host config location is uncertain, SotuRail generates prompt-only guidance instead of guessing.
|
|
16
19
|
|
|
17
|
-
Claude
|
|
20
|
+
Claude safe-hooks write `.claude/settings.json` and hook scripts under `.claude/hooks/`. The pre-tool hook blocks destructive command shapes and suggests `soturail run` for tests, builds and logs.
|
|
18
21
|
|
|
19
|
-
Always review generated hooks before enabling them. SotuRail should never auto-install unreviewed third-party skills, hooks or scripts.
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
soturail hooks prompt-only claude
|
|
23
|
-
soturail hooks prompt-only codex
|
|
24
|
-
soturail hooks prompt-only gemini
|
|
25
|
-
soturail hooks prompt-only cursor
|
|
26
|
-
```
|
|
22
|
+
Always review generated hooks before enabling them. SotuRail should never auto-install unreviewed third-party skills, hooks or scripts.
|
package/docs/mcp.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# MCP Server
|
|
2
|
+
|
|
3
|
+
SotuRail v0.3.0 includes a local MCP-compatible server over stdio using JSON-RPC 2.0 style messages.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
soturail mcp doctor
|
|
7
|
+
soturail mcp manifest
|
|
8
|
+
soturail mcp serve --transport stdio
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The server exposes read-only resources such as the repo map, tree, rules, approved memory, self report, latest benchmarks and roadmap. It also exposes safe tools for indexing, progressive reads, formatting, rule checks, skill listing, context pack generation and raw log expansion.
|
|
12
|
+
|
|
13
|
+
Security defaults:
|
|
14
|
+
|
|
15
|
+
- no arbitrary shell execution;
|
|
16
|
+
- no `soturail run` MCP tool in v0.3.0;
|
|
17
|
+
- raw log expansion redacts probable secrets unless `allow_raw=true`;
|
|
18
|
+
- provider cache hits are never invented.
|
|
@@ -9,6 +9,9 @@ Before publishing:
|
|
|
9
9
|
- [ ] `npm test`
|
|
10
10
|
- [ ] `npm audit --omit=dev`
|
|
11
11
|
- [ ] `node dist/cli.js self all`
|
|
12
|
+
- [ ] `node dist/cli.js skills --help`
|
|
13
|
+
- [ ] `node dist/cli.js mcp --help`
|
|
14
|
+
- [ ] `node dist/cli.js context --help`
|
|
12
15
|
- [ ] `npm pack --dry-run`
|
|
13
16
|
- [ ] `npm run release:check`
|
|
14
17
|
- [ ] `node dist/cli.js --version` matches `package.json`.
|
package/docs/release-workflow.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Release Workflow
|
|
2
2
|
|
|
3
|
-
SotuRail releases should be repeatable and evidence-backed.
|
|
3
|
+
SotuRail releases should be repeatable and evidence-backed. v0.3.0 exposes release helpers through `soturail release`.
|
|
4
4
|
|
|
5
5
|
## Check
|
|
6
6
|
|
|
@@ -18,27 +18,10 @@ The check also verifies:
|
|
|
18
18
|
- `CHANGELOG.md` and `RELEASE_NOTES_vX.Y.Z.md` exist for the local version;
|
|
19
19
|
- README install instructions and `LICENSE` exist.
|
|
20
20
|
|
|
21
|
-
## Prepare
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npm run release:prepare -- --version X.Y.Z
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Prepare mode:
|
|
28
|
-
|
|
29
|
-
- validates the version argument;
|
|
30
|
-
- updates `package.json`, `package-lock.json` and CLI version text;
|
|
31
|
-
- updates `CHANGELOG.md`;
|
|
32
|
-
- creates `RELEASE_NOTES_vX.Y.Z.md`;
|
|
33
|
-
- runs validation;
|
|
34
|
-
- commits `chore(release): prepare vX.Y.Z`;
|
|
35
|
-
- pushes `main`;
|
|
36
|
-
- never publishes to npm.
|
|
37
|
-
|
|
38
21
|
## Publish
|
|
39
22
|
|
|
40
23
|
```bash
|
|
41
|
-
npm run release:publish --
|
|
24
|
+
npm run release:publish -- X.Y.Z
|
|
42
25
|
```
|
|
43
26
|
|
|
44
27
|
Publish mode refuses to publish if build, tests, release preflight or runtime audit fail, if the git tree is dirty, or if the version already exists on npm.
|
|
@@ -54,17 +37,27 @@ If npm asks for 2FA during publish, use a fresh authenticator code:
|
|
|
54
37
|
|
|
55
38
|
```powershell
|
|
56
39
|
$env:NPM_CONFIG_OTP="<code>"
|
|
57
|
-
npm run release:publish --
|
|
40
|
+
npm run release:publish -- X.Y.Z
|
|
58
41
|
Remove-Item Env:NPM_CONFIG_OTP
|
|
59
42
|
```
|
|
60
43
|
|
|
61
44
|
## Full
|
|
62
45
|
|
|
63
46
|
```bash
|
|
64
|
-
npm run release:full --
|
|
47
|
+
npm run release:full -- X.Y.Z --publish-npm --github-release
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Full mode runs release gates, then publishes to npm only when `--publish-npm` is supplied, and creates or updates the GitHub release only when `--github-release` is supplied.
|
|
51
|
+
|
|
52
|
+
For explicit CLI usage:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
soturail release publish X.Y.Z
|
|
56
|
+
soturail release github X.Y.Z
|
|
57
|
+
soturail release full X.Y.Z --publish-npm --github-release
|
|
65
58
|
```
|
|
66
59
|
|
|
67
|
-
|
|
60
|
+
Release commands also accept `--target-version X.Y.Z`. The older `--version X.Y.Z` form remains supported for npm scripts, but the positional form avoids confusion with the global `soturail --version` flag.
|
|
68
61
|
|
|
69
62
|
Only create or update the GitHub release after npm publish succeeds and these checks pass:
|
|
70
63
|
|
package/docs/security-model.md
CHANGED
|
@@ -27,6 +27,12 @@ This is intentionally verbose so accidental bypasses are unlikely.
|
|
|
27
27
|
|
|
28
28
|
Raw command logs remain on disk so compressed summaries can always be audited.
|
|
29
29
|
|
|
30
|
+
Raw logs may contain secrets. Do not commit `.soturail/raw/`. MCP raw-log expansion redacts probable secrets by default unless `allow_raw=true` is explicitly passed.
|
|
31
|
+
|
|
32
|
+
## MCP And Skills
|
|
33
|
+
|
|
34
|
+
The v0.3.0 MCP server does not expose arbitrary shell execution. Skill Rail exports are local files for human review; SotuRail does not auto-install unreviewed third-party skills.
|
|
35
|
+
|
|
30
36
|
## Limitations
|
|
31
37
|
|
|
32
38
|
SotuRail does not isolate processes, prevent all shell tricks or replace OS permissions. Treat it as a policy and evidence layer.
|
package/docs/skill-rail.md
CHANGED
|
@@ -1,28 +1,22 @@
|
|
|
1
1
|
# Skill Rail
|
|
2
2
|
|
|
3
|
-
Skill Rail
|
|
4
|
-
|
|
5
|
-
The goal is to turn approved SotuRail specs, rules and workflows into portable, reviewable agent skills without installing untrusted marketplace content automatically.
|
|
6
|
-
|
|
7
|
-
Planned commands:
|
|
3
|
+
Skill Rail exports safe local agent skills without depending on external skill ecosystems.
|
|
8
4
|
|
|
9
5
|
```bash
|
|
10
|
-
soturail skills init
|
|
11
|
-
soturail skills
|
|
12
|
-
soturail skills
|
|
13
|
-
soturail skills
|
|
14
|
-
soturail skills export
|
|
6
|
+
soturail skills init demo-skill
|
|
7
|
+
soturail skills list
|
|
8
|
+
soturail skills validate
|
|
9
|
+
soturail skills export --target claude
|
|
10
|
+
soturail skills export --target codex
|
|
11
|
+
soturail skills export --target gemini
|
|
12
|
+
soturail skills export --target cursor
|
|
13
|
+
soturail skills export --target generic
|
|
14
|
+
soturail skills pack --format json
|
|
15
|
+
soturail skills pack --format markdown
|
|
15
16
|
```
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
Skills live in `.soturail/skills/<skill-id>/` with `skill.yml`, `SKILL.md`, examples and validators.
|
|
18
19
|
|
|
19
|
-
-
|
|
20
|
-
- Validate `SKILL.md` before use.
|
|
21
|
-
- Scan for prompt injection.
|
|
22
|
-
- Scan for destructive shell commands.
|
|
23
|
-
- Scan for secret exfiltration language.
|
|
24
|
-
- Scan for `curl`/`wget` pipe execution.
|
|
25
|
-
- Warn about untrusted scripts.
|
|
26
|
-
- Require human approval before enabling generated skills.
|
|
20
|
+
Validation checks required metadata, target names, duplicate IDs, deterministic content hashes, destructive shell patterns, prompt-injection style instructions and probable embedded secrets.
|
|
27
21
|
|
|
28
|
-
|
|
22
|
+
Exports are written to `.soturail/exports/skills/<target>/`. Review every generated file before enabling it in Claude, Codex, Gemini, Cursor or another host.
|
package/docs/usage.md
CHANGED
|
@@ -62,3 +62,18 @@ soturail rules check
|
|
|
62
62
|
soturail native doctor
|
|
63
63
|
soturail bench compare-engines
|
|
64
64
|
```
|
|
65
|
+
|
|
66
|
+
## v0.3.0 Workflows
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
soturail skills init demo-skill
|
|
70
|
+
soturail skills validate
|
|
71
|
+
soturail skills export --target claude
|
|
72
|
+
soturail context pack --target generic
|
|
73
|
+
soturail mcp doctor
|
|
74
|
+
soturail mcp manifest
|
|
75
|
+
soturail hooks install --agent claude --mode safe-hooks --dry-run
|
|
76
|
+
soturail release check
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
MCP is local stdio JSON-RPC style transport and does not expose arbitrary shell execution in v0.3.0.
|
package/docs/windows.md
CHANGED
package/docs/workflow-rail.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Workflow Rail
|
|
2
2
|
|
|
3
|
-
Workflow Rail is planned for v0.4.0. It is not implemented in v0.
|
|
3
|
+
Workflow Rail is planned for v0.4.0. It is not implemented in v0.3.0.
|
|
4
4
|
|
|
5
5
|
The goal is to describe repeatable engineering workflows as local, auditable artifacts that can later export into Skill Rail or an MCP server.
|
|
6
6
|
|