homingo 0.1.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.
Files changed (112) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/LICENSE +68 -0
  3. package/README.md +249 -0
  4. package/dist/commands/audit.d.ts +14 -0
  5. package/dist/commands/audit.d.ts.map +1 -0
  6. package/dist/commands/audit.js +178 -0
  7. package/dist/commands/audit.js.map +1 -0
  8. package/dist/commands/init.d.ts +2 -0
  9. package/dist/commands/init.d.ts.map +1 -0
  10. package/dist/commands/init.js +240 -0
  11. package/dist/commands/init.js.map +1 -0
  12. package/dist/commands/lint.d.ts +20 -0
  13. package/dist/commands/lint.d.ts.map +1 -0
  14. package/dist/commands/lint.js +490 -0
  15. package/dist/commands/lint.js.map +1 -0
  16. package/dist/commands/logs.d.ts +8 -0
  17. package/dist/commands/logs.d.ts.map +1 -0
  18. package/dist/commands/logs.js +67 -0
  19. package/dist/commands/logs.js.map +1 -0
  20. package/dist/config.d.ts +8 -0
  21. package/dist/config.d.ts.map +1 -0
  22. package/dist/config.js +67 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +54 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/providers/anthropic.d.ts +7 -0
  29. package/dist/providers/anthropic.d.ts.map +1 -0
  30. package/dist/providers/anthropic.js +29 -0
  31. package/dist/providers/anthropic.js.map +1 -0
  32. package/dist/providers/index.d.ts +20 -0
  33. package/dist/providers/index.d.ts.map +1 -0
  34. package/dist/providers/index.js +43 -0
  35. package/dist/providers/index.js.map +1 -0
  36. package/dist/providers/openai.d.ts +7 -0
  37. package/dist/providers/openai.d.ts.map +1 -0
  38. package/dist/providers/openai.js +32 -0
  39. package/dist/providers/openai.js.map +1 -0
  40. package/dist/providers/tracked-provider.d.ts +15 -0
  41. package/dist/providers/tracked-provider.d.ts.map +1 -0
  42. package/dist/providers/tracked-provider.js +26 -0
  43. package/dist/providers/tracked-provider.js.map +1 -0
  44. package/dist/providers/types.d.ts +23 -0
  45. package/dist/providers/types.d.ts.map +1 -0
  46. package/dist/providers/types.js +2 -0
  47. package/dist/providers/types.js.map +1 -0
  48. package/dist/reporting/html-renderer.d.ts +26 -0
  49. package/dist/reporting/html-renderer.d.ts.map +1 -0
  50. package/dist/reporting/html-renderer.js +549 -0
  51. package/dist/reporting/html-renderer.js.map +1 -0
  52. package/dist/reporting/logs-viewer.d.ts +12 -0
  53. package/dist/reporting/logs-viewer.d.ts.map +1 -0
  54. package/dist/reporting/logs-viewer.js +221 -0
  55. package/dist/reporting/logs-viewer.js.map +1 -0
  56. package/dist/reporting/opener.d.ts +9 -0
  57. package/dist/reporting/opener.d.ts.map +1 -0
  58. package/dist/reporting/opener.js +49 -0
  59. package/dist/reporting/opener.js.map +1 -0
  60. package/dist/reporting/run-metadata.d.ts +55 -0
  61. package/dist/reporting/run-metadata.d.ts.map +1 -0
  62. package/dist/reporting/run-metadata.js +61 -0
  63. package/dist/reporting/run-metadata.js.map +1 -0
  64. package/dist/reporting/storage.d.ts +27 -0
  65. package/dist/reporting/storage.d.ts.map +1 -0
  66. package/dist/reporting/storage.js +126 -0
  67. package/dist/reporting/storage.js.map +1 -0
  68. package/dist/rewriter/rewriter.d.ts +21 -0
  69. package/dist/rewriter/rewriter.d.ts.map +1 -0
  70. package/dist/rewriter/rewriter.js +63 -0
  71. package/dist/rewriter/rewriter.js.map +1 -0
  72. package/dist/shadow-router/generator.d.ts +14 -0
  73. package/dist/shadow-router/generator.d.ts.map +1 -0
  74. package/dist/shadow-router/generator.js +58 -0
  75. package/dist/shadow-router/generator.js.map +1 -0
  76. package/dist/shadow-router/pair-selector.d.ts +17 -0
  77. package/dist/shadow-router/pair-selector.d.ts.map +1 -0
  78. package/dist/shadow-router/pair-selector.js +146 -0
  79. package/dist/shadow-router/pair-selector.js.map +1 -0
  80. package/dist/shadow-router/scorer.d.ts +4 -0
  81. package/dist/shadow-router/scorer.d.ts.map +1 -0
  82. package/dist/shadow-router/scorer.js +169 -0
  83. package/dist/shadow-router/scorer.js.map +1 -0
  84. package/dist/shadow-router/simulator.d.ts +17 -0
  85. package/dist/shadow-router/simulator.d.ts.map +1 -0
  86. package/dist/shadow-router/simulator.js +64 -0
  87. package/dist/shadow-router/simulator.js.map +1 -0
  88. package/dist/shard/analyzer.d.ts +28 -0
  89. package/dist/shard/analyzer.d.ts.map +1 -0
  90. package/dist/shard/analyzer.js +146 -0
  91. package/dist/shard/analyzer.js.map +1 -0
  92. package/dist/shard/writer.d.ts +11 -0
  93. package/dist/shard/writer.d.ts.map +1 -0
  94. package/dist/shard/writer.js +53 -0
  95. package/dist/shard/writer.js.map +1 -0
  96. package/dist/skills/parser.d.ts +3 -0
  97. package/dist/skills/parser.d.ts.map +1 -0
  98. package/dist/skills/parser.js +48 -0
  99. package/dist/skills/parser.js.map +1 -0
  100. package/dist/types.d.ts +83 -0
  101. package/dist/types.d.ts.map +1 -0
  102. package/dist/types.js +2 -0
  103. package/dist/types.js.map +1 -0
  104. package/dist/utils/concurrency.d.ts +2 -0
  105. package/dist/utils/concurrency.d.ts.map +1 -0
  106. package/dist/utils/concurrency.js +14 -0
  107. package/dist/utils/concurrency.js.map +1 -0
  108. package/dist/utils/retry.d.ts +7 -0
  109. package/dist/utils/retry.d.ts.map +1 -0
  110. package/dist/utils/retry.js +44 -0
  111. package/dist/utils/retry.js.map +1 -0
  112. package/package.json +88 -0
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Heuristic indicators of multi-intent descriptions:
3
+ * - Multiple semicolons suggest distinct responsibility sections
4
+ * - Many commas with conjunctions suggest a laundry list of capabilities
5
+ * - Descriptions over 1024 chars are likely trying to do too much
6
+ */
7
+ const OVERLOAD_CHAR_THRESHOLD = 1024;
8
+ const MULTI_INTENT_SEMICOLONS = 2;
9
+ const MULTI_INTENT_CLAUSES = 4;
10
+ export class ShardAnalyzer {
11
+ provider;
12
+ model;
13
+ constructor(options) {
14
+ this.provider = options.provider;
15
+ this.model = options.model;
16
+ }
17
+ /**
18
+ * Pure logic check — no API calls.
19
+ * Determines if a skill description is overloaded based on heuristics.
20
+ */
21
+ analyzeOverload(skill) {
22
+ const len = skill.description.length;
23
+ const reasons = [];
24
+ // Check character length
25
+ if (len > OVERLOAD_CHAR_THRESHOLD) {
26
+ reasons.push(`description is ${len} chars (threshold: ${OVERLOAD_CHAR_THRESHOLD})`);
27
+ }
28
+ // Count semicolons as intent separators
29
+ const semicolonCount = (skill.description.match(/;/g) || []).length;
30
+ if (semicolonCount >= MULTI_INTENT_SEMICOLONS) {
31
+ reasons.push(`${semicolonCount} semicolons suggest multiple distinct responsibilities`);
32
+ }
33
+ // Count independent clauses (sentences or clauses separated by periods/conjunctions)
34
+ const sentenceCount = skill.description
35
+ .split(/[.!]/)
36
+ .map((s) => s.trim())
37
+ .filter((s) => s.length > 20).length;
38
+ if (sentenceCount >= MULTI_INTENT_CLAUSES) {
39
+ reasons.push(`${sentenceCount} distinct clauses suggest scope overload`);
40
+ }
41
+ // Check for "and" + verb patterns suggesting multiple responsibilities
42
+ const andVerbPattern = /\band\s+(also\s+)?(handles?|processes?|manages?|generates?|creates?|analyzes?)/gi;
43
+ const andVerbMatches = skill.description.match(andVerbPattern) || [];
44
+ if (andVerbMatches.length >= 2) {
45
+ reasons.push(`multiple "and [verb]" patterns suggest combined responsibilities`);
46
+ }
47
+ const isOverloaded = reasons.length > 0;
48
+ return {
49
+ isOverloaded,
50
+ reason: isOverloaded ? reasons.join("; ") : "Description is within acceptable scope",
51
+ descriptionLength: len,
52
+ };
53
+ }
54
+ /**
55
+ * Uses the configured LLM to analyze the skill and generate a shard plan.
56
+ * Identifies distinct intents and proposes sub-skills + orchestrator.
57
+ */
58
+ async generateShardPlan(skill) {
59
+ const prompt = `You are an AI skill architect. A skill's description determines how an LLM router selects it. The following skill description is overloaded — it covers too many distinct intents, which causes routing confusion.
60
+
61
+ SKILL TO SHARD:
62
+ Name: "${skill.name}"
63
+ Description: "${skill.description}"
64
+
65
+ Analyze the description and:
66
+ 1. Identify the distinct intents/responsibilities (2-4 groups)
67
+ 2. Propose sub-skills, each focused on one intent group
68
+ 3. Generate an orchestrator skill that delegates to the sub-skills
69
+
70
+ Naming convention:
71
+ - Sub-skills: "${skill.name}-{intent-suffix}" (e.g., "${skill.name}-analysis", "${skill.name}-generation")
72
+ - Orchestrator: "${skill.name}-orchestrator"
73
+
74
+ Requirements for each sub-skill:
75
+ - Description must be under 512 characters
76
+ - Include 1-3 negative triggers ("Does NOT handle...")
77
+ - Each sub-skill should be clearly distinct from the others
78
+
79
+ Requirements for the orchestrator:
80
+ - Description explains it delegates to the sub-skills
81
+ - Lists what each sub-skill handles
82
+ - Include negative triggers for tasks none of the sub-skills handle
83
+
84
+ Return JSON only. No markdown fences, no preamble.
85
+ {
86
+ "identifiedIntents": ["intent1 description", "intent2 description"],
87
+ "subSkills": [
88
+ {
89
+ "name": "skill-name-suffix",
90
+ "description": "focused description under 512 chars",
91
+ "intents": ["which intents this covers"],
92
+ "negativeTriggers": ["Does NOT handle X"]
93
+ }
94
+ ],
95
+ "orchestrator": {
96
+ "name": "skill-name-orchestrator",
97
+ "description": "orchestrator description",
98
+ "intents": ["delegates to sub-skills for all intents"],
99
+ "negativeTriggers": ["Does NOT handle X directly"]
100
+ }
101
+ }`;
102
+ const { text } = await this.provider.createMessage({
103
+ model: this.model,
104
+ maxTokens: 2048,
105
+ messages: [{ role: "user", content: prompt }],
106
+ });
107
+ let parsed;
108
+ try {
109
+ parsed = JSON.parse(text);
110
+ }
111
+ catch {
112
+ throw new Error(`Failed to parse shard plan response: ${text.slice(0, 200)}`);
113
+ }
114
+ // Validate response structure
115
+ if (!parsed.identifiedIntents ||
116
+ !parsed.subSkills ||
117
+ !parsed.orchestrator ||
118
+ parsed.subSkills.length < 2) {
119
+ throw new Error("Invalid shard plan: need at least 2 sub-skills");
120
+ }
121
+ const subSkills = parsed.subSkills.map((s) => ({
122
+ name: s.name,
123
+ description: s.description,
124
+ role: "sub-skill",
125
+ intents: s.intents,
126
+ negativeTriggers: s.negativeTriggers || [],
127
+ }));
128
+ const orchestrator = {
129
+ name: parsed.orchestrator.name,
130
+ description: parsed.orchestrator.description,
131
+ role: "orchestrator",
132
+ intents: parsed.orchestrator.intents,
133
+ negativeTriggers: parsed.orchestrator.negativeTriggers || [],
134
+ };
135
+ const overloadResult = this.analyzeOverload(skill);
136
+ return {
137
+ originalSkill: skill,
138
+ reason: overloadResult.reason,
139
+ descriptionLength: skill.description.length,
140
+ identifiedIntents: parsed.identifiedIntents,
141
+ subSkills,
142
+ orchestrator,
143
+ };
144
+ }
145
+ }
146
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/shard/analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ShardPlan } from "../types.js";
2
+ export interface WriteResult {
3
+ filesWritten: string[];
4
+ }
5
+ /**
6
+ * Writes shard plan to disk as SKILL.md files.
7
+ * Creates one directory per sub-skill + one for the orchestrator.
8
+ * Does NOT delete the original skill — the user does that manually.
9
+ */
10
+ export declare function writeShardPlan(plan: ShardPlan, outputDir: string): WriteResult;
11
+ //# sourceMappingURL=writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/shard/writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,aAAa,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAc9E"}
@@ -0,0 +1,53 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ /**
4
+ * Writes shard plan to disk as SKILL.md files.
5
+ * Creates one directory per sub-skill + one for the orchestrator.
6
+ * Does NOT delete the original skill — the user does that manually.
7
+ */
8
+ export function writeShardPlan(plan, outputDir) {
9
+ const filesWritten = [];
10
+ // Write each sub-skill
11
+ for (const subSkill of plan.subSkills) {
12
+ const filePath = writeSkillFile(subSkill, outputDir);
13
+ filesWritten.push(filePath);
14
+ }
15
+ // Write the orchestrator
16
+ const orchestratorPath = writeSkillFile(plan.orchestrator, outputDir);
17
+ filesWritten.push(orchestratorPath);
18
+ return { filesWritten };
19
+ }
20
+ function writeSkillFile(skill, outputDir) {
21
+ const skillDir = join(outputDir, skill.name);
22
+ mkdirSync(skillDir, { recursive: true });
23
+ const negativeTriggerLines = skill.negativeTriggers.length > 0
24
+ ? `\n${skill.negativeTriggers.map((t) => `- ${t}`).join("\n")}\n`
25
+ : "";
26
+ const roleLabel = skill.role === "orchestrator" ? "Orchestrator" : "Sub-skill";
27
+ const titleName = skill.name
28
+ .split("-")
29
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
30
+ .join(" ");
31
+ const content = `---
32
+ name: ${skill.name}
33
+ description: "${escapeYamlString(skill.description)}"
34
+ ---
35
+
36
+ # ${titleName}
37
+
38
+ ${skill.description}
39
+
40
+ ## Role
41
+ ${roleLabel}
42
+
43
+ ## Intents
44
+ ${skill.intents.map((i) => `- ${i}`).join("\n")}
45
+ ${negativeTriggerLines ? `\n## Negative Triggers${negativeTriggerLines}` : ""}`;
46
+ const filePath = join(skillDir, "SKILL.md");
47
+ writeFileSync(filePath, content);
48
+ return filePath;
49
+ }
50
+ function escapeYamlString(str) {
51
+ return str.replace(/"/g, '\\"');
52
+ }
53
+ //# sourceMappingURL=writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/shard/writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAOjC;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAe,EAAE,SAAiB;IAC/D,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,uBAAuB;IACvB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACrD,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED,yBAAyB;IACzB,MAAM,gBAAgB,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACtE,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAEpC,OAAO,EAAE,YAAY,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,KAAmB,EAAE,SAAiB;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,oBAAoB,GACxB,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;QAC/B,CAAC,CAAC,KAAK,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QACjE,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC;IAC/E,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI;SACzB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClD,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,MAAM,OAAO,GAAG;QACV,KAAK,CAAC,IAAI;gBACF,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC;;;IAG/C,SAAS;;EAEX,KAAK,CAAC,WAAW;;;EAGjB,SAAS;;;EAGT,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;EAC7C,oBAAoB,CAAC,CAAC,CAAC,yBAAyB,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAE9E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC5C,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW;IACnC,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Skill } from "../types.js";
2
+ export declare function parseSkills(skillsDir: string): Promise<Skill[]>;
3
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/skills/parser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAezC,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CA0CrE"}
@@ -0,0 +1,48 @@
1
+ import { readFileSync, existsSync, readdirSync } from "node:fs";
2
+ import { resolve, dirname, basename, join } from "node:path";
3
+ import matter from "gray-matter";
4
+ function findSkillFiles(dir) {
5
+ const results = [];
6
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
7
+ const fullPath = join(dir, entry.name);
8
+ if (entry.isDirectory()) {
9
+ results.push(...findSkillFiles(fullPath));
10
+ }
11
+ else if (entry.name === "SKILL.md") {
12
+ results.push(fullPath);
13
+ }
14
+ }
15
+ return results;
16
+ }
17
+ export async function parseSkills(skillsDir) {
18
+ const resolvedDir = resolve(skillsDir);
19
+ if (!existsSync(resolvedDir)) {
20
+ throw new Error(`Skills directory not found: ${resolvedDir}`);
21
+ }
22
+ const skillFiles = findSkillFiles(resolvedDir);
23
+ if (skillFiles.length === 0) {
24
+ throw new Error(`No SKILL.md files found in ${resolvedDir}\n` +
25
+ "Expected structure: <skills-dir>/<skill-name>/SKILL.md");
26
+ }
27
+ const skills = [];
28
+ const warnings = [];
29
+ for (const filePath of skillFiles) {
30
+ const raw = readFileSync(filePath, "utf-8");
31
+ const { data } = matter(raw);
32
+ const name = data.name || basename(dirname(filePath));
33
+ const description = data.description || "";
34
+ if (!description) {
35
+ warnings.push(`Warning: ${name} has no description (${filePath})`);
36
+ }
37
+ skills.push({
38
+ name,
39
+ description,
40
+ filePath,
41
+ });
42
+ }
43
+ if (warnings.length > 0) {
44
+ console.warn(warnings.join("\n"));
45
+ }
46
+ return skills;
47
+ }
48
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/skills/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC5C,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB;IACjD,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,+BAA+B,WAAW,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAE/C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,8BAA8B,WAAW,IAAI;YAC3C,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAE7B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QAE3C,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,QAAQ,CAAC,IAAI,CAAC,YAAY,IAAI,wBAAwB,QAAQ,GAAG,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;YACV,IAAI;YACJ,WAAW;YACX,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,83 @@
1
+ export interface Skill {
2
+ name: string;
3
+ description: string;
4
+ filePath: string;
5
+ examples?: string[];
6
+ }
7
+ export interface PromptGeneratorInput {
8
+ targetSkill: Skill;
9
+ competingSkill: Skill;
10
+ count: number;
11
+ }
12
+ export interface GeneratedPrompt {
13
+ id: string;
14
+ text: string;
15
+ expectedSkill: string;
16
+ targetPair: [string, string];
17
+ ambiguityReason: string;
18
+ }
19
+ export interface RoutingDecision {
20
+ promptId: string;
21
+ promptText: string;
22
+ selectedSkill: string;
23
+ expectedSkill: string;
24
+ isCorrect: boolean;
25
+ confidence: "high" | "medium" | "low";
26
+ reasoning: string;
27
+ }
28
+ export interface PairConflictReport {
29
+ skillA: string;
30
+ skillB: string;
31
+ promptsTested: number;
32
+ routingAccuracy: number;
33
+ severityLevel: "LOW" | "MEDIUM" | "HIGH" | "CRITICAL";
34
+ misroutes: RoutingDecision[];
35
+ fragileCorrects: RoutingDecision[];
36
+ topFailurePattern: string;
37
+ recommendedAction: string;
38
+ }
39
+ export interface FleetAuditReport {
40
+ generatedAt: string;
41
+ modelUsed: string;
42
+ totalSkills: number;
43
+ totalPairsTested: number;
44
+ estimatedFleetErrorRate: number;
45
+ criticalPairs: PairConflictReport[];
46
+ highPairs: PairConflictReport[];
47
+ mediumPairs: PairConflictReport[];
48
+ lowPairs: PairConflictReport[];
49
+ topFiveOffenders: string[];
50
+ exportPath: string;
51
+ }
52
+ export interface ShardedSkill {
53
+ name: string;
54
+ description: string;
55
+ role: "sub-skill" | "orchestrator";
56
+ intents: string[];
57
+ negativeTriggers: string[];
58
+ }
59
+ export interface ShardPlan {
60
+ originalSkill: Skill;
61
+ reason: string;
62
+ descriptionLength: number;
63
+ identifiedIntents: string[];
64
+ subSkills: ShardedSkill[];
65
+ orchestrator: ShardedSkill;
66
+ }
67
+ export interface HomingoConfig {
68
+ anthropicApiKey?: string;
69
+ openaiApiKey?: string;
70
+ model: string;
71
+ skillsDir: string;
72
+ shadowRouter: {
73
+ promptsPerPair: number;
74
+ minPrompts: number;
75
+ accuracyThreshold: number;
76
+ maxIterations: number;
77
+ };
78
+ output: {
79
+ reportDir: string;
80
+ format: "json" | "markdown" | "both";
81
+ };
82
+ }
83
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare function pMap<T, R>(items: T[], fn: (item: T, index: number) => Promise<R>, concurrency: number): Promise<R[]>;
2
+ //# sourceMappingURL=concurrency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/utils/concurrency.ts"],"names":[],"mappings":"AAAA,wBAAsB,IAAI,CAAC,CAAC,EAAE,CAAC,EAC7B,KAAK,EAAE,CAAC,EAAE,EACV,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,EAAE,CAAC,CAed"}
@@ -0,0 +1,14 @@
1
+ export async function pMap(items, fn, concurrency) {
2
+ const results = new Array(items.length);
3
+ let nextIndex = 0;
4
+ async function worker() {
5
+ while (nextIndex < items.length) {
6
+ const index = nextIndex++;
7
+ results[index] = await fn(items[index], index);
8
+ }
9
+ }
10
+ const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => worker());
11
+ await Promise.all(workers);
12
+ return results;
13
+ }
14
+ //# sourceMappingURL=concurrency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/utils/concurrency.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,KAAU,EACV,EAA0C,EAC1C,WAAmB;IAEnB,MAAM,OAAO,GAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,UAAU,MAAM;QACnB,OAAO,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5F,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAE3B,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface RetryOptions {
2
+ maxRetries: number;
3
+ baseDelayMs: number;
4
+ maxDelayMs: number;
5
+ }
6
+ export declare function withRetry<T>(fn: () => Promise<T>, options?: Partial<RetryOptions>): Promise<T>;
7
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AA8BD,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,OAAO,CAAC,YAAY,CAAM,GAClC,OAAO,CAAC,CAAC,CAAC,CAmBZ"}
@@ -0,0 +1,44 @@
1
+ const DEFAULT_RETRY = {
2
+ maxRetries: 3,
3
+ baseDelayMs: 1000,
4
+ maxDelayMs: 30000,
5
+ };
6
+ function sleep(ms) {
7
+ return new Promise((resolve) => setTimeout(resolve, ms));
8
+ }
9
+ function isRetryable(error) {
10
+ if (error instanceof Error) {
11
+ const msg = error.message.toLowerCase();
12
+ // Rate limits, overloaded, network errors
13
+ if (msg.includes("rate") || msg.includes("429") || msg.includes("overloaded"))
14
+ return true;
15
+ if (msg.includes("529") || msg.includes("500") || msg.includes("503"))
16
+ return true;
17
+ if (msg.includes("econnreset") || msg.includes("etimedout") || msg.includes("fetch failed"))
18
+ return true;
19
+ }
20
+ // Check for status code on Anthropic API errors
21
+ const err = error;
22
+ if (err.status === 429 || err.status === 529 || err.status === 500 || err.status === 503)
23
+ return true;
24
+ return false;
25
+ }
26
+ export async function withRetry(fn, options = {}) {
27
+ const opts = { ...DEFAULT_RETRY, ...options };
28
+ for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
29
+ try {
30
+ return await fn();
31
+ }
32
+ catch (error) {
33
+ if (attempt === opts.maxRetries || !isRetryable(error)) {
34
+ throw error;
35
+ }
36
+ const delay = Math.min(opts.baseDelayMs * Math.pow(2, attempt), opts.maxDelayMs);
37
+ const jitter = delay * (0.5 + Math.random() * 0.5);
38
+ await sleep(jitter);
39
+ }
40
+ }
41
+ // Unreachable, but satisfies TypeScript
42
+ throw new Error("Retry exhausted");
43
+ }
44
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAMA,MAAM,aAAa,GAAiB;IAClC,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,KAAK;CAClB,CAAC;AAEF,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QACxC,0CAA0C;QAC1C,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3F,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACnF,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC;YACzF,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,gDAAgD;IAChD,MAAM,GAAG,GAAG,KAA4B,CAAC;IACzC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QACtF,OAAO,IAAI,CAAC;IAEd,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAoB,EACpB,UAAiC,EAAE;IAEnC,MAAM,IAAI,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAE9C,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QAC5D,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,KAAK,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YACjF,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;YACnD,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;AACrC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,88 @@
1
+ {
2
+ "name": "homingo",
3
+ "version": "0.1.0",
4
+ "description": "Homingo — the homing instinct for your AI skills. Detect, diagnose, and fix routing drift.",
5
+ "type": "module",
6
+ "license": "BUSL-1.1",
7
+ "author": "Ravi Y.",
8
+ "homepage": "https://github.com/homingo/homingo.github.io.git#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/homingo/homingo.github.io.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/homingo/homingo.github.io/issues"
15
+ },
16
+ "keywords": [
17
+ "ai",
18
+ "skills",
19
+ "routing",
20
+ "drift",
21
+ "lint",
22
+ "audit",
23
+ "llm",
24
+ "cli",
25
+ "devtools"
26
+ ],
27
+ "bin": {
28
+ "homingo": "./dist/index.js"
29
+ },
30
+ "main": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "files": [
33
+ "dist",
34
+ "LICENSE",
35
+ "README.md",
36
+ "CHANGELOG.md"
37
+ ],
38
+ "scripts": {
39
+ "build": "tsc",
40
+ "dev": "tsx src/index.ts",
41
+ "start": "node dist/index.js",
42
+ "typecheck": "tsc --noEmit",
43
+ "lint": "eslint src/",
44
+ "lint:fix": "eslint src/ --fix",
45
+ "format": "prettier --write \"src/**/*.ts\"",
46
+ "format:check": "prettier --check \"src/**/*.ts\"",
47
+ "test": "vitest run",
48
+ "test:watch": "vitest",
49
+ "prepare": "husky",
50
+ "docs:dev": "vitepress dev docs",
51
+ "docs:build": "vitepress build docs",
52
+ "docs:preview": "vitepress preview docs"
53
+ },
54
+ "lint-staged": {
55
+ "*.ts": [
56
+ "eslint --fix",
57
+ "prettier --write"
58
+ ]
59
+ },
60
+ "dependencies": {
61
+ "@anthropic-ai/sdk": "^0.39.0",
62
+ "@inquirer/prompts": "^8.3.0",
63
+ "chalk": "^5.4.1",
64
+ "cli-table3": "^0.6.5",
65
+ "commander": "^13.1.0",
66
+ "dotenv": "^17.3.1",
67
+ "gray-matter": "^4.0.3",
68
+ "openai": "^6.27.0",
69
+ "ora": "^8.2.0"
70
+ },
71
+ "devDependencies": {
72
+ "@eslint/js": "^10.0.1",
73
+ "@types/node": "^22.13.0",
74
+ "eslint": "^10.0.3",
75
+ "eslint-config-prettier": "^10.1.8",
76
+ "husky": "^9.1.7",
77
+ "lint-staged": "^16.3.3",
78
+ "prettier": "^3.8.1",
79
+ "tsx": "^4.19.0",
80
+ "typescript": "^5.7.0",
81
+ "typescript-eslint": "^8.57.0",
82
+ "vitepress": "^1.6.4",
83
+ "vitest": "^4.0.18"
84
+ },
85
+ "engines": {
86
+ "node": ">=20"
87
+ }
88
+ }