semantu-agents 1.0.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/README.md +62 -0
- package/cli.mjs +122 -0
- package/package.json +22 -0
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# semantu-agents
|
|
2
|
+
|
|
3
|
+
Reusable Claude Code skills and hooks for Semantu projects.
|
|
4
|
+
|
|
5
|
+
The npm package is a thin CLI that clones this private repo — no skill files are shipped on npm.
|
|
6
|
+
|
|
7
|
+
## Project setup
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx semantu-agents
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Clones the agents repo into `packages/skills/`, patches `package.json` and `.gitignore`, then syncs skills to `.claude/skills/` and `.agents/skills/`. Skips gracefully without repo access.
|
|
14
|
+
|
|
15
|
+
Add to `package.json` so it runs on setup:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"scripts": {
|
|
20
|
+
"setup": "npx semantu-agents"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Global setup
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx semantu-agents --global
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Clones the repo into `~/.agents-src/` and syncs skills to `~/.claude/skills/` and `~/.agents/skills/`. This makes skills available to Claude Code and Codex across all projects without per-repo setup.
|
|
32
|
+
|
|
33
|
+
## Editing skills
|
|
34
|
+
|
|
35
|
+
Edit directly in `packages/skills/skills/`, then commit and push:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cd packages/skills
|
|
39
|
+
git checkout -b my-change
|
|
40
|
+
# edit skills...
|
|
41
|
+
git add -A && git commit -m "improve workflow skill"
|
|
42
|
+
git push -u origin my-change
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
To re-sync after editing:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm run sync:agents
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Skills
|
|
52
|
+
|
|
53
|
+
| Skill | Purpose |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `workflow` | Enforces the mode cadence: ideation → plan → tasks → implementation → review → wrapup |
|
|
56
|
+
| `ideation` | Explore and compare implementation options |
|
|
57
|
+
| `plan` | Convert decisions into a concrete architecture plan |
|
|
58
|
+
| `tasks` | Break a plan into phased tasks with validation criteria |
|
|
59
|
+
| `implementation` | Execute tasks phase-by-phase with commits and validation |
|
|
60
|
+
| `review` | Review work against intent, readiness, and gaps |
|
|
61
|
+
| `wrapup` | Cleanup, changesets, and PR preparation |
|
|
62
|
+
| `automatic` | Run the full workflow without manual mode transitions |
|
package/cli.mjs
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* semantu-agents — thin CLI that clones the private agents repo and syncs skills.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx semantu-agents — clone repo into packages/skills/, sync to project
|
|
8
|
+
* npx semantu-agents --global — clone repo into ~/.agents-src/, sync to ~/.claude/ and ~/.agents/
|
|
9
|
+
*
|
|
10
|
+
* Skips gracefully if the user lacks repo access.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync} from 'node:fs';
|
|
14
|
+
import {homedir} from 'node:os';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import {execSync} from 'node:child_process';
|
|
17
|
+
|
|
18
|
+
const skillsRepo = 'git@github.com:Semantu/agents.git';
|
|
19
|
+
|
|
20
|
+
function run(cmd, opts) {
|
|
21
|
+
return execSync(cmd, {stdio: 'inherit', ...opts});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function cloneOrPull(dir) {
|
|
25
|
+
if (existsSync(path.join(dir, '.git'))) {
|
|
26
|
+
console.log('Updating skills repo...');
|
|
27
|
+
run('git pull --ff-only', {cwd: dir});
|
|
28
|
+
} else {
|
|
29
|
+
console.log('Cloning skills repo...');
|
|
30
|
+
run(`git clone ${skillsRepo} ${dir}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function syncSkills(skillsSource, targets) {
|
|
35
|
+
for (const dest of targets) {
|
|
36
|
+
rmSync(dest, {recursive: true, force: true});
|
|
37
|
+
mkdirSync(path.dirname(dest), {recursive: true});
|
|
38
|
+
cpSync(skillsSource, dest, {recursive: true});
|
|
39
|
+
console.log(`Synced skills -> ${dest}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function setupGlobal() {
|
|
44
|
+
const home = homedir();
|
|
45
|
+
const srcDir = path.join(home, '.agents-src');
|
|
46
|
+
|
|
47
|
+
cloneOrPull(srcDir);
|
|
48
|
+
|
|
49
|
+
const skillsSource = path.join(srcDir, 'skills');
|
|
50
|
+
syncSkills(skillsSource, [
|
|
51
|
+
path.join(home, '.claude', 'skills'),
|
|
52
|
+
path.join(home, '.agents', 'skills'),
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
console.log('\nDone. Skills synced globally to ~/.claude/skills/ and ~/.agents/skills/');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function setupProject() {
|
|
59
|
+
const projectRoot = process.cwd();
|
|
60
|
+
const skillsDir = path.join(projectRoot, 'packages', 'skills');
|
|
61
|
+
|
|
62
|
+
cloneOrPull(skillsDir);
|
|
63
|
+
|
|
64
|
+
// Patch package.json scripts
|
|
65
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
66
|
+
if (existsSync(pkgPath)) {
|
|
67
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
68
|
+
const scripts = pkg.scripts || {};
|
|
69
|
+
let changed = false;
|
|
70
|
+
|
|
71
|
+
if (!scripts['sync:agents']) {
|
|
72
|
+
scripts['sync:agents'] = 'node packages/skills/sync.mjs';
|
|
73
|
+
changed = true;
|
|
74
|
+
}
|
|
75
|
+
if (!scripts['setup'] || scripts['setup'] === 'npx semantu-agents') {
|
|
76
|
+
scripts['setup'] = 'npx semantu-agents';
|
|
77
|
+
changed = true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (changed) {
|
|
81
|
+
pkg.scripts = scripts;
|
|
82
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
83
|
+
console.log('Updated package.json scripts');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Patch .gitignore
|
|
88
|
+
const ignorePath = path.join(projectRoot, '.gitignore');
|
|
89
|
+
const ignoreEntries = ['packages/', '.claude/', '.agents/'];
|
|
90
|
+
let ignoreContent = existsSync(ignorePath) ? readFileSync(ignorePath, 'utf8') : '';
|
|
91
|
+
let ignoreChanged = false;
|
|
92
|
+
|
|
93
|
+
for (const entry of ignoreEntries) {
|
|
94
|
+
if (!ignoreContent.split('\n').some(line => line.trim() === entry)) {
|
|
95
|
+
ignoreContent = ignoreContent.trimEnd() + '\n' + entry + '\n';
|
|
96
|
+
ignoreChanged = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (ignoreChanged) {
|
|
101
|
+
writeFileSync(ignorePath, ignoreContent);
|
|
102
|
+
console.log('Updated .gitignore');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Sync from the cloned repo
|
|
106
|
+
run('node sync.mjs', {cwd: skillsDir});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// --- Main ---
|
|
110
|
+
|
|
111
|
+
const isGlobal = process.argv.includes('--global') || process.argv.includes('-g');
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
if (isGlobal) {
|
|
115
|
+
setupGlobal();
|
|
116
|
+
} else {
|
|
117
|
+
setupProject();
|
|
118
|
+
}
|
|
119
|
+
} catch {
|
|
120
|
+
console.log('\nSkipping skills setup — could not access the skills repo.');
|
|
121
|
+
console.log("This is fine if you don't have access to github.com:Semantu/agents.");
|
|
122
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "semantu-agents",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Reusable Claude Code skills and hooks for Semantu projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"semantu-agents": "cli.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"cli.mjs"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"sync": "node sync.mjs"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@changesets/changelog-github": "^0.5.2",
|
|
20
|
+
"@changesets/cli": "^2.29.8"
|
|
21
|
+
}
|
|
22
|
+
}
|