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.
Files changed (3) hide show
  1. package/README.md +62 -0
  2. package/cli.mjs +122 -0
  3. 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
+ }