Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 1 addition & 2 deletions .claude/hooks/skill-activation-prompt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ describe("Skill Activation Snapshots", () => {

it("update dependencies", ({ task }) => createSnapshot(task.name));

it("update Cargo.toml workspace dependencies", ({ task }) =>
createSnapshot(task.name));
it("update Cargo.toml workspace dependencies", ({ task }) => createSnapshot(task.name));

it("improve documentation", ({ task }) => createSnapshot(task.name));

Expand Down
62 changes: 14 additions & 48 deletions .claude/hooks/skill-activation-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,11 @@ function main() {
const projectDir = getProjectDir();
debug("Project directory:", projectDir);

const rulesPath = path.join(
projectDir,
".claude",
"skills",
"skill-rules.json",
);
const rulesPath = path.join(projectDir, ".claude", "skills", "skill-rules.json");

debug("Loading rules from:", rulesPath);

const rules: SkillRules = JSON.parse(
readFileSync(rulesPath, "utf-8"),
) as SkillRules;
const rules: SkillRules = JSON.parse(readFileSync(rulesPath, "utf-8")) as SkillRules;

debug("Rules loaded, checking", Object.keys(rules.skills).length, "skills");

Expand All @@ -162,9 +155,7 @@ function main() {
// Keyword matching with fuzzy support
if (triggers.keywords) {
// Try exact substring match first (most specific)
const exactMatch = triggers.keywords.find((kw) =>
prompt.includes(kw.toLowerCase()),
);
const exactMatch = triggers.keywords.find((kw) => prompt.includes(kw.toLowerCase()));

if (exactMatch) {
debug(`Skill '${skillName}': MATCHED via exact keyword`, exactMatch);
Expand All @@ -178,9 +169,7 @@ function main() {
// For multi-word keywords, ALL words must fuzzy-match
// For single-word keywords, just check if it matches any prompt word
if (keywordWords.length === 1) {
return promptWords.some((pWord) =>
isFuzzyMatch(keywordWords[0]!, pWord),
);
return promptWords.some((pWord) => isFuzzyMatch(keywordWords[0]!, pWord));
}

// Multi-word: all keyword words must match
Expand All @@ -190,10 +179,7 @@ function main() {
});

if (fuzzyMatch) {
debug(
`Skill '${skillName}': MATCHED via fuzzy keyword`,
fuzzyMatch,
);
debug(`Skill '${skillName}': MATCHED via fuzzy keyword`, fuzzyMatch);
matchType = "keyword";
} else {
debug(`Skill '${skillName}': no keyword match`);
Expand All @@ -204,30 +190,20 @@ function main() {
// Intent pattern matching (always check, even if keyword matched)
if (triggers.intentPatterns) {
try {
const compiledPatterns = compileRegexPatterns(
triggers.intentPatterns,
skillName,
);
const compiledPatterns = compileRegexPatterns(triggers.intentPatterns, skillName);

const matchedPattern = compiledPatterns.find((cp) =>
cp.regex.test(prompt),
);
const matchedPattern = compiledPatterns.find((cp) => cp.regex.test(prompt));

if (matchedPattern) {
debug(
`Skill '${skillName}': MATCHED via intent pattern`,
matchedPattern.pattern,
);
debug(`Skill '${skillName}': MATCHED via intent pattern`, matchedPattern.pattern);
// Only set matchType to intent if keyword didn't already match
// (keywords are more specific and take priority)
matchType ??= "intent";
} else {
debug(`Skill '${skillName}': no intent pattern match`);
}
} catch (error) {
console.error(
`Warning: Skipping skill '${skillName}' due to invalid regex pattern`,
);
console.error(`Warning: Skipping skill '${skillName}' due to invalid regex pattern`);
console.error(error instanceof Error ? error.message : String(error));
continue;
}
Expand All @@ -249,18 +225,10 @@ function main() {
output += "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";

// Group by priority
const critical = matchedSkills.filter(
(skill) => skill.config.priority === "critical",
);
const high = matchedSkills.filter(
(skill) => skill.config.priority === "high",
);
const medium = matchedSkills.filter(
(skill) => skill.config.priority === "medium",
);
const low = matchedSkills.filter(
(skill) => skill.config.priority === "low",
);
const critical = matchedSkills.filter((skill) => skill.config.priority === "critical");
const high = matchedSkills.filter((skill) => skill.config.priority === "high");
const medium = matchedSkills.filter((skill) => skill.config.priority === "medium");
const low = matchedSkills.filter((skill) => skill.config.priority === "low");

if (critical.length > 0) {
output += "⚠️ CRITICAL SKILLS (REQUIRED):\n";
Expand Down Expand Up @@ -322,9 +290,7 @@ function main() {
console.error(`Error: ${error.message}`);

if (error.message.includes("ENOENT")) {
console.error(
"\nLikely cause: skill-rules.json not found or project directory incorrect",
);
console.error("\nLikely cause: skill-rules.json not found or project directory incorrect");
console.error(`Project dir: ${getProjectDir()}`);
}

Expand Down
25 changes: 3 additions & 22 deletions .claude/skills/skill-rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,7 @@
"priority": "high",
"description": "Rust documentation practices for HASH codebase. Use when writing doc comments, documenting functions/types/traits/modules, creating error sections, using intra-doc links, or following rustdoc conventions.",
"promptTriggers": {
"keywords": [
"rustdoc",
"doc comment",
"documentation",
"intra-doc link"
],
"keywords": ["rustdoc", "doc comment", "documentation", "intra-doc link"],
"intentPatterns": [
"\\bdocument(ing|ation)?\\b.*?\\b(rust|function|type|struct|enum|trait|module)\\b",
"\\b(write|add|create)\\b.*?\\bdoc\\s*comment\\b",
Expand Down Expand Up @@ -142,15 +137,7 @@
"priority": "high",
"description": "Git workflow for HASH including branch naming, PR creation, and PR reviews. Use when creating branches, making commits, opening pull requests, or reviewing PRs.",
"promptTriggers": {
"keywords": [
"git",
"branch",
"pull request",
"PR",
"commit",
"merge",
"review"
],
"keywords": ["git", "branch", "pull request", "PR", "commit", "merge", "review"],
"intentPatterns": [
"\\b(create|open|submit|review)\\b.*?\\b(PR|pull request|branch)\\b",
"\\b(name|naming)\\b.*?\\bbranch\\b",
Expand Down Expand Up @@ -214,13 +201,7 @@
"priority": "high",
"description": "Guide for creating effective Agent Skills. Use when users want to create a new skill (or update an existing skill) that extends an AI agent's capabilities with specialized knowledge, workflows, or tool integrations. Covers skill structure, YAML frontmatter, trigger configuration, and the 500-line rule.",
"promptTriggers": {
"keywords": [
"skill",
"skill-rules",
"SKILL.md",
"creating skill",
"writing skill"
],
"keywords": ["skill", "skill-rules", "SKILL.md", "creating skill", "writing skill"],
"intentPatterns": [
"\\b(how do|how does|explain)\\b.*?\\bskill\\b",
"\\b(create|add|modify|build|write)\\b.*?\\bskill\\b",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,7 @@ From `libs/@local/hashql/hir/tests/ui/lower/graph-hoisting/hoist.jsonc`:
[
"::graph::body::filter",
["::graph::head::entities", ["::graph::tmp::decision_time_now"]],
[
"fn",
{ "#tuple": [] },
{ "#struct": { "vertex": "_" } },
"_",
["==", "a", "b"],
],
["fn", { "#tuple": [] }, { "#struct": { "vertex": "_" } }, "_", ["==", "a", "b"]],
],
],
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,7 @@ Create sum types by combining newtypes with union types:
"let",
"value",
["Some", { "#literal": 42 }],
[
"if",
["==", "value", ["None"]],
{ "#literal": "empty" },
{ "#literal": "has value" },
],
["if", ["==", "value", ["None"]], { "#literal": "empty" }, { "#literal": "has value" }],
],
],
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ Use `:` prefix for named/labeled arguments.
**Object syntax:**

```jsonc
[
"greet",
{ ":name": { "#literal": "Alice" }, ":greeting": { "#literal": "Hello" } },
]
["greet", { ":name": { "#literal": "Alice" }, ":greeting": { "#literal": "Hello" } }]
```

**Shorthand string syntax:**
Expand Down
7 changes: 1 addition & 6 deletions .config/_examples/vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
{
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
"files.associations": {
"turbo.json": "jsonc",
".sqlfluff": "toml",
Expand Down
7 changes: 1 addition & 6 deletions .config/_examples/zed/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
"file_types": {
"TOML": [".sqlfluff"],
"JSONC": ["turbo.json"],
"Git Ignore": [
".prettierignore",
".markdownlintignore",
".dockerignore",
".sqlfluffignore"
]
"Git Ignore": [".prettierignore", ".markdownlintignore", ".dockerignore", ".sqlfluffignore"]
},
"auto_install_extensions": {
"oxc": true
Expand Down
5 changes: 1 addition & 4 deletions .config/agents/rules/zod.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ Zod v4 stores metadata in registries (primarily `z.globalRegistry`). Use `.meta(

```typescript
// βœ… Correct - .meta() at end of chain
z.string()
.min(1)
.max(100)
.meta({ description: "User's full name", label: "Name" });
z.string().min(1).max(100).meta({ description: "User's full name", label: "Name" });

// βœ… Correct - .describe() shorthand for description only
z.string().email().describe("Primary email address");
Expand Down
14 changes: 3 additions & 11 deletions apps/hash-ai-worker-ts/scripts/compare-llm-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import { getLlmResponse } from "../src/activities/shared/get-llm-response.js";
import { graphApiClient } from "../src/activities/shared/graph-api-client.js";
import { getAliceUserAccountId } from "../src/shared/testing-utilities/get-alice-user-account-id.js";

import type {
LlmParams,
LlmResponse,
} from "../src/activities/shared/get-llm-response/types.js";
import type { LlmParams, LlmResponse } from "../src/activities/shared/get-llm-response/types.js";
import type { CompareLlmResponseConfig } from "./compare-llm-response/types.js";
import type { WebId } from "@blockprotocol/type-system";

Expand All @@ -36,9 +33,7 @@ const getCompareLlmResponseConfig = async (params: {
};

if (!module.config) {
throw new Error(
`No config object exported in the file: ${configFilePath}`,
);
throw new Error(`No config object exported in the file: ${configFilePath}`);
}

return module.config;
Expand All @@ -62,10 +57,7 @@ const persistCompareLlmResponses = (params: {

const resultsFileName = `${resultsDirectory}/${now.toISOString()}.json`;

writeFileSync(
resultsFileName,
JSON.stringify({ llmParams, llmResponses }, null, 2),
);
writeFileSync(resultsFileName, JSON.stringify({ llmParams, llmResponses }, null, 2));
};

export const compareLlmResponses = async () => {
Expand Down
4 changes: 1 addition & 3 deletions apps/hash-ai-worker-ts/scripts/sanitize-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ const __dirname = path.dirname(__filename);
const url = process.argv[2] as Url;

if (!url) {
console.error(
"No URL provided – usage: `yarn sanitize https://example.com'`",
);
console.error("No URL provided – usage: `yarn sanitize https://example.com'`");
process.exit(1);
}

Expand Down
Loading
Loading