@iceinvein/agent-skills 0.1.16 → 0.1.17
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/dist/cli/index.js +158 -3
- package/package.json +6 -2
- package/skills/terse/SKILL.md +20 -2
- package/skills/terse/skill.json +7 -2
package/dist/cli/index.js
CHANGED
|
@@ -657,6 +657,111 @@ async function updateAllSkills(cwd) {
|
|
|
657
657
|
return results;
|
|
658
658
|
}
|
|
659
659
|
|
|
660
|
+
// src/cli/commands/bump.ts
|
|
661
|
+
import { join as join7 } from "node:path";
|
|
662
|
+
|
|
663
|
+
// src/cli/semver.ts
|
|
664
|
+
function bumpVersion(current, level) {
|
|
665
|
+
const parts = current.split(".");
|
|
666
|
+
if (parts.length !== 3 || parts.some((p) => !/^\d+$/.test(p))) {
|
|
667
|
+
throw new Error(`Invalid semver version: '${current}'`);
|
|
668
|
+
}
|
|
669
|
+
const [major, minor, patch] = parts.map(Number);
|
|
670
|
+
switch (level) {
|
|
671
|
+
case "major":
|
|
672
|
+
return `${major + 1}.0.0`;
|
|
673
|
+
case "minor":
|
|
674
|
+
return `${major}.${minor + 1}.0`;
|
|
675
|
+
case "patch":
|
|
676
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// src/cli/commands/bump.ts
|
|
681
|
+
async function bumpSkill(repoRoot, skillName, level) {
|
|
682
|
+
const manifestPath = join7(repoRoot, "skills", skillName, "skill.json");
|
|
683
|
+
const file = Bun.file(manifestPath);
|
|
684
|
+
if (!await file.exists()) {
|
|
685
|
+
return { ok: false, error: `Skill '${skillName}' not found at skills/${skillName}/skill.json` };
|
|
686
|
+
}
|
|
687
|
+
const manifest = await file.json();
|
|
688
|
+
const from = manifest.version;
|
|
689
|
+
let to;
|
|
690
|
+
try {
|
|
691
|
+
to = bumpVersion(from, level);
|
|
692
|
+
} catch (e) {
|
|
693
|
+
return { ok: false, error: `Invalid version '${from}' in skills/${skillName}/skill.json` };
|
|
694
|
+
}
|
|
695
|
+
manifest.version = to;
|
|
696
|
+
await Bun.write(manifestPath, JSON.stringify(manifest, null, 2) + `
|
|
697
|
+
`);
|
|
698
|
+
return { ok: true, from, to };
|
|
699
|
+
}
|
|
700
|
+
function getLatestTag(repoRoot) {
|
|
701
|
+
const result = Bun.spawnSync(["git", "describe", "--tags", "--abbrev=0"], {
|
|
702
|
+
cwd: repoRoot
|
|
703
|
+
});
|
|
704
|
+
if (result.exitCode !== 0)
|
|
705
|
+
return null;
|
|
706
|
+
return result.stdout.toString().trim();
|
|
707
|
+
}
|
|
708
|
+
var EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
709
|
+
function getChangedSkills(repoRoot, sinceTag) {
|
|
710
|
+
const base = sinceTag ?? EMPTY_TREE;
|
|
711
|
+
const args = ["git", "diff", "--name-only", base, "HEAD", "--", "skills/"];
|
|
712
|
+
const result = Bun.spawnSync(args, { cwd: repoRoot });
|
|
713
|
+
const output = result.stdout.toString().trim();
|
|
714
|
+
if (!output)
|
|
715
|
+
return new Set;
|
|
716
|
+
const names = new Set;
|
|
717
|
+
for (const line of output.split(`
|
|
718
|
+
`)) {
|
|
719
|
+
const parts = line.split("/");
|
|
720
|
+
if (parts.length >= 2 && parts[0] === "skills") {
|
|
721
|
+
names.add(parts[1]);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return names;
|
|
725
|
+
}
|
|
726
|
+
function skillVersionChanged(repoRoot, skillName, sinceTag) {
|
|
727
|
+
const base = sinceTag ?? EMPTY_TREE;
|
|
728
|
+
const args = ["git", "diff", base, "HEAD", "--", `skills/${skillName}/skill.json`];
|
|
729
|
+
const result = Bun.spawnSync(args, { cwd: repoRoot });
|
|
730
|
+
const diff = result.stdout.toString();
|
|
731
|
+
const hasRemoved = diff.split(`
|
|
732
|
+
`).some((l) => l.startsWith("-") && !l.startsWith("---") && l.includes('"version"'));
|
|
733
|
+
const hasAdded = diff.split(`
|
|
734
|
+
`).some((l) => l.startsWith("+") && !l.startsWith("+++") && l.includes('"version"'));
|
|
735
|
+
return hasRemoved && hasAdded;
|
|
736
|
+
}
|
|
737
|
+
async function bumpAllChanged(repoRoot, level, dryRun) {
|
|
738
|
+
const tag = getLatestTag(repoRoot);
|
|
739
|
+
const changed = getChangedSkills(repoRoot, tag);
|
|
740
|
+
const results = [];
|
|
741
|
+
for (const skillName of changed) {
|
|
742
|
+
if (skillVersionChanged(repoRoot, skillName, tag))
|
|
743
|
+
continue;
|
|
744
|
+
if (dryRun) {
|
|
745
|
+
const manifestPath = join7(repoRoot, "skills", skillName, "skill.json");
|
|
746
|
+
const file = Bun.file(manifestPath);
|
|
747
|
+
if (!await file.exists())
|
|
748
|
+
continue;
|
|
749
|
+
const manifest = await file.json();
|
|
750
|
+
const from = manifest.version;
|
|
751
|
+
try {
|
|
752
|
+
const to = bumpVersion(from, level);
|
|
753
|
+
results.push({ name: skillName, ok: true, from, to });
|
|
754
|
+
} catch {
|
|
755
|
+
results.push({ name: skillName, ok: false, error: `Invalid version '${from}'` });
|
|
756
|
+
}
|
|
757
|
+
} else {
|
|
758
|
+
const result = await bumpSkill(repoRoot, skillName, level);
|
|
759
|
+
results.push({ name: skillName, ...result });
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
return results;
|
|
763
|
+
}
|
|
764
|
+
|
|
660
765
|
// src/cli/update-check.ts
|
|
661
766
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
662
767
|
async function checkForUpdates(cwd) {
|
|
@@ -730,7 +835,7 @@ Select (comma-separated numbers, e.g. 1,3): `);
|
|
|
730
835
|
|
|
731
836
|
// src/cli/index.ts
|
|
732
837
|
import { mkdirSync as mkdirSync4 } from "fs";
|
|
733
|
-
import { join as
|
|
838
|
+
import { join as join8 } from "path";
|
|
734
839
|
import { homedir } from "os";
|
|
735
840
|
function resolveInstallDir(flags) {
|
|
736
841
|
if (flags.global !== undefined || flags.g !== undefined) {
|
|
@@ -738,7 +843,7 @@ function resolveInstallDir(flags) {
|
|
|
738
843
|
}
|
|
739
844
|
return process.cwd();
|
|
740
845
|
}
|
|
741
|
-
var BOOLEAN_FLAGS = new Set(["global", "g", "all"]);
|
|
846
|
+
var BOOLEAN_FLAGS = new Set(["global", "g", "all", "dry-run"]);
|
|
742
847
|
function parseArgs(argv) {
|
|
743
848
|
if (argv.length === 0)
|
|
744
849
|
return { command: "help", args: [], flags: {} };
|
|
@@ -772,12 +877,15 @@ Usage:
|
|
|
772
877
|
agent-skills remove <skill> [-g] Remove a skill
|
|
773
878
|
agent-skills update <skill> [-g] Update a skill
|
|
774
879
|
agent-skills update --all [-g] Update all installed skills
|
|
880
|
+
agent-skills bump <skill> [patch|minor|major] Bump a skill's version
|
|
881
|
+
agent-skills bump --all [patch|minor|major] Bump all changed skills
|
|
775
882
|
agent-skills list List available skills
|
|
776
883
|
agent-skills info <skill> Show skill details
|
|
777
884
|
|
|
778
885
|
Flags:
|
|
779
886
|
--tool <tool> Install for a specific tool (${TOOL_NAMES2.join(", ")})
|
|
780
887
|
-g, --global Install to home directory (available in all projects)
|
|
888
|
+
--dry-run With bump --all: check without writing (exit 1 if unbumped)
|
|
781
889
|
`);
|
|
782
890
|
}
|
|
783
891
|
function printInstalled(result, skipped) {
|
|
@@ -838,7 +946,7 @@ async function main() {
|
|
|
838
946
|
gemini: ".gemini"
|
|
839
947
|
};
|
|
840
948
|
if (dirs[tool]) {
|
|
841
|
-
mkdirSync4(
|
|
949
|
+
mkdirSync4(join8(installDir, dirs[tool]), { recursive: true });
|
|
842
950
|
}
|
|
843
951
|
}
|
|
844
952
|
} else {
|
|
@@ -943,6 +1051,53 @@ ${m.name} v${m.version}`);
|
|
|
943
1051
|
console.log(` Package: ${m.mcp.package}`);
|
|
944
1052
|
break;
|
|
945
1053
|
}
|
|
1054
|
+
case "bump": {
|
|
1055
|
+
const BUMP_LEVELS = ["patch", "minor", "major"];
|
|
1056
|
+
const repoRoot = import.meta.dir.replace(/\/dist\/cli$|\/src\/cli$/, "");
|
|
1057
|
+
if (flags.all !== undefined) {
|
|
1058
|
+
const levelArg = args[0] ?? "patch";
|
|
1059
|
+
if (!BUMP_LEVELS.includes(levelArg)) {
|
|
1060
|
+
console.error(`Error: invalid bump level '${levelArg}'. Must be one of: ${BUMP_LEVELS.join(", ")}`);
|
|
1061
|
+
process.exit(1);
|
|
1062
|
+
}
|
|
1063
|
+
const dryRun = flags["dry-run"] !== undefined;
|
|
1064
|
+
const results = await bumpAllChanged(repoRoot, levelArg, dryRun);
|
|
1065
|
+
if (results.length === 0) {
|
|
1066
|
+
if (!dryRun)
|
|
1067
|
+
console.log("All skill versions are up to date.");
|
|
1068
|
+
process.exit(0);
|
|
1069
|
+
}
|
|
1070
|
+
for (const r of results) {
|
|
1071
|
+
if (!r.ok) {
|
|
1072
|
+
console.error(` \u2717 ${r.name}: ${r.error}`);
|
|
1073
|
+
} else if (dryRun) {
|
|
1074
|
+
console.log(` needs bump: ${r.name} ${r.from} \u2192 ${r.to}`);
|
|
1075
|
+
} else {
|
|
1076
|
+
console.log(` \u2713 ${r.name} ${r.from} \u2192 ${r.to}`);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
if (dryRun)
|
|
1080
|
+
process.exit(1);
|
|
1081
|
+
break;
|
|
1082
|
+
}
|
|
1083
|
+
const skillName = args[0];
|
|
1084
|
+
if (!skillName) {
|
|
1085
|
+
console.error("Error: skill name required. Usage: agent-skills bump <skill> [patch|minor|major]");
|
|
1086
|
+
process.exit(1);
|
|
1087
|
+
}
|
|
1088
|
+
const level = args[1] ?? "patch";
|
|
1089
|
+
if (!BUMP_LEVELS.includes(level)) {
|
|
1090
|
+
console.error(`Error: invalid bump level '${args[1]}'. Must be one of: ${BUMP_LEVELS.join(", ")}`);
|
|
1091
|
+
process.exit(1);
|
|
1092
|
+
}
|
|
1093
|
+
const result = await bumpSkill(repoRoot, skillName, level);
|
|
1094
|
+
if (!result.ok) {
|
|
1095
|
+
console.error(`Error: ${result.error}`);
|
|
1096
|
+
process.exit(1);
|
|
1097
|
+
}
|
|
1098
|
+
console.log(`\u2713 ${skillName} ${result.from} \u2192 ${result.to}`);
|
|
1099
|
+
break;
|
|
1100
|
+
}
|
|
946
1101
|
case "help":
|
|
947
1102
|
default:
|
|
948
1103
|
printHelp();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iceinvein/agent-skills",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Install agent skills into AI coding tools",
|
|
5
5
|
"author": "iceinvein",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,7 +15,11 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "bun build src/cli/index.ts --outdir dist/cli --target bun",
|
|
17
17
|
"test": "bun test",
|
|
18
|
-
"dev": "bun run src/cli/index.ts"
|
|
18
|
+
"dev": "bun run src/cli/index.ts",
|
|
19
|
+
"skill:bump": "bun run src/cli/index.ts bump",
|
|
20
|
+
"skill:bump:all": "bun run src/cli/index.ts bump --all",
|
|
21
|
+
"skill:bump:check": "bun run src/cli/index.ts bump --all --dry-run",
|
|
22
|
+
"release": "bash scripts/release.sh"
|
|
19
23
|
},
|
|
20
24
|
"keywords": [
|
|
21
25
|
"ai",
|
package/skills/terse/SKILL.md
CHANGED
|
@@ -36,9 +36,27 @@ Every response, cut these patterns:
|
|
|
36
36
|
- Kill: [explanation] "So in summary, what we did was update the middleware to validate tokens correctly, which should fix the authentication issue."
|
|
37
37
|
- Write: [explanation ends]
|
|
38
38
|
|
|
39
|
-
**Narrating actions** — don't announce what you're about to do. Just do it.
|
|
39
|
+
**Narrating actions** — don't announce what you're about to do. Just do it. The tool call is the communication. Never preface a tool call with text explaining that you're about to make it.
|
|
40
40
|
- Kill: "Let me take a look at the file for you. I'll read it now and analyze what's going on."
|
|
41
|
-
-
|
|
41
|
+
- Kill: "Now let me fix that issue."
|
|
42
|
+
- Kill: "Let me check the tests."
|
|
43
|
+
- Kill: "I'll update the config next."
|
|
44
|
+
- Kill: "We need to update the schema first."
|
|
45
|
+
- Kill: "First, I'll read the file to understand the structure."
|
|
46
|
+
- Write: [tool call — no preamble]
|
|
47
|
+
|
|
48
|
+
**Banned action-narration openers** — these phrases before a tool call are always filler. Cut them 100% of the time:
|
|
49
|
+
- "Let me..." / "Now let me..." / "Now I'll..."
|
|
50
|
+
- "I'll..." / "I need to..." / "We need to..."
|
|
51
|
+
- "First, let me..." / "Next, I'll..."
|
|
52
|
+
- "Going to..." / "I'm going to..."
|
|
53
|
+
- "Time to..." / "Let's..."
|
|
54
|
+
|
|
55
|
+
If context is needed between tool calls, state the *finding* or *decision*, not the action:
|
|
56
|
+
- Kill: "Now let me update the handler to fix this."
|
|
57
|
+
- Write: "The handler is missing the null check." [edits file]
|
|
58
|
+
- Kill: "Let me run the tests to verify."
|
|
59
|
+
- Write: [runs tests]
|
|
42
60
|
|
|
43
61
|
**Over-explaining the obvious** — don't describe trivial operations.
|
|
44
62
|
- Kill: "I'll create a new file called `utils.ts`. This file will contain utility functions that we can reuse across the project."
|
package/skills/terse/skill.json
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "terse",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Professional output compression — proper grammar, no fluff, ~50-60% fewer tokens. Three levels: clean, tight, sharp.",
|
|
5
5
|
"author": "iceinvein",
|
|
6
6
|
"type": "prompt",
|
|
7
|
-
"tools": [
|
|
7
|
+
"tools": [
|
|
8
|
+
"claude",
|
|
9
|
+
"cursor",
|
|
10
|
+
"codex",
|
|
11
|
+
"gemini"
|
|
12
|
+
],
|
|
8
13
|
"files": {
|
|
9
14
|
"prompt": "SKILL.md"
|
|
10
15
|
},
|