@alavida/agentpack 0.1.3 → 0.1.5
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 +24 -0
- package/package.json +6 -2
- package/skills/agentpack-cli/SKILL.md +22 -14
- package/skills/agentpack-cli/references/skill-lifecycle.md +13 -11
- package/skills/authoring-skillgraphs-from-knowledge/SKILL.md +37 -16
- package/skills/authoring-skillgraphs-from-knowledge/references/authored-metadata.md +4 -3
- package/skills/developing-and-testing-skills/SKILL.md +20 -2
- package/skills/getting-started-skillgraphs/SKILL.md +3 -3
- package/skills/identifying-skill-opportunities/SKILL.md +1 -1
- package/skills/maintaining-skillgraph-freshness/SKILL.md +1 -1
- package/skills/repairing-broken-skill-or-plugin-state/SKILL.md +5 -1
- package/skills/shipping-production-plugins-and-packages/SKILL.md +16 -8
- package/skills/sync-state.json +83 -0
- package/src/commands/skills.js +28 -10
- package/src/infrastructure/fs/dev-session-repository.js +25 -0
- package/src/infrastructure/runtime/materialize-skills.js +18 -1
- package/src/lib/skills.js +185 -4
package/README.md
CHANGED
|
@@ -253,6 +253,28 @@ Validate the shipped agent skill:
|
|
|
253
253
|
npm run intent:validate
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
+
## Releases
|
|
257
|
+
|
|
258
|
+
This repo now uses Changesets for versioning and publishing.
|
|
259
|
+
|
|
260
|
+
Normal maintainer flow:
|
|
261
|
+
|
|
262
|
+
1. Add a changeset in any PR that changes user-facing behavior.
|
|
263
|
+
2. Merge the feature PR to `main`.
|
|
264
|
+
3. Let GitHub open or update the `Version Packages` release PR.
|
|
265
|
+
4. Review and merge that release PR.
|
|
266
|
+
5. The merge publishes to npm automatically.
|
|
267
|
+
|
|
268
|
+
Useful local commands:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
npx changeset
|
|
272
|
+
npm run version-packages
|
|
273
|
+
npm run release
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Manual git tags are no longer the normal release path.
|
|
277
|
+
|
|
256
278
|
## Optional Agent Integration
|
|
257
279
|
|
|
258
280
|
This package also ships an agent-facing skill under:
|
|
@@ -273,10 +295,12 @@ In authoring repos:
|
|
|
273
295
|
|
|
274
296
|
- commit `.agentpack/build-state.json`
|
|
275
297
|
- commit `.agentpack/catalog.json`
|
|
298
|
+
- commit `skills/sync-state.json` when maintaining shipped Intent skills
|
|
276
299
|
|
|
277
300
|
In consumer/runtime repos:
|
|
278
301
|
|
|
279
302
|
- do not commit `.agentpack/install.json`
|
|
303
|
+
- do not commit `.agentpack/dev-session.json`
|
|
280
304
|
|
|
281
305
|
## License
|
|
282
306
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alavida/agentpack",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Package-backed skills lifecycle CLI for agent skills and plugins",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"agentpack": "bin/agentpack.js",
|
|
8
|
-
"intent": "
|
|
8
|
+
"intent": "bin/intent.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"bin",
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
"validate:live": "node scripts/live-validation.mjs",
|
|
20
20
|
"smoke:monorepo": "node scripts/smoke-monorepo.mjs",
|
|
21
21
|
"docs:dev": "cd docs && mint dev",
|
|
22
|
+
"changeset": "changeset",
|
|
23
|
+
"version-packages": "changeset version",
|
|
24
|
+
"release": "changeset publish",
|
|
22
25
|
"intent:validate": "npx @tanstack/intent validate",
|
|
23
26
|
"build:dashboard": "node scripts/build-dashboard.mjs"
|
|
24
27
|
},
|
|
@@ -51,6 +54,7 @@
|
|
|
51
54
|
"react-dom": "^19.1.1"
|
|
52
55
|
},
|
|
53
56
|
"devDependencies": {
|
|
57
|
+
"@changesets/cli": "^2.30.0",
|
|
54
58
|
"@tanstack/intent": "^0.0.14",
|
|
55
59
|
"esbuild": "^0.25.10"
|
|
56
60
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agentpack-cli
|
|
3
3
|
description: Use the agentpack CLI correctly when treating knowledge as a package. Apply the authored skill lifecycle, plugin lifecycle, source-backed validation, install flow, and bundled plugin artifact flow without mixing those stages together.
|
|
4
|
-
library_version: 0.1.
|
|
4
|
+
library_version: 0.1.4
|
|
5
5
|
sources:
|
|
6
6
|
- README.md
|
|
7
7
|
- docs/introduction.mdx
|
|
@@ -20,7 +20,8 @@ Use this skill when the user is working with `@alavida/agentpack` and needs the
|
|
|
20
20
|
|
|
21
21
|
Agentpack is a lifecycle toolchain for agent artifacts:
|
|
22
22
|
|
|
23
|
-
- a
|
|
23
|
+
- a package is the distribution unit
|
|
24
|
+
- an exported skill is the runtime module unit
|
|
24
25
|
- a plugin package is a deployable runtime shell
|
|
25
26
|
- source docs are the truth
|
|
26
27
|
- `SKILL.md` is the compiled agent-facing artifact
|
|
@@ -49,19 +50,20 @@ If a skill points at `domains/.../knowledge/*.md`, run `skills validate`, `skill
|
|
|
49
50
|
|
|
50
51
|
### 1. Authored packaged skill
|
|
51
52
|
|
|
52
|
-
Use when the user is creating or editing one
|
|
53
|
+
Use when the user is creating or editing one packaged skill module or a package that exports several skill modules.
|
|
53
54
|
|
|
54
55
|
Default flow:
|
|
55
56
|
|
|
56
|
-
- `agentpack skills inspect <
|
|
57
|
-
- `agentpack skills validate <
|
|
58
|
-
- `agentpack skills dev <
|
|
59
|
-
- `agentpack skills dev --no-dashboard <
|
|
57
|
+
- `agentpack skills inspect <target>`
|
|
58
|
+
- `agentpack skills validate <target>`
|
|
59
|
+
- `agentpack skills dev <target>` if local runtime testing is needed
|
|
60
|
+
- `agentpack skills dev --no-dashboard <target>` if the user wants to skip the local workbench
|
|
60
61
|
|
|
61
62
|
Key idea:
|
|
62
63
|
|
|
63
|
-
- `
|
|
64
|
-
- `
|
|
64
|
+
- `package.json.agentpack.skills` declares exported skill modules
|
|
65
|
+
- `SKILL.md.requires` is the source of truth for skill-to-skill edges
|
|
66
|
+
- `package.json.dependencies` is the managed cross-package mirror
|
|
65
67
|
- `validate` and `dev` sync dependencies automatically
|
|
66
68
|
- `skills validate` records the current source-hash snapshot in `.agentpack/build-state.json`
|
|
67
69
|
- `skills dev` materializes the compiled skill artifact for runtime use
|
|
@@ -71,11 +73,16 @@ Persistence rule:
|
|
|
71
73
|
- commit `.agentpack/build-state.json` so stale detection works across GitHub, CI, and teammate machines
|
|
72
74
|
- commit `.agentpack/catalog.json` in authoring repos
|
|
73
75
|
- do not commit `.agentpack/install.json`
|
|
76
|
+
- do not commit `.agentpack/dev-session.json`
|
|
77
|
+
- commit `skills/sync-state.json` when maintaining the shipped Intent skills for this package
|
|
74
78
|
|
|
75
79
|
Runtime notes:
|
|
76
80
|
|
|
77
81
|
- after `skills dev` writes to `.claude/skills/` or `.agents/skills/`, start a fresh agent session if the current one was already running
|
|
78
|
-
- `skills dev` starts a localhost workbench by default for one selected skill, with provenance edges,
|
|
82
|
+
- `skills dev` starts a localhost workbench by default for one selected exported skill, with provenance edges, internal module edges, cross-package dependency edges, and actions like validate or stale checks
|
|
83
|
+
- `skills dev` records the active session in `.agentpack/dev-session.json` so the next run can clean up stale runtime links after abnormal termination
|
|
84
|
+
- if a stale local dev session blocks startup, use `agentpack skills dev cleanup` and escalate to `agentpack skills dev cleanup --force` only when the recorded pid is a false positive
|
|
85
|
+
- use `agentpack skills unlink <root> --recursive` when you need to remove one active dev root plus its transitive local runtime links
|
|
79
86
|
- do not reload `metadata.sources` manually once the dev-linked skill exists; trust the compiled `SKILL.md` artifact unless you are explicitly updating the skill
|
|
80
87
|
- invoke the resulting skill through the runtime's skill mechanism, not by opening the file and reading it as plain text
|
|
81
88
|
|
|
@@ -87,7 +94,7 @@ Use when the skill is already published and the user wants it available in anoth
|
|
|
87
94
|
|
|
88
95
|
Default flow:
|
|
89
96
|
|
|
90
|
-
- `agentpack skills install <package-name>`
|
|
97
|
+
- `agentpack skills install <package-name-or-local-package-path>`
|
|
91
98
|
- `agentpack skills env`
|
|
92
99
|
|
|
93
100
|
Do not prescribe `skills dev` here unless the user is authoring locally.
|
|
@@ -119,8 +126,8 @@ Use when the source docs changed and the user needs to know whether the packaged
|
|
|
119
126
|
Default flow:
|
|
120
127
|
|
|
121
128
|
- `agentpack skills stale`
|
|
122
|
-
- `agentpack skills stale <
|
|
123
|
-
- `agentpack skills validate <
|
|
129
|
+
- `agentpack skills stale <target>`
|
|
130
|
+
- `agentpack skills validate <target>`
|
|
124
131
|
|
|
125
132
|
Key idea:
|
|
126
133
|
|
|
@@ -133,7 +140,8 @@ When the user is reasoning about the model itself, explain agentpack this way:
|
|
|
133
140
|
|
|
134
141
|
- docs or knowledge files are source files
|
|
135
142
|
- `SKILL.md` is the compiled artifact
|
|
136
|
-
- `package.json` is the
|
|
143
|
+
- `package.json` is the package manifest and export table
|
|
144
|
+
- canonical skill ids look like `@scope/package:skill-name`
|
|
137
145
|
- install and materialization are the runtime-resolution step
|
|
138
146
|
- staleness means the source changed after the last known compiled state
|
|
139
147
|
|
|
@@ -7,10 +7,11 @@ Use this reference when the user needs the methodology behind packaged skills, n
|
|
|
7
7
|
A packaged skill is a reusable capability artifact.
|
|
8
8
|
|
|
9
9
|
- source docs or knowledge files are the truth
|
|
10
|
-
- `SKILL.md` is the authored agent artifact
|
|
10
|
+
- `SKILL.md` is the authored agent artifact for one exported skill module
|
|
11
11
|
- `package.json` is the package and distribution artifact
|
|
12
|
-
- `
|
|
13
|
-
- `
|
|
12
|
+
- `package.json.agentpack.skills` declares exported skill modules
|
|
13
|
+
- `requires` expresses direct skill dependencies using canonical ids like `@scope/package:skill-name`
|
|
14
|
+
- `package.json.dependencies` is the managed cross-package mirror of `requires`
|
|
14
15
|
|
|
15
16
|
This is closer to a compiler pipeline than a prompt file:
|
|
16
17
|
|
|
@@ -22,27 +23,28 @@ This is closer to a compiler pipeline than a prompt file:
|
|
|
22
23
|
|
|
23
24
|
## Single Source Of Truth
|
|
24
25
|
|
|
25
|
-
`SKILL.md.requires` is the dependency truth.
|
|
26
|
+
`SKILL.md.requires` is the dependency truth for skill-to-skill edges.
|
|
26
27
|
|
|
27
|
-
Do not tell the user to hand-maintain `package.json.dependencies` as the primary dependency source. Agentpack treats those dependencies as a compiled mirror.
|
|
28
|
+
Do not tell the user to hand-maintain `package.json.dependencies` as the primary dependency source. Agentpack treats those dependencies as a compiled package-level mirror for cross-package references.
|
|
28
29
|
|
|
29
30
|
Practical consequence:
|
|
30
31
|
|
|
31
32
|
- if `requires` changes, run `skills validate` or `skills dev`
|
|
32
|
-
- those commands sync
|
|
33
|
+
- those commands sync cross-package package dependencies automatically
|
|
34
|
+
- same-package module references do not create package dependency entries
|
|
33
35
|
|
|
34
36
|
## Local Authoring Flow
|
|
35
37
|
|
|
36
38
|
Use this when the user is creating or changing a packaged skill in the same repo as its source docs.
|
|
37
39
|
|
|
38
|
-
1. `agentpack skills inspect <
|
|
39
|
-
2. `agentpack skills validate <
|
|
40
|
-
3. `agentpack skills dev <
|
|
40
|
+
1. `agentpack skills inspect <target>`
|
|
41
|
+
2. `agentpack skills validate <target>`
|
|
42
|
+
3. `agentpack skills dev <target>` if the user wants agent runtime discovery during iteration
|
|
41
43
|
|
|
42
44
|
What each step means:
|
|
43
45
|
|
|
44
46
|
- `inspect` explains what the skill currently is
|
|
45
|
-
- `validate` checks package readiness, source existence, and records the validated source snapshot in `.agentpack/build-state.json`
|
|
47
|
+
- `validate` checks package readiness, exported skill declarations, source existence, canonical dependency resolution, and records the validated source snapshot in `.agentpack/build-state.json`
|
|
46
48
|
- `dev` links the skill into `.claude/skills/` and `.agents/skills/` for local testing
|
|
47
49
|
|
|
48
50
|
Important persistence behavior:
|
|
@@ -76,7 +78,7 @@ Authoring stage:
|
|
|
76
78
|
|
|
77
79
|
Consumption stage:
|
|
78
80
|
|
|
79
|
-
- package name
|
|
81
|
+
- package name or local package path
|
|
80
82
|
- installed from registry or tarball
|
|
81
83
|
- `skills install`
|
|
82
84
|
- `skills env`
|
|
@@ -3,7 +3,7 @@ name: authoring-skillgraphs-from-knowledge
|
|
|
3
3
|
description: Use when authoring packaged skills from source knowledge with valid SKILL.md metadata, package.json release fields, provenance sources, and requires edges in agentpack.
|
|
4
4
|
type: core
|
|
5
5
|
library: agentpack
|
|
6
|
-
library_version: "0.1.
|
|
6
|
+
library_version: "0.1.4"
|
|
7
7
|
sources:
|
|
8
8
|
- "alavida-ai/agentpack:docs/commands.mdx"
|
|
9
9
|
- "alavida-ai/agentpack:docs/architecture.mdx"
|
|
@@ -22,14 +22,22 @@ metadata:
|
|
|
22
22
|
sources:
|
|
23
23
|
- domains/value/knowledge/selling-points.md
|
|
24
24
|
requires:
|
|
25
|
-
- @alavida
|
|
25
|
+
- "@alavida/methodology:gary-provost"
|
|
26
26
|
---
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
```json
|
|
30
30
|
{
|
|
31
|
-
"name": "@alavida
|
|
31
|
+
"name": "@alavida/value-copywriting",
|
|
32
32
|
"version": "1.0.0",
|
|
33
|
+
"files": ["skills"],
|
|
34
|
+
"agentpack": {
|
|
35
|
+
"skills": {
|
|
36
|
+
"value-copywriting": {
|
|
37
|
+
"path": "skills/value-copywriting/SKILL.md"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
33
41
|
"repository": {
|
|
34
42
|
"type": "git",
|
|
35
43
|
"url": "git+https://github.com/alavida-ai/knowledge-base.git"
|
|
@@ -37,9 +45,8 @@ requires:
|
|
|
37
45
|
"publishConfig": {
|
|
38
46
|
"registry": "https://npm.pkg.github.com"
|
|
39
47
|
},
|
|
40
|
-
"files": ["SKILL.md"],
|
|
41
48
|
"dependencies": {
|
|
42
|
-
"@alavida
|
|
49
|
+
"@alavida/methodology": "^1.0.0"
|
|
43
50
|
}
|
|
44
51
|
}
|
|
45
52
|
```
|
|
@@ -50,20 +57,20 @@ requires:
|
|
|
50
57
|
|
|
51
58
|
```yaml
|
|
52
59
|
requires:
|
|
53
|
-
- @alavida
|
|
60
|
+
- "@alavida/methodology:gary-provost"
|
|
54
61
|
```
|
|
55
62
|
|
|
56
63
|
### Validate to sync and record provenance
|
|
57
64
|
|
|
58
65
|
```bash
|
|
59
|
-
agentpack skills validate domains/value/skills/copywriting
|
|
66
|
+
agentpack skills validate domains/value/skills/value-copywriting
|
|
60
67
|
```
|
|
61
68
|
|
|
62
69
|
### Inspect by path or package name
|
|
63
70
|
|
|
64
71
|
```bash
|
|
65
|
-
agentpack skills inspect domains/value/skills/copywriting
|
|
66
|
-
agentpack skills inspect @alavida
|
|
72
|
+
agentpack skills inspect domains/value/skills/value-copywriting
|
|
73
|
+
agentpack skills inspect @alavida/value-copywriting:value-copywriting
|
|
67
74
|
```
|
|
68
75
|
|
|
69
76
|
## Common Mistakes
|
|
@@ -75,7 +82,7 @@ Wrong:
|
|
|
75
82
|
```json
|
|
76
83
|
{
|
|
77
84
|
"dependencies": {
|
|
78
|
-
"@alavida
|
|
85
|
+
"@alavida/methodology": "^1.0.0"
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
88
|
```
|
|
@@ -84,10 +91,10 @@ Correct:
|
|
|
84
91
|
|
|
85
92
|
```yaml
|
|
86
93
|
requires:
|
|
87
|
-
- @alavida
|
|
94
|
+
- "@alavida/methodology:gary-provost"
|
|
88
95
|
```
|
|
89
96
|
|
|
90
|
-
`requires` is the authored dependency truth; `package.json.dependencies` is the
|
|
97
|
+
`requires` is the authored dependency truth; `package.json.dependencies` is the managed cross-package mirror.
|
|
91
98
|
|
|
92
99
|
Source: skills/agentpack-cli/SKILL.md
|
|
93
100
|
|
|
@@ -105,11 +112,18 @@ Correct:
|
|
|
105
112
|
|
|
106
113
|
```json
|
|
107
114
|
{
|
|
108
|
-
"files": ["
|
|
115
|
+
"files": ["skills"],
|
|
116
|
+
"agentpack": {
|
|
117
|
+
"skills": {
|
|
118
|
+
"value-copywriting": {
|
|
119
|
+
"path": "skills/value-copywriting/SKILL.md"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
109
123
|
}
|
|
110
124
|
```
|
|
111
125
|
|
|
112
|
-
A package that excludes
|
|
126
|
+
A package that excludes its exported skill files is structurally invalid even if the authored source exists locally.
|
|
113
127
|
|
|
114
128
|
Source: docs/commands.mdx
|
|
115
129
|
|
|
@@ -119,7 +133,7 @@ Wrong:
|
|
|
119
133
|
|
|
120
134
|
```json
|
|
121
135
|
{
|
|
122
|
-
"name": "@alavida
|
|
136
|
+
"name": "@alavida/value-copywriting"
|
|
123
137
|
}
|
|
124
138
|
```
|
|
125
139
|
|
|
@@ -127,8 +141,15 @@ Correct:
|
|
|
127
141
|
|
|
128
142
|
```json
|
|
129
143
|
{
|
|
130
|
-
"name": "@alavida
|
|
144
|
+
"name": "@alavida/value-copywriting",
|
|
131
145
|
"version": "1.0.0",
|
|
146
|
+
"agentpack": {
|
|
147
|
+
"skills": {
|
|
148
|
+
"value-copywriting": {
|
|
149
|
+
"path": "skills/value-copywriting/SKILL.md"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
132
153
|
"repository": {
|
|
133
154
|
"type": "git",
|
|
134
155
|
"url": "git+https://github.com/alavida-ai/knowledge-base.git"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Authored Metadata
|
|
2
2
|
|
|
3
3
|
- `SKILL.md` owns `name`, `description`, `metadata.sources`, and `requires`
|
|
4
|
-
- `package.json` owns
|
|
5
|
-
- `
|
|
6
|
-
|
|
4
|
+
- `package.json.agentpack.skills` owns the exported skill map and each exported skill path
|
|
5
|
+
- `package.json` owns package-level distribution metadata such as package name, version, publish config, and repository
|
|
6
|
+
- `requires` uses canonical ids like `@scope/package:skill-name`
|
|
7
|
+
- `skills validate` syncs managed cross-package dependencies from `requires` and refreshes `.agentpack/build-state.json`
|
|
@@ -3,7 +3,7 @@ name: developing-and-testing-skills
|
|
|
3
3
|
description: Use when iterating locally on a packaged skill with agentpack skills dev, the localhost workbench, repo-local materialization, and runtime testing feedback loops.
|
|
4
4
|
type: core
|
|
5
5
|
library: agentpack
|
|
6
|
-
library_version: "0.1.
|
|
6
|
+
library_version: "0.1.3"
|
|
7
7
|
sources:
|
|
8
8
|
- "alavida-ai/agentpack:docs/commands.mdx"
|
|
9
9
|
- "alavida-ai/agentpack:docs/introduction.mdx"
|
|
@@ -30,7 +30,7 @@ agentpack skills dev domains/value/skills/copywriting
|
|
|
30
30
|
agentpack skills dev domains/value/skills/copywriting
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
This links the selected skill into `.claude/skills/` and `.agents/skills
|
|
33
|
+
This links the selected skill into `.claude/skills/` and `.agents/skills/`, records the active dev session in `.agentpack/dev-session.json`, and starts a localhost workbench by default.
|
|
34
34
|
|
|
35
35
|
### Use CLI-only mode when you explicitly do not want the dashboard
|
|
36
36
|
|
|
@@ -44,6 +44,24 @@ agentpack skills dev --no-dashboard domains/value/skills/copywriting
|
|
|
44
44
|
agentpack skills unlink value-copywriting
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
If the previous dev process was killed badly and left stale runtime links behind:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
agentpack skills dev cleanup
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If a wrapper-managed process left a false-positive live pid in `.agentpack/dev-session.json`:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
agentpack skills dev cleanup --force
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If you need to remove the active root plus its recorded transitive links in one shot:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
agentpack skills unlink value-copywriting --recursive
|
|
63
|
+
```
|
|
64
|
+
|
|
47
65
|
## Common Mistakes
|
|
48
66
|
|
|
49
67
|
### HIGH Expecting the current agent session to pick up new links
|
|
@@ -3,7 +3,7 @@ name: getting-started-skillgraphs
|
|
|
3
3
|
description: Use when starting from an empty repo or empty skillgraph and needing the first correct authoring loop, lifecycle framing, repo-root routing, and inspect/validate/dev command flow in agentpack.
|
|
4
4
|
type: lifecycle
|
|
5
5
|
library: agentpack
|
|
6
|
-
library_version: "0.1.
|
|
6
|
+
library_version: "0.1.4"
|
|
7
7
|
sources:
|
|
8
8
|
- "alavida-ai/agentpack:docs/introduction.mdx"
|
|
9
9
|
- "alavida-ai/agentpack:docs/commands.mdx"
|
|
@@ -46,7 +46,7 @@ agentpack skills dev domains/value/skills/copywriting
|
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
48
|
cd consumer-repo
|
|
49
|
-
agentpack skills install @alavida
|
|
49
|
+
agentpack skills install @alavida/value-copywriting
|
|
50
50
|
agentpack skills env
|
|
51
51
|
```
|
|
52
52
|
|
|
@@ -77,7 +77,7 @@ Source: docs/introduction.mdx
|
|
|
77
77
|
Wrong:
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
agentpack skills install @alavida
|
|
80
|
+
agentpack skills install @alavida/value-copywriting
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
Correct:
|
|
@@ -3,7 +3,7 @@ name: identifying-skill-opportunities
|
|
|
3
3
|
description: Use when deciding what raw knowledge should become a packaged skill, a reusable capability boundary, a requires edge, or a plugin-local wrapper in an agentpack skillgraph.
|
|
4
4
|
type: core
|
|
5
5
|
library: agentpack
|
|
6
|
-
library_version: "0.1.
|
|
6
|
+
library_version: "0.1.3"
|
|
7
7
|
sources:
|
|
8
8
|
- "alavida-ai/agentpack:docs/architecture.mdx"
|
|
9
9
|
- "alavida-ai/agentpack:docs/overview.mdx"
|
|
@@ -3,7 +3,7 @@ name: maintaining-skillgraph-freshness
|
|
|
3
3
|
description: Use when validating authored skills, checking stale state, and keeping build-state and catalog metadata aligned with changing knowledge in an agentpack skillgraph.
|
|
4
4
|
type: lifecycle
|
|
5
5
|
library: agentpack
|
|
6
|
-
library_version: "0.1.
|
|
6
|
+
library_version: "0.1.3"
|
|
7
7
|
sources:
|
|
8
8
|
- "alavida-ai/agentpack:docs/commands.mdx"
|
|
9
9
|
- "alavida-ai/agentpack:docs/current-state.mdx"
|
|
@@ -3,7 +3,7 @@ name: repairing-broken-skill-or-plugin-state
|
|
|
3
3
|
description: Use when auditing or repairing stale skills, unresolved requires, missing runtime dependencies, affected dependents, or malformed plugin definition files in agentpack.
|
|
4
4
|
type: lifecycle
|
|
5
5
|
library: agentpack
|
|
6
|
-
library_version: "0.1.
|
|
6
|
+
library_version: "0.1.3"
|
|
7
7
|
sources:
|
|
8
8
|
- "alavida-ai/agentpack:docs/current-state.mdx"
|
|
9
9
|
- "alavida-ai/agentpack:docs/commands.mdx"
|
|
@@ -100,11 +100,15 @@ Correct:
|
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
102
|
agentpack skills unlink value-copywriting
|
|
103
|
+
agentpack skills unlink value-copywriting --recursive
|
|
104
|
+
agentpack skills dev cleanup
|
|
103
105
|
agentpack skills install @alavida-ai/value-copywriting
|
|
104
106
|
```
|
|
105
107
|
|
|
106
108
|
Runtime state should be repaired through agentpack lifecycle commands, not direct edits under `.claude/skills` or `.agents/skills`.
|
|
107
109
|
|
|
110
|
+
Use `skills dev cleanup --force` only when a wrapper-managed process or pid reuse leaves a false-positive active session in `.agentpack/dev-session.json`.
|
|
111
|
+
|
|
108
112
|
Source: docs/architecture.mdx
|
|
109
113
|
|
|
110
114
|
## References
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: shipping-production-plugins-and-packages
|
|
3
|
-
description: Use when turning maintained skills into deployable bundled plugins or publishable
|
|
3
|
+
description: Use when turning maintained skills into deployable bundled plugins or publishable skill packages with explicit dependency closure, hooks, MCP tools, and production checks in agentpack.
|
|
4
4
|
type: core
|
|
5
5
|
library: agentpack
|
|
6
|
-
library_version: "0.1.
|
|
6
|
+
library_version: "0.1.4"
|
|
7
7
|
sources:
|
|
8
8
|
- "alavida-ai/agentpack:docs/commands.mdx"
|
|
9
9
|
- "alavida-ai/agentpack:docs/architecture.mdx"
|
|
@@ -26,13 +26,21 @@ agentpack plugin build plugins/website-dev
|
|
|
26
26
|
|
|
27
27
|
## Core Patterns
|
|
28
28
|
|
|
29
|
-
### Ship
|
|
29
|
+
### Ship one package for one reusable skill module
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
agentpack skills validate domains/value/skills/copywriting
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Use this when
|
|
35
|
+
Use this when one package should export one reusable skill module and does not need to ship bundled with hooks, MCP tools, or other runtime pieces.
|
|
36
|
+
|
|
37
|
+
### Ship one package that exports several related skill modules
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
agentpack skills validate domains/value/skills/pm-foundations
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Use this when several skills belong together as one package but still need to remain separate runtime modules through `package.json.agentpack.skills`.
|
|
36
44
|
|
|
37
45
|
### Bundle a production plugin when shipping several skills together
|
|
38
46
|
|
|
@@ -56,7 +64,7 @@ Wrong:
|
|
|
56
64
|
|
|
57
65
|
```yaml
|
|
58
66
|
requires:
|
|
59
|
-
- @alavida
|
|
67
|
+
- "@alavida/value-copywriting:value-copywriting"
|
|
60
68
|
```
|
|
61
69
|
|
|
62
70
|
```json
|
|
@@ -70,7 +78,7 @@ Correct:
|
|
|
70
78
|
```json
|
|
71
79
|
{
|
|
72
80
|
"devDependencies": {
|
|
73
|
-
"@alavida
|
|
81
|
+
"@alavida/value-copywriting": "^1.0.0"
|
|
74
82
|
}
|
|
75
83
|
}
|
|
76
84
|
```
|
|
@@ -110,11 +118,11 @@ Publish one packaged skill and assume hooks, MCP tools, and related skills ship
|
|
|
110
118
|
Correct:
|
|
111
119
|
|
|
112
120
|
```text
|
|
113
|
-
Use a
|
|
121
|
+
Use a skill package for one or many reusable skill modules
|
|
114
122
|
Use a bundled plugin when several skills, hooks, or MCP tools must ship together
|
|
115
123
|
```
|
|
116
124
|
|
|
117
|
-
|
|
125
|
+
Skill packages are reusable distribution units; exported skills are runtime modules; plugins are deployable runtime shells.
|
|
118
126
|
|
|
119
127
|
Source: README.md
|
|
120
128
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"skills": {
|
|
4
|
+
"agentpack-cli": {
|
|
5
|
+
"library_version": "0.1.3",
|
|
6
|
+
"synced_at": "2026-03-12T00:00:00.000Z",
|
|
7
|
+
"sources_sha": {
|
|
8
|
+
"README.md": "2680d4fa603b070e6bd92c162b3d172131b71c39c9dc39351ed452d95567b0bd",
|
|
9
|
+
"docs/introduction.mdx": "c1a8989382dc81a3a33dae1e8f243d159b92835a1999a8793741a25b317b455d",
|
|
10
|
+
"docs/overview.mdx": "48151b11dfef153223ba2aed7100eeeafc100c475694c98e053f9c4ffb025357",
|
|
11
|
+
"docs/architecture.mdx": "400617fb8ba4a5f09a78b998e3b1a01262caed05e0344206ca1f8fd71519ea22",
|
|
12
|
+
"docs/build-lifecycle.mdx": "0e697180c639a72514272e6421f900ac3d5248ecc09220409efc716bf0d4fa71",
|
|
13
|
+
"docs/commands.mdx": "5f2ec2839caa8a6758f36daaa150f6af8d3700e26b135333fad6a0719dacb05b",
|
|
14
|
+
"docs/current-state.mdx": "b4ad89e40706aff29bbe3149daeeb3feac6d07bb3ddfd4f164e630cd5b7997a8",
|
|
15
|
+
"docs/distribution.mdx": "060e47b28c3da13ff61e6b1b04e018beb8dc5d6ebd30b5a3d1574fceb289e3f4",
|
|
16
|
+
"docs/end-to-end-test-plan.md": "c1e37589660a438cb1a9742f68e769ed68f6f8849f1510d8445e99c2bff1ec21"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"authoring-skillgraphs-from-knowledge": {
|
|
20
|
+
"library_version": "0.1.3",
|
|
21
|
+
"synced_at": "2026-03-12T00:00:00.000Z",
|
|
22
|
+
"sources_sha": {
|
|
23
|
+
"alavida-ai/agentpack:docs/commands.mdx": "5f2ec2839caa8a6758f36daaa150f6af8d3700e26b135333fad6a0719dacb05b",
|
|
24
|
+
"alavida-ai/agentpack:docs/architecture.mdx": "400617fb8ba4a5f09a78b998e3b1a01262caed05e0344206ca1f8fd71519ea22",
|
|
25
|
+
"alavida-ai/agentpack:skills/agentpack-cli/SKILL.md": "54d9a43172ff6b7e7218bb9a9454b56d38233e9d1a6df9362e7167ceb9dc2249"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"developing-and-testing-skills": {
|
|
29
|
+
"library_version": "0.1.3",
|
|
30
|
+
"synced_at": "2026-03-12T00:00:00.000Z",
|
|
31
|
+
"sources_sha": {
|
|
32
|
+
"alavida-ai/agentpack:docs/commands.mdx": "5f2ec2839caa8a6758f36daaa150f6af8d3700e26b135333fad6a0719dacb05b",
|
|
33
|
+
"alavida-ai/agentpack:docs/introduction.mdx": "c1a8989382dc81a3a33dae1e8f243d159b92835a1999a8793741a25b317b455d",
|
|
34
|
+
"alavida-ai/agentpack:README.md": "2680d4fa603b070e6bd92c162b3d172131b71c39c9dc39351ed452d95567b0bd"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"getting-started-skillgraphs": {
|
|
38
|
+
"library_version": "0.1.3",
|
|
39
|
+
"synced_at": "2026-03-12T00:00:00.000Z",
|
|
40
|
+
"sources_sha": {
|
|
41
|
+
"alavida-ai/agentpack:docs/introduction.mdx": "c1a8989382dc81a3a33dae1e8f243d159b92835a1999a8793741a25b317b455d",
|
|
42
|
+
"alavida-ai/agentpack:docs/commands.mdx": "5f2ec2839caa8a6758f36daaa150f6af8d3700e26b135333fad6a0719dacb05b",
|
|
43
|
+
"alavida-ai/agentpack:README.md": "2680d4fa603b070e6bd92c162b3d172131b71c39c9dc39351ed452d95567b0bd"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"identifying-skill-opportunities": {
|
|
47
|
+
"library_version": "0.1.3",
|
|
48
|
+
"synced_at": "2026-03-12T00:00:00.000Z",
|
|
49
|
+
"sources_sha": {
|
|
50
|
+
"alavida-ai/agentpack:docs/architecture.mdx": "400617fb8ba4a5f09a78b998e3b1a01262caed05e0344206ca1f8fd71519ea22",
|
|
51
|
+
"alavida-ai/agentpack:docs/overview.mdx": "48151b11dfef153223ba2aed7100eeeafc100c475694c98e053f9c4ffb025357",
|
|
52
|
+
"alavida-ai/agentpack:skills/agentpack-cli/SKILL.md": "54d9a43172ff6b7e7218bb9a9454b56d38233e9d1a6df9362e7167ceb9dc2249"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"maintaining-skillgraph-freshness": {
|
|
56
|
+
"library_version": "0.1.3",
|
|
57
|
+
"synced_at": "2026-03-12T00:00:00.000Z",
|
|
58
|
+
"sources_sha": {
|
|
59
|
+
"alavida-ai/agentpack:docs/commands.mdx": "5f2ec2839caa8a6758f36daaa150f6af8d3700e26b135333fad6a0719dacb05b",
|
|
60
|
+
"alavida-ai/agentpack:docs/current-state.mdx": "b4ad89e40706aff29bbe3149daeeb3feac6d07bb3ddfd4f164e630cd5b7997a8",
|
|
61
|
+
"alavida-ai/agentpack:README.md": "2680d4fa603b070e6bd92c162b3d172131b71c39c9dc39351ed452d95567b0bd"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"repairing-broken-skill-or-plugin-state": {
|
|
65
|
+
"library_version": "0.1.3",
|
|
66
|
+
"synced_at": "2026-03-12T00:00:00.000Z",
|
|
67
|
+
"sources_sha": {
|
|
68
|
+
"alavida-ai/agentpack:docs/current-state.mdx": "b4ad89e40706aff29bbe3149daeeb3feac6d07bb3ddfd4f164e630cd5b7997a8",
|
|
69
|
+
"alavida-ai/agentpack:docs/commands.mdx": "5f2ec2839caa8a6758f36daaa150f6af8d3700e26b135333fad6a0719dacb05b",
|
|
70
|
+
"alavida-ai/agentpack:src/domain/plugins/load-plugin-definition.js": "3aac67288351229e878d0877097b41cd369cc594fc8683fccf2506b94a5f17e7"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"shipping-production-plugins-and-packages": {
|
|
74
|
+
"library_version": "0.1.3",
|
|
75
|
+
"synced_at": "2026-03-12T00:00:00.000Z",
|
|
76
|
+
"sources_sha": {
|
|
77
|
+
"alavida-ai/agentpack:docs/commands.mdx": "5f2ec2839caa8a6758f36daaa150f6af8d3700e26b135333fad6a0719dacb05b",
|
|
78
|
+
"alavida-ai/agentpack:docs/architecture.mdx": "400617fb8ba4a5f09a78b998e3b1a01262caed05e0344206ca1f8fd71519ea22",
|
|
79
|
+
"alavida-ai/agentpack:README.md": "2680d4fa603b070e6bd92c162b3d172131b71c39c9dc39351ed452d95567b0bd"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
package/src/commands/skills.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
installSkills,
|
|
12
12
|
listOutdatedSkills,
|
|
13
13
|
resolveInstallTargets,
|
|
14
|
+
cleanupSkillDevSession,
|
|
14
15
|
startSkillDev,
|
|
15
16
|
unlinkSkill,
|
|
16
17
|
uninstallSkills,
|
|
@@ -22,13 +23,16 @@ export function skillsCommand() {
|
|
|
22
23
|
const cmd = new Command('skills')
|
|
23
24
|
.description('Inspect and manage package-backed skills');
|
|
24
25
|
|
|
25
|
-
cmd
|
|
26
|
+
const devCmd = cmd
|
|
26
27
|
.command('dev')
|
|
27
28
|
.description('Link one local packaged skill for local Claude and agent discovery')
|
|
28
29
|
.option('--no-sync', 'Skip syncing managed package dependencies from requires')
|
|
29
30
|
.option('--no-dashboard', 'Skip starting the local skill development workbench')
|
|
30
|
-
.argument('
|
|
31
|
+
.argument('[target]', 'Packaged skill directory or SKILL.md path')
|
|
31
32
|
.action(async (target, opts, command) => {
|
|
33
|
+
if (!target) {
|
|
34
|
+
command.help({ error: true });
|
|
35
|
+
}
|
|
32
36
|
const globalOpts = command.optsWithGlobals();
|
|
33
37
|
const session = startSkillDev(target, {
|
|
34
38
|
sync: opts.sync,
|
|
@@ -70,23 +74,37 @@ export function skillsCommand() {
|
|
|
70
74
|
},
|
|
71
75
|
});
|
|
72
76
|
|
|
73
|
-
const stop = () => {
|
|
74
|
-
session.close();
|
|
75
|
-
process.exit(0);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
process.once('SIGTERM', stop);
|
|
79
|
-
process.once('SIGINT', stop);
|
|
80
77
|
await session.ready;
|
|
81
78
|
});
|
|
82
79
|
|
|
80
|
+
devCmd
|
|
81
|
+
.command('cleanup')
|
|
82
|
+
.description('Remove recorded skills dev links for a stale session')
|
|
83
|
+
.option('--force', 'Remove recorded links even if the session pid still appears alive')
|
|
84
|
+
.action((opts, command) => {
|
|
85
|
+
const globalOpts = command.optsWithGlobals();
|
|
86
|
+
const result = cleanupSkillDevSession({ force: opts.force });
|
|
87
|
+
|
|
88
|
+
if (globalOpts.json) {
|
|
89
|
+
output.json(result);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
output.write(`Cleaned: ${result.cleaned}`);
|
|
94
|
+
if (result.name) output.write(`Root Skill: ${result.name}`);
|
|
95
|
+
for (const removed of result.removed) {
|
|
96
|
+
output.write(`Removed: ${removed}`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
83
100
|
cmd
|
|
84
101
|
.command('unlink')
|
|
85
102
|
.description('Remove one locally linked skill from Claude and agent discovery paths')
|
|
103
|
+
.option('--recursive', 'Remove the active dev root and its recorded transitive links')
|
|
86
104
|
.argument('<name>', 'Skill frontmatter name')
|
|
87
105
|
.action((name, opts, command) => {
|
|
88
106
|
const globalOpts = command.optsWithGlobals();
|
|
89
|
-
const result = unlinkSkill(name);
|
|
107
|
+
const result = unlinkSkill(name, { recursive: opts.recursive });
|
|
90
108
|
|
|
91
109
|
if (globalOpts.json) {
|
|
92
110
|
output.json(result);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
function getDevSessionPath(repoRoot) {
|
|
5
|
+
return join(repoRoot, '.agentpack', 'dev-session.json');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function readDevSession(repoRoot) {
|
|
9
|
+
const sessionPath = getDevSessionPath(repoRoot);
|
|
10
|
+
if (!existsSync(sessionPath)) return null;
|
|
11
|
+
return JSON.parse(readFileSync(sessionPath, 'utf-8'));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function writeDevSession(repoRoot, session) {
|
|
15
|
+
mkdirSync(join(repoRoot, '.agentpack'), { recursive: true });
|
|
16
|
+
writeFileSync(getDevSessionPath(repoRoot), JSON.stringify(session, null, 2) + '\n');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function removeDevSession(repoRoot) {
|
|
20
|
+
rmSync(getDevSessionPath(repoRoot), { force: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function devSessionExists(repoRoot) {
|
|
24
|
+
return existsSync(getDevSessionPath(repoRoot));
|
|
25
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, rmSync, symlinkSync } from 'node:fs';
|
|
2
|
-
import { dirname, join, relative } from 'node:path';
|
|
2
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
3
3
|
import { writeInstallState } from '../fs/install-state-repository.js';
|
|
4
4
|
|
|
5
5
|
function ensureDir(pathValue) {
|
|
@@ -40,6 +40,23 @@ export function removeSkillLinksByNames(repoRoot, names, normalizeDisplayPath) {
|
|
|
40
40
|
return [...new Set(removed)];
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
export function removeSkillLinksByPaths(repoRoot, paths, normalizeDisplayPath) {
|
|
44
|
+
const removed = [];
|
|
45
|
+
const allowedRoots = [
|
|
46
|
+
resolve(repoRoot, '.claude', 'skills'),
|
|
47
|
+
resolve(repoRoot, '.agents', 'skills'),
|
|
48
|
+
];
|
|
49
|
+
for (const relativePath of paths || []) {
|
|
50
|
+
const pathValue = resolve(repoRoot, relativePath);
|
|
51
|
+
const inAllowedRoot = allowedRoots.some((root) => pathValue === root || pathValue.startsWith(`${root}/`));
|
|
52
|
+
if (!inAllowedRoot) continue;
|
|
53
|
+
if (!existsSync(pathValue)) continue;
|
|
54
|
+
removePathIfExists(pathValue);
|
|
55
|
+
removed.push(normalizeDisplayPath(repoRoot, pathValue));
|
|
56
|
+
}
|
|
57
|
+
return [...new Set(removed)];
|
|
58
|
+
}
|
|
59
|
+
|
|
43
60
|
function ensureSymlink(targetPath, linkPath) {
|
|
44
61
|
removePathIfExists(linkPath);
|
|
45
62
|
mkdirSync(dirname(linkPath), { recursive: true });
|
package/src/lib/skills.js
CHANGED
|
@@ -9,11 +9,13 @@ import {
|
|
|
9
9
|
readNodeStatus,
|
|
10
10
|
} from '../domain/skills/skill-graph.js';
|
|
11
11
|
import { readInstallState } from '../infrastructure/fs/install-state-repository.js';
|
|
12
|
+
import { readDevSession, writeDevSession, removeDevSession } from '../infrastructure/fs/dev-session-repository.js';
|
|
12
13
|
import {
|
|
13
14
|
ensureSkillLink,
|
|
14
15
|
rebuildInstallState,
|
|
15
16
|
removePathIfExists,
|
|
16
17
|
removeSkillLinks,
|
|
18
|
+
removeSkillLinksByPaths,
|
|
17
19
|
removeSkillLinksByNames,
|
|
18
20
|
} from '../infrastructure/runtime/materialize-skills.js';
|
|
19
21
|
import {
|
|
@@ -171,6 +173,100 @@ function readPackageJson(packageDir) {
|
|
|
171
173
|
};
|
|
172
174
|
}
|
|
173
175
|
|
|
176
|
+
function isProcessAlive(pid) {
|
|
177
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
178
|
+
try {
|
|
179
|
+
process.kill(pid, 0);
|
|
180
|
+
return true;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
if (error.code === 'EPERM') return true;
|
|
183
|
+
if (error.code === 'ESRCH') return false;
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function buildDevSessionNextSteps(command) {
|
|
189
|
+
return [{
|
|
190
|
+
action: 'run_command',
|
|
191
|
+
command,
|
|
192
|
+
reason: 'Use the dev session cleanup flow to remove recorded linked skills for this repo',
|
|
193
|
+
}];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function toDevSessionRecord(repoRoot, target, result, existing = null) {
|
|
197
|
+
const now = new Date().toISOString();
|
|
198
|
+
const rootSkill = result.linkedSkills.find((entry) => entry.name === result.name) || result.linkedSkills[0] || null;
|
|
199
|
+
return {
|
|
200
|
+
version: 1,
|
|
201
|
+
session_id: existing?.session_id || `dev-${now.replaceAll(':', '-').replaceAll('.', '-')}`,
|
|
202
|
+
status: 'active',
|
|
203
|
+
pid: process.pid,
|
|
204
|
+
repo_root: repoRoot,
|
|
205
|
+
target,
|
|
206
|
+
root_skill: rootSkill
|
|
207
|
+
? {
|
|
208
|
+
name: rootSkill.name,
|
|
209
|
+
package_name: rootSkill.packageName,
|
|
210
|
+
path: rootSkill.path,
|
|
211
|
+
}
|
|
212
|
+
: null,
|
|
213
|
+
linked_skills: result.linkedSkills.map((entry) => ({
|
|
214
|
+
name: entry.name,
|
|
215
|
+
package_name: entry.packageName,
|
|
216
|
+
path: entry.path,
|
|
217
|
+
})),
|
|
218
|
+
links: result.links,
|
|
219
|
+
started_at: existing?.started_at || now,
|
|
220
|
+
updated_at: now,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function cleanupRecordedDevSession(repoRoot, session, status = 'stale') {
|
|
225
|
+
if (!session) {
|
|
226
|
+
return {
|
|
227
|
+
cleaned: false,
|
|
228
|
+
removed: [],
|
|
229
|
+
session: null,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
writeDevSession(repoRoot, {
|
|
234
|
+
...session,
|
|
235
|
+
status,
|
|
236
|
+
updated_at: new Date().toISOString(),
|
|
237
|
+
});
|
|
238
|
+
const removed = removeSkillLinksByPaths(repoRoot, session.links || [], normalizeDisplayPath);
|
|
239
|
+
removeDevSession(repoRoot);
|
|
240
|
+
return {
|
|
241
|
+
cleaned: removed.length > 0 || Boolean(session),
|
|
242
|
+
removed,
|
|
243
|
+
session,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function reconcileDevSession(repoRoot) {
|
|
248
|
+
const session = readDevSession(repoRoot);
|
|
249
|
+
if (!session) return null;
|
|
250
|
+
|
|
251
|
+
if (session.status === 'active' && isProcessAlive(session.pid)) {
|
|
252
|
+
throw new AgentpackError('A skills dev session is already active in this repo', {
|
|
253
|
+
code: 'skills_dev_session_active',
|
|
254
|
+
exitCode: EXIT_CODES.GENERAL,
|
|
255
|
+
nextSteps: [
|
|
256
|
+
...buildDevSessionNextSteps('agentpack skills dev cleanup'),
|
|
257
|
+
...buildDevSessionNextSteps('agentpack skills dev cleanup --force'),
|
|
258
|
+
],
|
|
259
|
+
details: {
|
|
260
|
+
rootSkill: session.root_skill?.name || null,
|
|
261
|
+
pid: session.pid,
|
|
262
|
+
startedAt: session.started_at || null,
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return cleanupRecordedDevSession(repoRoot, session, 'stale');
|
|
268
|
+
}
|
|
269
|
+
|
|
174
270
|
export function syncSkillDependencies(skillDir) {
|
|
175
271
|
const skillFile = join(skillDir, 'SKILL.md');
|
|
176
272
|
const metadata = parseSkillFrontmatterFile(skillFile);
|
|
@@ -271,12 +367,14 @@ export function startSkillDev(target, {
|
|
|
271
367
|
const outerRepoRoot = findRepoRoot(cwd);
|
|
272
368
|
const { skillDir } = resolveLocalPackagedSkillDir(outerRepoRoot, target);
|
|
273
369
|
const repoRoot = findRepoRoot(skillDir);
|
|
370
|
+
reconcileDevSession(repoRoot);
|
|
274
371
|
let closed = false;
|
|
275
372
|
let timer = null;
|
|
276
373
|
let currentNames = [];
|
|
277
374
|
let watcher = null;
|
|
278
375
|
let workbench = null;
|
|
279
376
|
let initialResult = null;
|
|
377
|
+
let sessionRecord = null;
|
|
280
378
|
|
|
281
379
|
const cleanup = () => {
|
|
282
380
|
if (closed) return { name: currentNames[0] || null, unlinked: false, removed: [] };
|
|
@@ -284,10 +382,20 @@ export function startSkillDev(target, {
|
|
|
284
382
|
clearTimeout(timer);
|
|
285
383
|
if (watcher) watcher.close();
|
|
286
384
|
if (workbench) workbench.close();
|
|
287
|
-
|
|
385
|
+
if (sessionRecord) {
|
|
386
|
+
writeDevSession(repoRoot, {
|
|
387
|
+
...sessionRecord,
|
|
388
|
+
status: 'cleaning',
|
|
389
|
+
updated_at: new Date().toISOString(),
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
const removed = sessionRecord
|
|
393
|
+
? removeSkillLinksByPaths(repoRoot, sessionRecord.links || [], normalizeDisplayPath)
|
|
394
|
+
: removeSkillLinksByNames(repoRoot, currentNames, normalizeDisplayPath);
|
|
395
|
+
removeDevSession(repoRoot);
|
|
288
396
|
detachProcessCleanup();
|
|
289
397
|
return {
|
|
290
|
-
name: currentNames[0] || null,
|
|
398
|
+
name: sessionRecord?.root_skill?.name || currentNames[0] || null,
|
|
291
399
|
unlinked: removed.length > 0,
|
|
292
400
|
removed,
|
|
293
401
|
};
|
|
@@ -295,9 +403,14 @@ export function startSkillDev(target, {
|
|
|
295
403
|
|
|
296
404
|
const processCleanupHandlers = new Map();
|
|
297
405
|
const attachProcessCleanup = () => {
|
|
298
|
-
|
|
406
|
+
const exitHandler = () => cleanup();
|
|
407
|
+
processCleanupHandlers.set('exit', exitHandler);
|
|
408
|
+
process.once('exit', exitHandler);
|
|
409
|
+
|
|
410
|
+
for (const eventName of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
|
299
411
|
const handler = () => {
|
|
300
412
|
cleanup();
|
|
413
|
+
process.exit(0);
|
|
301
414
|
};
|
|
302
415
|
processCleanupHandlers.set(eventName, handler);
|
|
303
416
|
process.once(eventName, handler);
|
|
@@ -333,6 +446,8 @@ export function startSkillDev(target, {
|
|
|
333
446
|
removeSkillLinksByNames(repoRoot, staleNames, normalizeDisplayPath);
|
|
334
447
|
}
|
|
335
448
|
currentNames = nextNames;
|
|
449
|
+
sessionRecord = toDevSessionRecord(repoRoot, target, result, sessionRecord);
|
|
450
|
+
writeDevSession(repoRoot, sessionRecord);
|
|
336
451
|
return result;
|
|
337
452
|
};
|
|
338
453
|
|
|
@@ -390,8 +505,37 @@ export function startSkillDev(target, {
|
|
|
390
505
|
};
|
|
391
506
|
}
|
|
392
507
|
|
|
393
|
-
export function unlinkSkill(name, { cwd = process.cwd() } = {}) {
|
|
508
|
+
export function unlinkSkill(name, { cwd = process.cwd(), recursive = false } = {}) {
|
|
394
509
|
const repoRoot = findRepoRoot(cwd);
|
|
510
|
+
const session = readDevSession(repoRoot);
|
|
511
|
+
|
|
512
|
+
if (recursive) {
|
|
513
|
+
if (!session || session.root_skill?.name !== name) {
|
|
514
|
+
throw new AgentpackError('Recursive unlink requires the active dev-session root skill', {
|
|
515
|
+
code: 'linked_skill_recursive_unlink_requires_root',
|
|
516
|
+
exitCode: EXIT_CODES.GENERAL,
|
|
517
|
+
nextSteps: session?.root_skill?.name
|
|
518
|
+
? [{
|
|
519
|
+
action: 'run_command',
|
|
520
|
+
command: `agentpack skills unlink ${session.root_skill.name} --recursive`,
|
|
521
|
+
reason: 'Recursive unlink in v1 only works for the recorded dev-session root skill',
|
|
522
|
+
}]
|
|
523
|
+
: buildDevSessionNextSteps('agentpack skills dev cleanup --force'),
|
|
524
|
+
details: {
|
|
525
|
+
rootSkill: session?.root_skill?.name || null,
|
|
526
|
+
},
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
const removed = removeSkillLinksByPaths(repoRoot, session.links || [], normalizeDisplayPath);
|
|
531
|
+
removeDevSession(repoRoot);
|
|
532
|
+
return {
|
|
533
|
+
name,
|
|
534
|
+
unlinked: removed.length > 0,
|
|
535
|
+
removed,
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
395
539
|
const existing = [
|
|
396
540
|
join(repoRoot, '.claude', 'skills', name),
|
|
397
541
|
join(repoRoot, '.agents', 'skills', name),
|
|
@@ -413,6 +557,43 @@ export function unlinkSkill(name, { cwd = process.cwd() } = {}) {
|
|
|
413
557
|
};
|
|
414
558
|
}
|
|
415
559
|
|
|
560
|
+
export function cleanupSkillDevSession({ cwd = process.cwd(), force = false } = {}) {
|
|
561
|
+
const repoRoot = findRepoRoot(cwd);
|
|
562
|
+
const session = readDevSession(repoRoot);
|
|
563
|
+
if (!session) {
|
|
564
|
+
return {
|
|
565
|
+
cleaned: false,
|
|
566
|
+
active: false,
|
|
567
|
+
removed: [],
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (!force && session.status === 'active' && isProcessAlive(session.pid)) {
|
|
572
|
+
throw new AgentpackError('A skills dev session is still active in this repo', {
|
|
573
|
+
code: 'skills_dev_session_active',
|
|
574
|
+
exitCode: EXIT_CODES.GENERAL,
|
|
575
|
+
nextSteps: [
|
|
576
|
+
...buildDevSessionNextSteps('agentpack skills dev cleanup'),
|
|
577
|
+
...buildDevSessionNextSteps('agentpack skills dev cleanup --force'),
|
|
578
|
+
],
|
|
579
|
+
details: {
|
|
580
|
+
rootSkill: session.root_skill?.name || null,
|
|
581
|
+
pid: session.pid,
|
|
582
|
+
startedAt: session.started_at || null,
|
|
583
|
+
},
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
const result = cleanupRecordedDevSession(repoRoot, session, 'stale');
|
|
588
|
+
return {
|
|
589
|
+
cleaned: true,
|
|
590
|
+
active: false,
|
|
591
|
+
forced: force,
|
|
592
|
+
name: session.root_skill?.name || null,
|
|
593
|
+
removed: result.removed,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
|
|
416
597
|
function buildValidateNextSteps(packageMetadata, valid) {
|
|
417
598
|
if (!valid || !packageMetadata.packageName) return [];
|
|
418
599
|
|