Browse Source

refactor: update SYSTEM_PROMPT.md and agent files for clarity and consistency; enhance rename script to handle non-UTF-8 files

Giancalo Voci 3 weeks ago
parent
commit
c340dd3f2b

+ 8 - 1
SYSTEM_PROMPT.md

@@ -43,4 +43,11 @@ Load skill `coding-standard-rules`
 # Verification & Delegation
 
 - **Verification**: Run minimal targeted verification commands for non-trivial changes. Report exact commands and output. Never claim unexecuted validation.
-- **Task Delegation**: When using the `Task` tool, report outputs concisely and faithfully. Pass clear, self-contained imperative instructions to sub-agents.
+- **Task Delegation**: When using the `Task` tool, report outputs concisely and faithfully. Pass clear, self-contained imperative instructions to sub-agents.
+
+---
+
+# Skills & Agents Source of Truth
+
+- **Edit only in source**: Skills, agent bodies, and this system prompt live in `C:\sources\oh-my-skills` (`skills/`, `agents/`, `SYSTEM_PROMPT.md`). Modify them ONLY there.
+- **Never edit synced copies**: `~/.agents/skills`, `~/.agents/agents`, and global prompt files (e.g. `~/.claude/CLAUDE.md`) are sync targets; the user syncs them manually.

+ 1 - 1
agents/gv-dev.md

@@ -6,7 +6,7 @@ You are a Senior Software Developer. Implement assigned tasks autonomously, clea
 
 * **Strict File Scope**: Read, create, or modify ONLY files explicitly listed in the delegated task. Do NOT search, inspect, or touch unlisted files.
 * **Full Authority**: Delegated tasks are pre-approved. Never ask for confirmation, present proposed diffs, or request permission before editing listed files.
-* **Safe Commands**: Run safe verification/build commands freely without asking.
+* **Safe Commands**: Run safe build, lint, and syntax-check commands freely without asking. Run tests only when the delegated task explicitly requests it, with a 2-minute timeout.
 * **Stop & Ask ONLY if**: The task is ambiguous, conflicts with the codebase, needs unlisted files, or requires destructive/external actions.
 
 ## Style & Output Format

+ 9 - 4
agents/gv-reviewer.md

@@ -28,7 +28,8 @@ Use `<CATEGORY>-<NNN>` with zero-padded sequential numbers, unique per thread:
 ### Severity Classification
 
 * `REQUIRED` (Blocking): Confirmed vulnerabilities (regardless of age), violated spec criteria, introduced/reachable regressions, and concrete code-provable errors.
-* `CONCERNS` (Non-Blocking): Unconfirmed risks, unrelated pre-existing issues, or behavior dependent on unprovable runtime state.
+* `CONCERN` (Non-Blocking): Unconfirmed risks, unrelated pre-existing issues, or behavior dependent on unprovable runtime state.
+* `PASS`: Acceptance criterion verified as satisfied.
 
 *Note: Classify findings as `introduced`, `pre-existing`, or `indeterminate`.*
 
@@ -61,11 +62,15 @@ For every open `REQUIRED` item, provide complete remediation details for direct
   - **Evidence**: Code trace proving the issue
   - **Remediation**: Complete, statically verifiable fix instructions or explicit alternatives
 
-### CONCERNS
+### CONCERN
 - **`<ID>`** (`<classification>`) — `file:line` — Short summary & rationale
 
+### PASS
+- **`<MS-ID>`** — criterion satisfied — `file:line` evidence
+
 ---
-**Summary**: X REQUIRED, Y CONCERNS
-**Verdict**: APPROVED | REJECTED  *(APPROVED requires 0 open REQUIRED items)*
+**Summary**: X REQUIRED, Y CONCERN, Z PASS
+**Verdict**: APPROVED | CHANGES_REQUIRED | REJECTED
+*(APPROVED: 0 open REQUIRED · CHANGES_REQUIRED: fixable REQUIRED remain · REJECTED: criteria unreachable within scope)*
 
 ```

+ 4 - 1
skills/refactor-rename/SKILL.md

@@ -25,8 +25,11 @@ The helper skips these directories to avoid metadata and installed dependencies:
 - `.svn`
 - `node_modules`
 - `vendor`
+- `dist`
+- `target`
+- `__pycache__`
 
-It skips symbolic links and binary files. It processes text files regardless of extension, including `.md`, `.txt`, source files, and configuration files.
+It skips symbolic links, binary files, and files that are not valid UTF-8 (reported as `Skipped non-UTF-8 file`; rename those manually). It processes text files regardless of extension, including `.md`, `.txt`, source files, and configuration files.
 
 ## Workflow
 

+ 33 - 4
skills/refactor-rename/scripts/replace-text.mjs

@@ -4,7 +4,8 @@ import { readdir, readFile, rename, writeFile } from 'node:fs/promises';
 import { basename, dirname, relative, resolve } from 'node:path';
 import { fileURLToPath } from 'node:url';
 
-const EXCLUDED_DIRECTORIES = new Set(['.git', '.hg', '.svn', 'node_modules', 'vendor']);
+const EXCLUDED_DIRECTORIES = new Set(['.git', '.hg', '.svn', 'node_modules', 'vendor', 'dist', 'target', '__pycache__']);
+const utf8Decoder = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
 const argumentsList = process.argv.slice(2);
 const applyChanges = argumentsList.at(-1) === '--apply';
 
@@ -124,8 +125,33 @@ async function collectTextChange(path, oldValue, newValue, changes) {
 		process.exit(1);
 	}
 
-	if (!contents.includes(0) && contents.includes(oldValue)) {
-		changes.set(path, contents.toString().replaceAll(oldValue, newValue));
+	if (contents.includes(0) || !contents.includes(oldValue)) {
+		return;
+	}
+
+	const text = decodeUtf8(contents);
+	if (text === null) {
+		console.warn(`Skipped non-UTF-8 file: ${displayPath(path)}.`);
+		return;
+	}
+
+	changes.set(path, text.replaceAll(oldValue, newValue));
+}
+
+/**
+ * Decodes a buffer as strict UTF-8, preserving any BOM.
+ *
+ * @param {Buffer} contents
+ * @returns {string|null} Decoded text, or null when the bytes are not valid UTF-8.
+ */
+function decodeUtf8(contents) {
+	try {
+		return utf8Decoder.decode(contents);
+	} catch (error) {
+		if (error instanceof TypeError) {
+			return null;
+		}
+		throw error;
 	}
 }
 
@@ -143,7 +169,10 @@ function validatePathChanges(changes) {
 	}
 
 	for (const [source, target] of changes) {
-		if (existsSync(target) && !changes.has(target)) {
+
+		// Case-insensitive filesystems (NTFS, APFS) resolve a case-only target to the source itself.
+		const isCaseOnlyRename = source.toLowerCase() === target.toLowerCase();
+		if (existsSync(target) && !changes.has(target) && !isCaseOnlyRename) {
 			console.error(`Target path already exists: ${displayPath(target)}.`);
 			process.exit(1);
 		}