@robot-inventor/agent-skills 1.0.1 → 1.2.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robot-inventor/agent-skills",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Roboin's personal collection of Agent Skills.",
|
|
5
5
|
"homepage": "https://github.com/Robot-Inventor/agent-skills#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
"type": "module",
|
|
16
16
|
"main": "./scripts/opencode.ts",
|
|
17
17
|
"files": ["./hooks/", "./skills/", "./scripts/"],
|
|
18
|
+
"engines": {
|
|
19
|
+
"opencode": ">=1.18.29"
|
|
20
|
+
},
|
|
18
21
|
"publishConfig": {
|
|
19
22
|
"access": "public",
|
|
20
23
|
"provenance": true
|
|
@@ -23,6 +26,9 @@
|
|
|
23
26
|
"ci:version": "changeset version && bun ./scripts/syncVersion.ts && git add .",
|
|
24
27
|
"ci:publish": "changeset publish"
|
|
25
28
|
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@opencode/plugin": "^2.0.15"
|
|
31
|
+
},
|
|
26
32
|
"devDependencies": {
|
|
27
33
|
"@changesets/changelog-github": "^1.0.0",
|
|
28
34
|
"@changesets/cli": "^3.0.0",
|
package/scripts/codex.ts
CHANGED
package/scripts/opencode.ts
CHANGED
|
@@ -1,26 +1,46 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { exists, readFile } from "node:fs/promises";
|
|
2
|
+
import { Plugin } from "@opencode/plugin";
|
|
3
|
+
import type { PluginModule } from "@opencode-ai/plugin";
|
|
2
4
|
import { SKILLS } from "./skills";
|
|
3
|
-
import { exists } from "node:fs/promises";
|
|
4
|
-
import { join } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { join } from "node:path";
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const skills = isWebProject ? SKILLS.web : SKILLS.nonWeb;
|
|
8
|
+
const selectSkills = async (directory: string) =>
|
|
9
|
+
(await exists(join(directory, "package.json"))) ? SKILLS.web : SKILLS.nonWeb;
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
config: async (config) => {
|
|
13
|
-
config.instructions ??= [];
|
|
11
|
+
const skillPath = (skill: string) => fileURLToPath(new URL(`../skills/${skill}/SKILL.md`, import.meta.url));
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const plugin = {
|
|
14
|
+
...Plugin.define({
|
|
15
|
+
id: "io.roboin.agent-skills",
|
|
16
|
+
async setup(ctx) {
|
|
17
|
+
const skills = await selectSkills(ctx.location.directory);
|
|
18
|
+
const instructions = await Promise.all(skills.map((skill) => readFile(skillPath(skill), "utf8")));
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
await ctx.session.hook("context", (event) => {
|
|
21
|
+
for (const text of instructions) {
|
|
22
|
+
event.system.push({ type: "text", text });
|
|
20
23
|
}
|
|
21
|
-
}
|
|
24
|
+
});
|
|
22
25
|
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
26
|
+
}),
|
|
27
|
+
async server({ directory }) {
|
|
28
|
+
const skills = await selectSkills(directory);
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
config: async (config) => {
|
|
32
|
+
config.instructions ??= [];
|
|
33
|
+
|
|
34
|
+
for (const skill of skills) {
|
|
35
|
+
const path = skillPath(skill);
|
|
36
|
+
|
|
37
|
+
if (!config.instructions.includes(path)) {
|
|
38
|
+
config.instructions.push(path);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
} as const satisfies PluginModule;
|
|
25
45
|
|
|
26
|
-
export
|
|
46
|
+
export default plugin;
|
package/scripts/syncVersion.ts
CHANGED
|
@@ -16,7 +16,7 @@ Before implementing a feature or fixing a bug, consider all options. Instead of
|
|
|
16
16
|
|
|
17
17
|
Also avoid bringing unnecessary complexity into your code. Carefully examine related processing to ensure there are no impossible conditional branches or unnecessary try-catch blocks. Check the type definitions and actual processing, and remove any impossible conditional branches. There is no need to wrap code in a new try-catch block if an exception is unlikely to occur normally or if a try-catch already exists inside the called function.
|
|
18
18
|
|
|
19
|
-
Flag excessive validation, overly defensive implementation, and unnecessary complexity that does not serve the code's intended purpose. For example, a function that opens product links for a specific website may only need to verify the hostname. Checking the pathname may add complexity without improving security. You might remove validation by defining the function argument as a type such as `https://example.com/product/{string}`, or by accepting only a product ID and constructing the link inside the function. These are examples, but you should look for simpler implementations of the same kind. Ask what purpose the code serves and whether the implementation contains only what that purpose requires.
|
|
19
|
+
Flag excessive validation, overly defensive implementation, unnecessary intermediate representation, and unnecessary complexity that does not serve the code's intended purpose. For example, a function that opens product links for a specific website may only need to verify the hostname. Checking the pathname may add complexity without improving security. You might remove validation by defining the function argument as a type such as `https://example.com/product/{string}`, or by accepting only a product ID and constructing the link inside the function. These are examples, but you should look for simpler implementations of the same kind. Ask what purpose the code serves and whether the implementation contains only what that purpose requires.
|
|
20
20
|
|
|
21
21
|
## Avoid reinventing the wheel
|
|
22
22
|
|
|
@@ -114,10 +114,31 @@ if (myArray.length) {...}
|
|
|
114
114
|
|
|
115
115
|
The `max-lines` and `max-lines-per-function` rules exist as indicators of code readability and maintainability. Warnings for these rules suggest that your code design may be poor. Simply removing line breaks to meet the rules is a superficial solution and actually makes the code harder to read, thus violating the essence of the rules. Instead, you should fix the problem by removing redundant code or properly restructuring and modularizing it. If you've only slightly exceeded the limit and your code is already well-designed, you should disable the rules rather than removing line breaks or forcing splits.
|
|
116
116
|
|
|
117
|
-
###
|
|
117
|
+
### Do not validate it yourself
|
|
118
118
|
|
|
119
119
|
TypeScript types are not just an afterthought to JavaScript. Designing with types in mind keeps your code clean and efficient. With proper type design, validation is rarely needed except at project boundaries such as user input or web API responses. When code is properly designed based on types, function inputs and outputs are reliable, eliminating the need to validate values repeatedly.
|
|
120
120
|
|
|
121
|
+
Check the project dependencies to see if a validation library is installed. If one is installed, you should leverage the library's features rather than writing your own validator.
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
// Incorrect
|
|
125
|
+
const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
126
|
+
const isParson = (value: unknown): value is Person => isRecord(value) && typeof value.name === "string" && typeof value.age === "number" && value.age >= 0;
|
|
127
|
+
|
|
128
|
+
isParson(externalValue) ? externalValue : "Unknown";
|
|
129
|
+
|
|
130
|
+
// Correct
|
|
131
|
+
import { type } from "arktype";
|
|
132
|
+
|
|
133
|
+
const Person = type({
|
|
134
|
+
name: "string",
|
|
135
|
+
age: "number >= 0"
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const parsed = Person(externalValue);
|
|
139
|
+
parsed instanceof type.errors ? "Unknown" : parsed;
|
|
140
|
+
```
|
|
141
|
+
|
|
121
142
|
## CSS
|
|
122
143
|
|
|
123
144
|
### Define only the necessary styles
|
|
@@ -126,10 +147,48 @@ When writing CSS, first check if a reset CSS is loaded into your project and if
|
|
|
126
147
|
|
|
127
148
|
In CSS, you should only specify properties that need to be changed from the parent element, and you should not specify properties that do not need to be changed again. Remember that CSS has inheritance, and style accordingly.
|
|
128
149
|
|
|
150
|
+
```css
|
|
151
|
+
/* reset.css */
|
|
152
|
+
* {
|
|
153
|
+
margin: 0;
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```css
|
|
158
|
+
/* style.css */
|
|
159
|
+
|
|
160
|
+
/* Incorrect */
|
|
161
|
+
h1 {
|
|
162
|
+
margin: 0;
|
|
163
|
+
font-weight: bold;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
h1 div {
|
|
167
|
+
font-weight: bold;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Correct */
|
|
171
|
+
h1 {
|
|
172
|
+
font-weight: bold;
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
129
176
|
### Intentional typography design
|
|
130
177
|
|
|
131
178
|
Do not specify `font-family` outside the document root unless absolutely necessary, such as in code blocks. Also, as a general rule, do not change the font size unless there is a clear reason, such as making unimportant notices smaller or headings larger. Since the base font size may be overridden by browser settings, use `em` or `rem` instead of `px` for font size or areas that depend on font size.
|
|
132
179
|
|
|
180
|
+
```css
|
|
181
|
+
/* Incorrect */
|
|
182
|
+
h1 {
|
|
183
|
+
font-size: 32px;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* Correct */
|
|
187
|
+
h1 {
|
|
188
|
+
font-size: 2rem;
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
133
192
|
## HTML and JSX
|
|
134
193
|
|
|
135
194
|
### Avoid redundant definitions
|