@rmrdeveloper/sideroom-pi 8.0.0 → 8.0.2
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/extensions/guidelines/catalog.ts +47 -0
- package/extensions/guidelines/guard.ts +23 -32
- package/extensions/guidelines/prompt.ts +13 -13
- package/package.json +1 -1
- package/skills/sideroom-domain-modeling/SKILL.md +1 -1
- package/skills/sideroom-domain-scaffold/SKILL.md +1 -1
- package/skills/sideroom-grill/SKILL.md +1 -1
- package/skills/sideroom-guidelines/SKILL.md +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { dirname, join, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
|
|
4
|
+
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
|
|
5
|
+
const LANGUAGE_GUIDE_DIRECTORY = join(
|
|
6
|
+
PACKAGE_ROOT,
|
|
7
|
+
'skills/sideroom-guidelines/references/languages',
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export const GUIDELINE_SKILL_PATH = join(
|
|
11
|
+
PACKAGE_ROOT,
|
|
12
|
+
'skills/sideroom-guidelines/SKILL.md',
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
export interface LanguageGuide {
|
|
16
|
+
readonly extensions: readonly string[];
|
|
17
|
+
readonly fileName: string;
|
|
18
|
+
readonly path: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const LANGUAGE_GUIDES: readonly LanguageGuide[] = [
|
|
22
|
+
languageGuide('go.md', ['.go']),
|
|
23
|
+
languageGuide('java.md', ['.java']),
|
|
24
|
+
languageGuide('php-laravel.md', ['.php']),
|
|
25
|
+
languageGuide('python.md', ['.py']),
|
|
26
|
+
languageGuide('rust.md', ['.rs']),
|
|
27
|
+
languageGuide('typescript.md', ['.ts', '.tsx']),
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
export const LANGUAGE_GUIDE_FILES: readonly string[] = LANGUAGE_GUIDES.map(
|
|
31
|
+
({ fileName }) => fileName,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
export const LANGUAGE_TARGET_LABELS: readonly string[] = LANGUAGE_GUIDES.map(
|
|
35
|
+
({ extensions }) => extensions.join('/'),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
function languageGuide(
|
|
39
|
+
fileName: string,
|
|
40
|
+
extensions: readonly string[],
|
|
41
|
+
): LanguageGuide {
|
|
42
|
+
return {
|
|
43
|
+
extensions,
|
|
44
|
+
fileName,
|
|
45
|
+
path: join(LANGUAGE_GUIDE_DIRECTORY, fileName),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -1,29 +1,11 @@
|
|
|
1
|
-
import { dirname, join, resolve } from 'node:path';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
1
|
import {
|
|
4
2
|
type ExtensionAPI,
|
|
5
3
|
isReadToolResult,
|
|
6
4
|
isToolCallEventType,
|
|
7
5
|
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { GUIDELINE_SKILL_PATH, LANGUAGE_GUIDES } from './catalog.ts';
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
export const GUIDELINE_SKILL_PATH = join(
|
|
11
|
-
PACKAGE_ROOT,
|
|
12
|
-
'skills/sideroom-guidelines/SKILL.md',
|
|
13
|
-
);
|
|
14
|
-
const LANGUAGE_GUIDE_DIRECTORY = join(
|
|
15
|
-
PACKAGE_ROOT,
|
|
16
|
-
'skills/sideroom-guidelines/references/languages',
|
|
17
|
-
);
|
|
18
|
-
const LANGUAGE_GUIDE_BY_EXTENSION: Readonly<Record<string, string>> = {
|
|
19
|
-
'.go': join(LANGUAGE_GUIDE_DIRECTORY, 'go.md'),
|
|
20
|
-
'.java': join(LANGUAGE_GUIDE_DIRECTORY, 'java.md'),
|
|
21
|
-
'.php': join(LANGUAGE_GUIDE_DIRECTORY, 'php-laravel.md'),
|
|
22
|
-
'.py': join(LANGUAGE_GUIDE_DIRECTORY, 'python.md'),
|
|
23
|
-
'.rs': join(LANGUAGE_GUIDE_DIRECTORY, 'rust.md'),
|
|
24
|
-
'.ts': join(LANGUAGE_GUIDE_DIRECTORY, 'typescript.md'),
|
|
25
|
-
'.tsx': join(LANGUAGE_GUIDE_DIRECTORY, 'typescript.md'),
|
|
26
|
-
};
|
|
8
|
+
export { GUIDELINE_SKILL_PATH } from './catalog.ts';
|
|
27
9
|
|
|
28
10
|
interface ReadInput {
|
|
29
11
|
readonly path: string;
|
|
@@ -56,7 +38,11 @@ export function registerGuidelineGuard(
|
|
|
56
38
|
|
|
57
39
|
// SAFETY: Pi validates built-in read arguments before emitting tool_result.
|
|
58
40
|
const input = event.input as unknown as ReadInput;
|
|
59
|
-
if (
|
|
41
|
+
if (
|
|
42
|
+
input.offset !== undefined ||
|
|
43
|
+
input.limit !== undefined ||
|
|
44
|
+
event.details?.truncation?.truncated === true
|
|
45
|
+
) {
|
|
60
46
|
return;
|
|
61
47
|
}
|
|
62
48
|
recordGuidelineRead(state, input.path);
|
|
@@ -70,7 +56,11 @@ export function registerGuidelineGuard(
|
|
|
70
56
|
return;
|
|
71
57
|
}
|
|
72
58
|
|
|
73
|
-
const reason = mutationBlockReason(
|
|
59
|
+
const reason = mutationBlockReason(
|
|
60
|
+
state,
|
|
61
|
+
event.input.path,
|
|
62
|
+
pi.getActiveTools().includes('read'),
|
|
63
|
+
);
|
|
74
64
|
if (reason === undefined) {
|
|
75
65
|
return;
|
|
76
66
|
}
|
|
@@ -92,9 +82,9 @@ export function recordGuidelineRead(
|
|
|
92
82
|
return;
|
|
93
83
|
}
|
|
94
84
|
|
|
95
|
-
for (const
|
|
96
|
-
if (normalizedPath === normalizePath(
|
|
97
|
-
state.languageGuidesRead.add(
|
|
85
|
+
for (const guide of LANGUAGE_GUIDES) {
|
|
86
|
+
if (normalizedPath === normalizePath(guide.path)) {
|
|
87
|
+
state.languageGuidesRead.add(guide.path);
|
|
98
88
|
return;
|
|
99
89
|
}
|
|
100
90
|
}
|
|
@@ -103,6 +93,7 @@ export function recordGuidelineRead(
|
|
|
103
93
|
export function mutationBlockReason(
|
|
104
94
|
state: GuidelineReadState,
|
|
105
95
|
targetPath: string,
|
|
96
|
+
readToolAvailable = true,
|
|
106
97
|
): string | undefined {
|
|
107
98
|
const requiredPaths: string[] = [];
|
|
108
99
|
if (!state.skillRead) {
|
|
@@ -117,18 +108,18 @@ export function mutationBlockReason(
|
|
|
117
108
|
if (requiredPaths.length === 0) {
|
|
118
109
|
return undefined;
|
|
119
110
|
}
|
|
111
|
+
if (!readToolAvailable) {
|
|
112
|
+
return `Blocked ${targetPath}: the read tool is inactive, so the guidelines gate cannot be satisfied. Enable read, then read ${requiredPaths.join(' and ')} before retrying the mutation.`;
|
|
113
|
+
}
|
|
120
114
|
|
|
121
|
-
return `Blocked ${targetPath}: read ${requiredPaths.join(' and ')} with the read tool in this agent run, then retry the
|
|
115
|
+
return `Blocked ${targetPath}: read ${requiredPaths.join(' and ')} with the read tool in this agent run, then retry the mutation.`;
|
|
122
116
|
}
|
|
123
117
|
|
|
124
118
|
function languageGuideFor(path: string): string | undefined {
|
|
125
119
|
const normalizedPath = normalizePath(path).toLowerCase();
|
|
126
|
-
|
|
127
|
-
normalizedPath.endsWith(
|
|
128
|
-
);
|
|
129
|
-
return extension === undefined
|
|
130
|
-
? undefined
|
|
131
|
-
: LANGUAGE_GUIDE_BY_EXTENSION[extension];
|
|
120
|
+
return LANGUAGE_GUIDES.find(({ extensions }) =>
|
|
121
|
+
extensions.some((extension) => normalizedPath.endsWith(extension)),
|
|
122
|
+
)?.path;
|
|
132
123
|
}
|
|
133
124
|
|
|
134
125
|
function normalizePath(path: string): string {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
+
import { GUIDELINE_SKILL_PATH, LANGUAGE_GUIDES } from './catalog.ts';
|
|
2
|
+
|
|
3
|
+
export { LANGUAGE_GUIDE_FILES } from './catalog.ts';
|
|
4
|
+
|
|
1
5
|
export const GUIDELINES_REMINDER_HEADING =
|
|
2
6
|
'Sideroom coding guidelines (always-on reminder):';
|
|
3
7
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Before finishing, review changed code against the loaded guide and run the relevant formatter, linter, type checks, and tests.`;
|
|
8
|
+
const LANGUAGE_GUIDE_REMINDERS = LANGUAGE_GUIDES.map(
|
|
9
|
+
({ extensions, path }) =>
|
|
10
|
+
`If a file you will write or edit ends in ${extensions.join(' or ')}, use the read tool without offset or limit to load the exact matching guide at ${path} in full.`,
|
|
11
|
+
).join('\n');
|
|
9
12
|
|
|
10
|
-
export const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'rust.md',
|
|
16
|
-
'typescript.md',
|
|
17
|
-
] as const;
|
|
13
|
+
export const GUIDELINES_REMINDER = `${GUIDELINES_REMINDER_HEADING}
|
|
14
|
+
Before the first write or edit in each agent run, use the read tool without offset or limit to load ${GUIDELINE_SKILL_PATH} in full.
|
|
15
|
+
${LANGUAGE_GUIDE_REMINDERS}
|
|
16
|
+
A required read counts only when it succeeds without truncation. Until all required reads succeed, do not call write or edit and do not mutate files through bash or another tool; the extension blocks those mutations.
|
|
17
|
+
After changing files, review the code against the loaded guide and run the relevant formatter, linter, type checks, and tests.`;
|
|
18
18
|
|
|
19
19
|
export function appendGuidelinesReminder(systemPrompt: string): string {
|
|
20
20
|
if (systemPrompt.includes(GUIDELINES_REMINDER_HEADING)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sideroom-domain-modeling
|
|
3
|
-
description: "
|
|
3
|
+
description: "Resolve domain-language conflicts and naming decisions. Use when terms are ambiguous, overloaded, or used inconsistently; when deciding what belongs in CONTEXT.md; or when a domain choice may need an ADR. Use for one or a few terms, not for simply reading CONTEXT.md, scanning an entire repository, or reshaping modules."
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: RMRdeveloper
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sideroom-domain-scaffold
|
|
3
|
-
description: "
|
|
3
|
+
description: "Build or complete a code-first CONTEXT.md for a repository with missing or thin domain vocabulary. Use when the user asks to document or survey the repo, scaffold a brownfield glossary, or derive domain terms from central business code. Do not use for resolving one naming conflict or conducting an interactive design interview."
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: RMRdeveloper
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sideroom-grill
|
|
3
|
-
description: "
|
|
3
|
+
description: "Interview the user in rounds to resolve a fuzzy plan, design decision, or domain-language conflict before implementation. Use when the user asks to be grilled, wants clarifying questions, or says the plan or terms are not settled. Do not use for a code-first repository scan or a simple glossary lookup."
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: RMRdeveloper
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sideroom-guidelines
|
|
3
|
-
description: "
|
|
3
|
+
description: "Apply Sideroom's mandatory coding workflow before implementing, refactoring, or fixing Java, Laravel/PHP, TypeScript/TSX, Python, Go, or Rust code. Load this skill and the exact language guide before mutation. Do not use for unrelated prose or domain-only discussions."
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: RMRdeveloper
|