universal-memory 0.2.1__tar.gz → 0.3.0__tar.gz
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.
- {universal_memory-0.2.1 → universal_memory-0.3.0}/PKG-INFO +42 -10
- {universal_memory-0.2.1 → universal_memory-0.3.0}/README.md +41 -9
- {universal_memory-0.2.1 → universal_memory-0.3.0}/pyproject.toml +1 -1
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/__init__.py +1 -1
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/onboarding/setup_project.py +60 -9
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/__init__.py +64 -0
- universal_memory-0.3.0/src/universal_memory/application/skills/adopt_skill.py +215 -0
- universal_memory-0.3.0/src/universal_memory/application/skills/cleanup_skill.py +208 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/create_skill.py +46 -16
- universal_memory-0.3.0/src/universal_memory/application/skills/draft_skill.py +401 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/import_skill.py +15 -2
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/list_skills.py +95 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/native_skill_sync.py +85 -0
- universal_memory-0.3.0/src/universal_memory/application/skills/rename_skill.py +118 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/sync_skills.py +18 -2
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/update_skill.py +243 -1
- universal_memory-0.3.0/src/universal_memory/application/skills/validate_skill.py +315 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/bootstrap/cli.py +61 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/bootstrap/mcp.py +56 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/agent_skill.py +10 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/agent_skill_repository.py +27 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/security/local_audit_log_repository.py +13 -5
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/storage/local_agent_skill_repository.py +39 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/interfaces/cli/init_command.py +934 -7
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/interfaces/mcp/server.py +265 -2
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/__main__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/diagnostics/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/diagnostics/doctor_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/host/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/host/drift_detector.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/host/setup_host_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/host/sync_instructions_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/memory/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/memory/assemble_context_summary_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/memory/context_hygiene_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/memory/get_memory_status_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/memory/list_facts_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/memory/purge_fact_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/memory/remember_fact_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/memory/search_facts_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/onboarding/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/security/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/security/list_audit_log_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/security/list_snapshots_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/security/rollback_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/security/safe_write_use_case.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/generate_skill.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/promote_skill.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/propose_skill.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/recommend_skills.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/skills/track_latent_skill.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/update/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/application/update/update_use_cases.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/bootstrap/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/audit_event.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/base.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/context_summary.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/fact.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/host.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/instruction_target.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/latent_skill.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/rule.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/runtime.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/safe_write_result.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/entities/snapshot.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/exceptions.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/audit_log_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/config_validation_port.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/context_summary_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/fact_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/latent_skill_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/project_layout_port.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/rule_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/secret_scanner_port.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/ports/snapshot_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/domain/project_layout.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/config/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/config/adapters.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/config/project_layout.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/config/toml_loader.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/security/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/security/entropy_secret_scanner.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/security/local_snapshot_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/storage/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/storage/local_context_summary_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/storage/local_fact_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/storage/local_latent_skill_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/infrastructure/storage/local_rule_repository.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/interfaces/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/interfaces/cli/__init__.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/interfaces/cli/message_catalog.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/interfaces/errors.py +0 -0
- {universal_memory-0.2.1 → universal_memory-0.3.0}/src/universal_memory/interfaces/mcp/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: universal-memory
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Vendor-agnostic cognitive persistence layer for AI agents.
|
|
5
5
|
Keywords: agent-memory,ai,ai-agents,agent-skills,claude-code,codex,context-engineering,developer-tools,llm,mcp,memory
|
|
6
6
|
Author: Yan L. Amorelli
|
|
@@ -171,21 +171,37 @@ umem context --scope project
|
|
|
171
171
|
|
|
172
172
|
### 4. Adopt or create an Agent Skill
|
|
173
173
|
|
|
174
|
-
If a skill already exists
|
|
175
|
-
|
|
174
|
+
If a skill already exists, choose the safest adoption path first. Use `adopt` for an
|
|
175
|
+
existing `.umem/skills/<slug>` directory; use `import` for native runtime directories
|
|
176
|
+
such as `.agents/skills/<slug>` and sync it back out to configured runtimes:
|
|
176
177
|
|
|
177
178
|
```bash
|
|
179
|
+
umem skills adopt .umem/skills/review-protocol --scope project
|
|
178
180
|
umem skills import .agents/skills/review-protocol --scope project --sync
|
|
179
181
|
umem skills detail review-protocol
|
|
180
182
|
```
|
|
181
183
|
|
|
182
|
-
If you are starting from scratch,
|
|
184
|
+
If you are starting from scratch, draft and publish it without native side effects:
|
|
183
185
|
|
|
184
186
|
```bash
|
|
185
|
-
umem skills create \
|
|
187
|
+
umem skills draft create \
|
|
186
188
|
--name "Review Protocol" \
|
|
187
189
|
--description "Reusable review workflow" \
|
|
188
190
|
--trigger "when reviewing code"
|
|
191
|
+
umem skills draft validate review-protocol
|
|
192
|
+
umem skills publish review-protocol --format summary
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
For a one-step workflow, create the canonical skill. It is canonical-only by default;
|
|
196
|
+
request sync explicitly when native runtime targets should be written:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
umem skills create \
|
|
200
|
+
--name "Review Protocol" \
|
|
201
|
+
--description "Reusable review workflow" \
|
|
202
|
+
--trigger "when reviewing code" \
|
|
203
|
+
--format summary
|
|
204
|
+
umem skills sync review-protocol --check-gitignore --format summary
|
|
189
205
|
```
|
|
190
206
|
|
|
191
207
|
After editing `.umem/skills/review-protocol/SKILL.md`, refresh one runtime skill with:
|
|
@@ -291,7 +307,7 @@ your shell `PATH`.
|
|
|
291
307
|
|
|
292
308
|
## Managing Agent Skills
|
|
293
309
|
|
|
294
|
-
You can create, import,
|
|
310
|
+
You can draft, create, adopt, import, validate, maintain, and sync specialized behaviors:
|
|
295
311
|
```bash
|
|
296
312
|
# List all active skills
|
|
297
313
|
umem skills list
|
|
@@ -299,14 +315,30 @@ umem skills list
|
|
|
299
315
|
# Inspect one skill
|
|
300
316
|
umem skills detail review-protocol
|
|
301
317
|
|
|
302
|
-
#
|
|
303
|
-
umem skills create --name "Review Protocol" --description "Reusable review workflow"
|
|
318
|
+
# Draft, validate, and publish without native runtime writes
|
|
319
|
+
umem skills draft create --name "Review Protocol" --description "Reusable review workflow"
|
|
320
|
+
umem skills draft validate review-protocol
|
|
321
|
+
umem skills publish review-protocol
|
|
322
|
+
|
|
323
|
+
# Create a new canonical skill and explicitly sync native targets
|
|
324
|
+
umem skills create --name "Review Protocol" --description "Reusable review workflow" --sync
|
|
304
325
|
|
|
305
|
-
# Adopt
|
|
326
|
+
# Adopt existing canonical work
|
|
327
|
+
umem skills adopt .umem/skills/review-protocol --scope project
|
|
328
|
+
|
|
329
|
+
# Import an existing native skill and distribute complete runtime copies
|
|
306
330
|
umem skills import .agents/skills/review-protocol --scope project --sync
|
|
307
331
|
|
|
332
|
+
# Validate and maintain canonical skills
|
|
333
|
+
umem skills validate review-protocol
|
|
334
|
+
umem skills canonical update review-protocol --file .umem/skills/review-protocol/SKILL.md
|
|
335
|
+
umem skills rename review-protocol --slug review-checklist
|
|
336
|
+
umem skills cleanup review-checklist --targets --format summary
|
|
337
|
+
umem skills cleanup review-checklist --targets --apply
|
|
338
|
+
umem skills repair --remove-orphan-targets --format summary
|
|
339
|
+
|
|
308
340
|
# Synchronize one canonical skill into active native runtime folders
|
|
309
|
-
umem skills sync review-protocol
|
|
341
|
+
umem skills sync review-protocol --check-gitignore --format summary
|
|
310
342
|
|
|
311
343
|
# Synchronize all active canonical skills during maintenance
|
|
312
344
|
umem update --skills
|
|
@@ -143,21 +143,37 @@ umem context --scope project
|
|
|
143
143
|
|
|
144
144
|
### 4. Adopt or create an Agent Skill
|
|
145
145
|
|
|
146
|
-
If a skill already exists
|
|
147
|
-
|
|
146
|
+
If a skill already exists, choose the safest adoption path first. Use `adopt` for an
|
|
147
|
+
existing `.umem/skills/<slug>` directory; use `import` for native runtime directories
|
|
148
|
+
such as `.agents/skills/<slug>` and sync it back out to configured runtimes:
|
|
148
149
|
|
|
149
150
|
```bash
|
|
151
|
+
umem skills adopt .umem/skills/review-protocol --scope project
|
|
150
152
|
umem skills import .agents/skills/review-protocol --scope project --sync
|
|
151
153
|
umem skills detail review-protocol
|
|
152
154
|
```
|
|
153
155
|
|
|
154
|
-
If you are starting from scratch,
|
|
156
|
+
If you are starting from scratch, draft and publish it without native side effects:
|
|
155
157
|
|
|
156
158
|
```bash
|
|
157
|
-
umem skills create \
|
|
159
|
+
umem skills draft create \
|
|
158
160
|
--name "Review Protocol" \
|
|
159
161
|
--description "Reusable review workflow" \
|
|
160
162
|
--trigger "when reviewing code"
|
|
163
|
+
umem skills draft validate review-protocol
|
|
164
|
+
umem skills publish review-protocol --format summary
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
For a one-step workflow, create the canonical skill. It is canonical-only by default;
|
|
168
|
+
request sync explicitly when native runtime targets should be written:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
umem skills create \
|
|
172
|
+
--name "Review Protocol" \
|
|
173
|
+
--description "Reusable review workflow" \
|
|
174
|
+
--trigger "when reviewing code" \
|
|
175
|
+
--format summary
|
|
176
|
+
umem skills sync review-protocol --check-gitignore --format summary
|
|
161
177
|
```
|
|
162
178
|
|
|
163
179
|
After editing `.umem/skills/review-protocol/SKILL.md`, refresh one runtime skill with:
|
|
@@ -263,7 +279,7 @@ your shell `PATH`.
|
|
|
263
279
|
|
|
264
280
|
## Managing Agent Skills
|
|
265
281
|
|
|
266
|
-
You can create, import,
|
|
282
|
+
You can draft, create, adopt, import, validate, maintain, and sync specialized behaviors:
|
|
267
283
|
```bash
|
|
268
284
|
# List all active skills
|
|
269
285
|
umem skills list
|
|
@@ -271,14 +287,30 @@ umem skills list
|
|
|
271
287
|
# Inspect one skill
|
|
272
288
|
umem skills detail review-protocol
|
|
273
289
|
|
|
274
|
-
#
|
|
275
|
-
umem skills create --name "Review Protocol" --description "Reusable review workflow"
|
|
290
|
+
# Draft, validate, and publish without native runtime writes
|
|
291
|
+
umem skills draft create --name "Review Protocol" --description "Reusable review workflow"
|
|
292
|
+
umem skills draft validate review-protocol
|
|
293
|
+
umem skills publish review-protocol
|
|
294
|
+
|
|
295
|
+
# Create a new canonical skill and explicitly sync native targets
|
|
296
|
+
umem skills create --name "Review Protocol" --description "Reusable review workflow" --sync
|
|
276
297
|
|
|
277
|
-
# Adopt
|
|
298
|
+
# Adopt existing canonical work
|
|
299
|
+
umem skills adopt .umem/skills/review-protocol --scope project
|
|
300
|
+
|
|
301
|
+
# Import an existing native skill and distribute complete runtime copies
|
|
278
302
|
umem skills import .agents/skills/review-protocol --scope project --sync
|
|
279
303
|
|
|
304
|
+
# Validate and maintain canonical skills
|
|
305
|
+
umem skills validate review-protocol
|
|
306
|
+
umem skills canonical update review-protocol --file .umem/skills/review-protocol/SKILL.md
|
|
307
|
+
umem skills rename review-protocol --slug review-checklist
|
|
308
|
+
umem skills cleanup review-checklist --targets --format summary
|
|
309
|
+
umem skills cleanup review-checklist --targets --apply
|
|
310
|
+
umem skills repair --remove-orphan-targets --format summary
|
|
311
|
+
|
|
280
312
|
# Synchronize one canonical skill into active native runtime folders
|
|
281
|
-
umem skills sync review-protocol
|
|
313
|
+
umem skills sync review-protocol --check-gitignore --format summary
|
|
282
314
|
|
|
283
315
|
# Synchronize all active canonical skills during maintenance
|
|
284
316
|
umem update --skills
|
|
@@ -273,7 +273,9 @@ approval, generation, activation, deactivation, and updates.
|
|
|
273
273
|
## Use Cases
|
|
274
274
|
|
|
275
275
|
- Track a recurring workflow or methodology as a latent skill candidate.
|
|
276
|
+
- Draft a skill when content may need validation before publish.
|
|
276
277
|
- Create a skill directly when the user already knows the desired skill.
|
|
278
|
+
- Adopt existing canonical work in place when it already lives under `.umem/skills/<slug>/`.
|
|
277
279
|
- Import an existing local or native skill directory into the canonical `.umem/skills`
|
|
278
280
|
registry.
|
|
279
281
|
- Sync canonical skills into supported native runtime targets after import or changes.
|
|
@@ -290,8 +292,20 @@ approval, generation, activation, deactivation, and updates.
|
|
|
290
292
|
```bash
|
|
291
293
|
umem skills list --format json
|
|
292
294
|
umem skills detail <skill-id-or-name> --format json
|
|
293
|
-
umem skills create --name "Skill name" --description "What the skill does." --scope project --trigger "when to use it" --format json
|
|
295
|
+
umem skills draft create --name "Skill name" --description "What the skill does." --scope project --trigger "when to use it" --format json
|
|
296
|
+
umem skills draft validate <draft-or-path> --format json
|
|
297
|
+
umem skills publish <draft-or-path> --format summary
|
|
298
|
+
umem skills create --name "Skill name" --description "What the skill does." --scope project --trigger "when to use it" --format summary
|
|
299
|
+
umem skills adopt .umem/skills/<skill-name> --scope project --format summary
|
|
294
300
|
umem skills import .agents/skills/<skill-name> --scope project --sync --format json
|
|
301
|
+
umem skills validate <skill-id-or-name-or-path> --format json
|
|
302
|
+
umem skills canonical update <skill-id-or-name> --file <relative-markdown-path> --format json
|
|
303
|
+
umem skills rename <skill-id-or-name> --slug <new-slug> --format json
|
|
304
|
+
umem skills cleanup <skill-id-or-name> --targets --format summary
|
|
305
|
+
umem skills cleanup <skill-id-or-name> --targets --apply --format summary
|
|
306
|
+
umem skills repair --remove-orphan-targets --format summary
|
|
307
|
+
umem skills repair --remove-orphan-targets --apply --format summary
|
|
308
|
+
umem skills sync <skill-id-or-name> --check-gitignore --format summary
|
|
295
309
|
umem skills import .agents/skills/<skill-name>/SKILL.md --scope project --replace-native --sync --format json
|
|
296
310
|
umem skills sync <skill-id-or-name> --format json
|
|
297
311
|
umem skills track --name "Skill name" --description "What the skill does." --scope project --evidence-summary "Why this pattern recurred." --tag workflow --format json
|
|
@@ -336,13 +350,27 @@ and does not prompt for overwrite. Use explicit `umem skills sync <skill-id-or-n
|
|
|
336
350
|
- `--trigger <text>`: repeatable trigger used in generated skill frontmatter.
|
|
337
351
|
- `--file <relative-markdown-path>`: complete replacement markdown for `SKILL.md`.
|
|
338
352
|
- `--format json`: canonical automation output.
|
|
353
|
+
- `--format summary`: concise human and agent-facing output with status, paths, warnings,
|
|
354
|
+
dry-run/apply status, and next steps.
|
|
355
|
+
- `--check-gitignore`: sync diagnostic that warns when generated native runtime targets
|
|
356
|
+
are tracked by git or not covered by ignore rules. The check runs after target planning/writes
|
|
357
|
+
and is diagnostic only: do not edit `.gitignore` or untrack files from this warning alone.
|
|
358
|
+
In automation, report the warning and let repository policy decide whether ignore rules should change.
|
|
339
359
|
|
|
340
360
|
## MCP Equivalents
|
|
341
361
|
|
|
342
362
|
- `list_skills()`
|
|
343
363
|
- `get_skill_detail(name_or_id="<skill-id-or-name>")`
|
|
344
|
-
- `
|
|
364
|
+
- `create_skill_draft(name="Skill name", description="What the skill does.", scope="project")`
|
|
365
|
+
- `validate_skill(skill_or_path="<skill-id-or-name-or-path>")`
|
|
366
|
+
- `publish_skill(draft_or_path="<draft-or-path>", sync=false)`
|
|
367
|
+
- `create_skill(name="Skill name", description="What the skill does.", scope="project", raw_markdown="<complete SKILL.md content>", sync=false)`
|
|
368
|
+
- `adopt_skill(path=".umem/skills/<skill-name>", scope="project", sync_after_adopt=false)`
|
|
345
369
|
- `import_skill(path=".agents/skills/<skill-name>", scope="project", replace_native=false, sync_after_import=true)`
|
|
370
|
+
- `update_canonical_skill(skill_id_or_name="<skill-id-or-name>", raw_markdown="<complete SKILL.md content>", sync=false)`
|
|
371
|
+
- `rename_skill(skill_id_or_name="<skill-id-or-name>", slug="<new-slug>")`
|
|
372
|
+
- `cleanup_skill(skill_id_or_name="<skill-id-or-name>", targets=true, dry_run=true)`
|
|
373
|
+
- `repair_skills(remove_orphan_targets=true, dry_run=true)`
|
|
346
374
|
- `sync_skills(skill_id_or_name="<skill-id-or-name>", targets=null, drift_decision="keep")`
|
|
347
375
|
- `track_latent_skill(name="Skill name", description="What the skill does.", scope="project", evidence_summary="Why this pattern recurred.", tags=["workflow"])`
|
|
348
376
|
- `recommend_skills(scope="project", min_recurrence=null, dry_run=true)`
|
|
@@ -361,14 +389,25 @@ and does not prompt for overwrite. Use explicit `umem skills sync <skill-id-or-n
|
|
|
361
389
|
- `skills list` returns active, candidate, and disabled skills with relative paths when
|
|
362
390
|
materialized.
|
|
363
391
|
- `skills detail` returns triggers and metadata without loading large references.
|
|
364
|
-
- `skills create` writes
|
|
365
|
-
|
|
392
|
+
- `skills draft create` writes editable draft content only; validate and publish before sync.
|
|
393
|
+
- `skills create` writes a requested canonical skill directly and does not sync native
|
|
394
|
+
targets unless `--sync` is present.
|
|
395
|
+
- `skills publish` converts a draft to canonical and does not sync native targets unless
|
|
396
|
+
`--sync` is present.
|
|
397
|
+
- `skills adopt` registers existing `.umem/skills/<slug>` work in place without creating a suffixed duplicate.
|
|
398
|
+
- Use `skills import`, not `skills adopt`, for existing native runtime directories such
|
|
399
|
+
as `.agents/skills/<slug>` or `.opencode/skills/<slug>`.
|
|
400
|
+
- `skills validate`, `skills canonical update`, `skills rename`, `skills cleanup`, and
|
|
401
|
+
`skills repair` are the supported maintenance path for canonical skills.
|
|
366
402
|
- `skills import` is the normal path for an existing `.agents/skills/...`, `.opencode/skills/...`,
|
|
367
403
|
or other local Agent Skills directory. It registers a canonical UMEM skill and copies
|
|
368
404
|
the source directory into `.umem/skills/<slug>/`.
|
|
369
405
|
- `skills sync` materializes canonical skills into configured native runtime targets;
|
|
370
406
|
importing a skill does not necessarily make it available to every runtime until sync
|
|
371
407
|
runs.
|
|
408
|
+
- `skills sync --check-gitignore --format summary` is the preferred interactive safety
|
|
409
|
+
check when a user wants actionable warnings about tracked or unignored runtime targets.
|
|
410
|
+
It warns after sync planning/writes and never edits `.gitignore` or untracks files.
|
|
372
411
|
- `skills sync` can create or update runtime directories such as `.opencode/skills/...`,
|
|
373
412
|
`.agents/skills/...`, or `.antigravity/...` depending on configured runtimes. Treat these
|
|
374
413
|
as intentional worktree changes and review whether repository ignore rules should include
|
|
@@ -386,10 +425,13 @@ and does not prompt for overwrite. Use explicit `umem skills sync <skill-id-or-n
|
|
|
386
425
|
- `skills generate` creates canonical files under `.umem/skills/` for project skills.
|
|
387
426
|
- `skills deactivate` preserves files and changes status to disabled.
|
|
388
427
|
- `skills activate` requires a readable, valid `SKILL.md`.
|
|
389
|
-
- `skills update`, `activate`, and `deactivate`
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
428
|
+
- `skills update`, `activate`, and `deactivate` operate on latent/generated skill IDs.
|
|
429
|
+
For canonical Agent Skills, use `skills canonical update`, `skills rename`, `skills cleanup`,
|
|
430
|
+
`skills repair`, and `skills sync`.
|
|
431
|
+
- `skills cleanup` previews cleanup for one canonical skill by default; add `--apply`
|
|
432
|
+
only after reviewing removable and blocked paths.
|
|
433
|
+
- `skills repair` previews project-wide orphan target cleanup by default; add
|
|
434
|
+
`--remove-orphan-targets --apply` only after reviewing the summary.
|
|
393
435
|
- `host sync --apply` should be non-interactive in agent automation: use
|
|
394
436
|
`umem host sync --apply --yes --format json`.
|
|
395
437
|
|
|
@@ -618,6 +660,15 @@ CLI commands with `--format json` and MCP tools should return equivalent payload
|
|
|
618
660
|
| Host sync | `umem host sync --apply --yes --format json` | `sync_instructions(apply=true)` |
|
|
619
661
|
| Skills list | `umem skills list --format json` | `list_skills()` |
|
|
620
662
|
| Skill detail | `umem skills detail <skill-id-or-name> --format json` | `get_skill_detail(name_or_id="<skill-id-or-name>")` |
|
|
663
|
+
| Skill draft create | `umem skills draft create ... --format json` | `create_skill_draft(...)` |
|
|
664
|
+
| Skill validate | `umem skills validate <skill-or-path> --format json` | `validate_skill(skill_or_path="<skill-or-path>")` |
|
|
665
|
+
| Skill publish | `umem skills publish <draft-or-path> --format json` | `publish_skill(draft_or_path="<draft-or-path>")` |
|
|
666
|
+
| Skill create | `umem skills create ... --format json` | `create_skill(...)` |
|
|
667
|
+
| Skill adopt | `umem skills adopt <path> --format json` | `adopt_skill(path="<path>")` |
|
|
668
|
+
| Skill canonical update | `umem skills canonical update <skill> --file <path> --format json` | `update_canonical_skill(...)` |
|
|
669
|
+
| Skill rename | `umem skills rename <skill> --slug <slug> --format json` | `rename_skill(...)` |
|
|
670
|
+
| Skill cleanup | `umem skills cleanup <skill> --targets --format json` | `cleanup_skill(...)` |
|
|
671
|
+
| Skill repair | `umem skills repair --remove-orphan-targets --format json` | `repair_skills(...)` |
|
|
621
672
|
| Track skill | `umem skills track ... --format json` | `track_latent_skill(...)` |
|
|
622
673
|
| Recommend skills | `umem skills recommend --scope project --format json` | `recommend_skills(scope="project", dry_run=true)` |
|
|
623
674
|
| Propose skill | `umem skills propose <latent-skill-id> --decision yes --format json` | `propose_skill(latent_skill_id="<latent-skill-id>", decision="yes")` |
|
|
@@ -625,7 +676,7 @@ CLI commands with `--format json` and MCP tools should return equivalent payload
|
|
|
625
676
|
| Generate skill | `umem skills generate <latent-skill-id> --yes --format json` | `generate_skill(latent_skill_id="<latent-skill-id>")` |
|
|
626
677
|
| Activate skill | `umem skills activate <latent-skill-id> --format json` | `activate_skill(latent_skill_id="<latent-skill-id>")` |
|
|
627
678
|
| Deactivate skill | `umem skills deactivate <latent-skill-id> --format json` | `deactivate_skill(latent_skill_id="<latent-skill-id>")` |
|
|
628
|
-
| Update skill | `umem skills update <latent-skill-id> ... --format json` | `update_skill(...)` |
|
|
679
|
+
| Update latent/generated skill | `umem skills update <latent-skill-id> ... --format json` | `update_skill(...)` |
|
|
629
680
|
|
|
630
681
|
## Error Mapping
|
|
631
682
|
|
|
@@ -1,8 +1,30 @@
|
|
|
1
|
+
from universal_memory.application.skills.adopt_skill import (
|
|
2
|
+
AdoptSkillCommand,
|
|
3
|
+
AdoptSkillResult,
|
|
4
|
+
AdoptSkillUseCase,
|
|
5
|
+
)
|
|
6
|
+
from universal_memory.application.skills.cleanup_skill import (
|
|
7
|
+
CleanupPlan,
|
|
8
|
+
CleanupSkillCommand,
|
|
9
|
+
CleanupSkillResult,
|
|
10
|
+
CleanupSkillUseCase,
|
|
11
|
+
RepairSkillsCommand,
|
|
12
|
+
RepairSkillsResult,
|
|
13
|
+
RepairSkillsUseCase,
|
|
14
|
+
)
|
|
1
15
|
from universal_memory.application.skills.create_skill import (
|
|
2
16
|
CreateSkillCommand,
|
|
3
17
|
CreateSkillResult,
|
|
4
18
|
CreateSkillUseCase,
|
|
5
19
|
)
|
|
20
|
+
from universal_memory.application.skills.draft_skill import (
|
|
21
|
+
CreateSkillDraftCommand,
|
|
22
|
+
CreateSkillDraftUseCase,
|
|
23
|
+
DraftSkillResult,
|
|
24
|
+
PublishSkillCommand,
|
|
25
|
+
PublishSkillResult,
|
|
26
|
+
PublishSkillUseCase,
|
|
27
|
+
)
|
|
6
28
|
from universal_memory.application.skills.generate_skill import (
|
|
7
29
|
GenerateSkillCommand,
|
|
8
30
|
GenerateSkillResult,
|
|
@@ -39,6 +61,11 @@ from universal_memory.application.skills.recommend_skills import (
|
|
|
39
61
|
RecommendSkillsUseCase,
|
|
40
62
|
SkillRecommendationItem,
|
|
41
63
|
)
|
|
64
|
+
from universal_memory.application.skills.rename_skill import (
|
|
65
|
+
RenameSkillCommand,
|
|
66
|
+
RenameSkillResult,
|
|
67
|
+
RenameSkillUseCase,
|
|
68
|
+
)
|
|
42
69
|
from universal_memory.application.skills.sync_skills import (
|
|
43
70
|
SyncSkillResult,
|
|
44
71
|
SyncSkillsCommand,
|
|
@@ -57,21 +84,41 @@ from universal_memory.application.skills.update_skill import (
|
|
|
57
84
|
DeactivateSkillCommand,
|
|
58
85
|
DeactivateSkillResult,
|
|
59
86
|
DeactivateSkillUseCase,
|
|
87
|
+
UpdateCanonicalSkillCommand,
|
|
88
|
+
UpdateCanonicalSkillResult,
|
|
89
|
+
UpdateCanonicalSkillUseCase,
|
|
60
90
|
UpdateSkillCommand,
|
|
61
91
|
UpdateSkillResult,
|
|
62
92
|
UpdateSkillUseCase,
|
|
63
93
|
)
|
|
94
|
+
from universal_memory.application.skills.validate_skill import (
|
|
95
|
+
SkillValidationCheck,
|
|
96
|
+
SkillValidationReport,
|
|
97
|
+
ValidateSkillCommand,
|
|
98
|
+
ValidateSkillResult,
|
|
99
|
+
ValidateSkillUseCase,
|
|
100
|
+
)
|
|
64
101
|
|
|
65
102
|
__all__ = [
|
|
66
103
|
"ActivateSkillCommand",
|
|
67
104
|
"ActivateSkillResult",
|
|
68
105
|
"ActivateSkillUseCase",
|
|
106
|
+
"AdoptSkillCommand",
|
|
107
|
+
"AdoptSkillResult",
|
|
108
|
+
"AdoptSkillUseCase",
|
|
109
|
+
"CleanupPlan",
|
|
110
|
+
"CleanupSkillCommand",
|
|
111
|
+
"CleanupSkillResult",
|
|
112
|
+
"CleanupSkillUseCase",
|
|
69
113
|
"CreateSkillCommand",
|
|
114
|
+
"CreateSkillDraftCommand",
|
|
115
|
+
"CreateSkillDraftUseCase",
|
|
70
116
|
"CreateSkillResult",
|
|
71
117
|
"CreateSkillUseCase",
|
|
72
118
|
"DeactivateSkillCommand",
|
|
73
119
|
"DeactivateSkillResult",
|
|
74
120
|
"DeactivateSkillUseCase",
|
|
121
|
+
"DraftSkillResult",
|
|
75
122
|
"GenerateSkillCommand",
|
|
76
123
|
"GenerateSkillResult",
|
|
77
124
|
"GenerateSkillUseCase",
|
|
@@ -91,11 +138,22 @@ __all__ = [
|
|
|
91
138
|
"ProposeSkillDecision",
|
|
92
139
|
"ProposeSkillResult",
|
|
93
140
|
"ProposeSkillUseCase",
|
|
141
|
+
"PublishSkillCommand",
|
|
142
|
+
"PublishSkillResult",
|
|
143
|
+
"PublishSkillUseCase",
|
|
94
144
|
"RecommendSkillsCommand",
|
|
95
145
|
"RecommendSkillsResult",
|
|
96
146
|
"RecommendSkillsUseCase",
|
|
147
|
+
"RenameSkillCommand",
|
|
148
|
+
"RenameSkillResult",
|
|
149
|
+
"RenameSkillUseCase",
|
|
150
|
+
"RepairSkillsCommand",
|
|
151
|
+
"RepairSkillsResult",
|
|
152
|
+
"RepairSkillsUseCase",
|
|
97
153
|
"SkillListItem",
|
|
98
154
|
"SkillRecommendationItem",
|
|
155
|
+
"SkillValidationCheck",
|
|
156
|
+
"SkillValidationReport",
|
|
99
157
|
"SyncSkillResult",
|
|
100
158
|
"SyncSkillsCommand",
|
|
101
159
|
"SyncSkillsResult",
|
|
@@ -103,7 +161,13 @@ __all__ = [
|
|
|
103
161
|
"TrackLatentSkillCommand",
|
|
104
162
|
"TrackLatentSkillResult",
|
|
105
163
|
"TrackLatentSkillUseCase",
|
|
164
|
+
"UpdateCanonicalSkillCommand",
|
|
165
|
+
"UpdateCanonicalSkillResult",
|
|
166
|
+
"UpdateCanonicalSkillUseCase",
|
|
106
167
|
"UpdateSkillCommand",
|
|
107
168
|
"UpdateSkillResult",
|
|
108
169
|
"UpdateSkillUseCase",
|
|
170
|
+
"ValidateSkillCommand",
|
|
171
|
+
"ValidateSkillResult",
|
|
172
|
+
"ValidateSkillUseCase",
|
|
109
173
|
]
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from datetime import UTC, datetime
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
from uuid import uuid4
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
10
|
+
|
|
11
|
+
from universal_memory.application.security import SafeWriteUseCase
|
|
12
|
+
from universal_memory.application.skills.create_skill import _hash_text
|
|
13
|
+
from universal_memory.application.skills.import_skill import ImportSkillCommand, ImportSkillUseCase
|
|
14
|
+
from universal_memory.application.skills.update_skill import _parse_skill_markdown, _slug
|
|
15
|
+
from universal_memory.application.skills.validate_skill import (
|
|
16
|
+
assert_validation_passes,
|
|
17
|
+
validate_skill_tree,
|
|
18
|
+
validate_slug,
|
|
19
|
+
)
|
|
20
|
+
from universal_memory.domain import ValidationFailedError
|
|
21
|
+
from universal_memory.domain.entities import (
|
|
22
|
+
AgentSkill,
|
|
23
|
+
AgentSkillStatus,
|
|
24
|
+
LatentSkillScope,
|
|
25
|
+
RuntimeRegistry,
|
|
26
|
+
)
|
|
27
|
+
from universal_memory.domain.ports import AgentSkillRepository
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True, slots=True)
|
|
31
|
+
class AdoptSkillCommand:
|
|
32
|
+
path: str | Path
|
|
33
|
+
scope: LatentSkillScope
|
|
34
|
+
origin: str
|
|
35
|
+
slug: str | None = None
|
|
36
|
+
replace_native: bool = False
|
|
37
|
+
sync_after_adopt: bool = False
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(frozen=True, slots=True)
|
|
41
|
+
class AdoptSkillResult:
|
|
42
|
+
agent_skill: AgentSkill
|
|
43
|
+
slug: str
|
|
44
|
+
skill_dir: str
|
|
45
|
+
skill_file: str
|
|
46
|
+
adopted_source: str
|
|
47
|
+
affected_paths: list[str]
|
|
48
|
+
audit_reference: str
|
|
49
|
+
snapshot_reference: str
|
|
50
|
+
native_installations: list[dict[str, Any]] = field(default_factory=list)
|
|
51
|
+
warnings: list[str] = field(default_factory=list)
|
|
52
|
+
|
|
53
|
+
def to_payload(self) -> dict[str, Any]:
|
|
54
|
+
return {
|
|
55
|
+
"skill_id": self.agent_skill.id,
|
|
56
|
+
"name": self.agent_skill.name,
|
|
57
|
+
"slug": self.slug,
|
|
58
|
+
"skill_dir": self.skill_dir,
|
|
59
|
+
"skill_file": self.skill_file,
|
|
60
|
+
"adopted_source": self.adopted_source,
|
|
61
|
+
"affected_paths": self.affected_paths,
|
|
62
|
+
"audit_reference": self.audit_reference,
|
|
63
|
+
"snapshot_reference": self.snapshot_reference,
|
|
64
|
+
"native_installations": self.native_installations,
|
|
65
|
+
"warnings": self.warnings,
|
|
66
|
+
"canonical_skill": {
|
|
67
|
+
"id": self.agent_skill.id,
|
|
68
|
+
"name": self.agent_skill.name,
|
|
69
|
+
"description": self.agent_skill.description,
|
|
70
|
+
"scope": self.agent_skill.scope.value,
|
|
71
|
+
"status": self.agent_skill.status.value,
|
|
72
|
+
"canonical_path": self.agent_skill.canonical_path,
|
|
73
|
+
"origin": self.agent_skill.origin,
|
|
74
|
+
"content_hash": self.agent_skill.content_hash,
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class _AdoptSkillSchema(BaseModel):
|
|
80
|
+
model_config = ConfigDict(extra="forbid", from_attributes=True)
|
|
81
|
+
|
|
82
|
+
path: str | Path
|
|
83
|
+
scope: LatentSkillScope
|
|
84
|
+
origin: str = Field(min_length=1)
|
|
85
|
+
slug: str | None = None
|
|
86
|
+
replace_native: bool = False
|
|
87
|
+
sync_after_adopt: bool = False
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class AdoptSkillUseCase:
|
|
91
|
+
def __init__(
|
|
92
|
+
self,
|
|
93
|
+
*,
|
|
94
|
+
project_root: Path,
|
|
95
|
+
repository: AgentSkillRepository,
|
|
96
|
+
safe_write_use_case: SafeWriteUseCase,
|
|
97
|
+
global_safe_write_use_case: SafeWriteUseCase | None = None,
|
|
98
|
+
runtime_registry: RuntimeRegistry | None = None,
|
|
99
|
+
) -> None:
|
|
100
|
+
self.project_root = project_root.resolve()
|
|
101
|
+
self.repository = repository
|
|
102
|
+
self.safe_write_use_case = safe_write_use_case
|
|
103
|
+
self.global_safe_write_use_case = global_safe_write_use_case or safe_write_use_case
|
|
104
|
+
self.import_use_case = ImportSkillUseCase(
|
|
105
|
+
project_root=project_root,
|
|
106
|
+
repository=repository,
|
|
107
|
+
safe_write_use_case=safe_write_use_case,
|
|
108
|
+
global_safe_write_use_case=global_safe_write_use_case,
|
|
109
|
+
runtime_registry=runtime_registry,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def execute(self, command: AdoptSkillCommand) -> AdoptSkillResult:
|
|
113
|
+
validated = _AdoptSkillSchema.model_validate(command)
|
|
114
|
+
source_dir = _source_dir(self.project_root, Path(validated.path))
|
|
115
|
+
skill_file = source_dir / "SKILL.md"
|
|
116
|
+
markdown = skill_file.read_text(encoding="utf-8")
|
|
117
|
+
parsed = _parse_skill_markdown(markdown)
|
|
118
|
+
slug = validate_slug(validated.slug.strip() if validated.slug else _slug(parsed.name))
|
|
119
|
+
canonical_dir = _skill_dir_for(validated.scope, slug)
|
|
120
|
+
canonical_file = f"{canonical_dir}/SKILL.md"
|
|
121
|
+
report = validate_skill_tree(skill_file, project_root=self.project_root, subject=slug)
|
|
122
|
+
assert_validation_passes(report)
|
|
123
|
+
for existing in self.repository.list(scope=validated.scope):
|
|
124
|
+
if existing.slug == slug:
|
|
125
|
+
raise ValidationFailedError(f"Skill slug already exists: {slug}")
|
|
126
|
+
|
|
127
|
+
if _is_canonical_source(self.project_root, source_dir, canonical_dir):
|
|
128
|
+
now = datetime.now(UTC)
|
|
129
|
+
skill = AgentSkill(
|
|
130
|
+
id=str(uuid4()),
|
|
131
|
+
created_at=now,
|
|
132
|
+
updated_at=now,
|
|
133
|
+
name=parsed.name,
|
|
134
|
+
slug=slug,
|
|
135
|
+
description=parsed.description,
|
|
136
|
+
scope=validated.scope,
|
|
137
|
+
status=AgentSkillStatus.active,
|
|
138
|
+
canonical_path=canonical_file,
|
|
139
|
+
origin=validated.origin,
|
|
140
|
+
audit_reference="",
|
|
141
|
+
content_hash=_hash_text(markdown),
|
|
142
|
+
metadata={
|
|
143
|
+
"triggers": parsed.triggers,
|
|
144
|
+
"creation_flow": "adopt",
|
|
145
|
+
"adopt_source": _relative_display(self.project_root, source_dir),
|
|
146
|
+
"validation": report.to_payload(),
|
|
147
|
+
},
|
|
148
|
+
)
|
|
149
|
+
registry_write = self.repository.write(skill, origin=validated.origin)
|
|
150
|
+
return AdoptSkillResult(
|
|
151
|
+
agent_skill=skill,
|
|
152
|
+
slug=slug,
|
|
153
|
+
skill_dir=canonical_dir,
|
|
154
|
+
skill_file=canonical_file,
|
|
155
|
+
adopted_source=_relative_display(self.project_root, source_dir),
|
|
156
|
+
affected_paths=[canonical_file],
|
|
157
|
+
audit_reference=registry_write.audit_reference
|
|
158
|
+
if registry_write is not None
|
|
159
|
+
else "",
|
|
160
|
+
snapshot_reference=registry_write.snapshot_reference
|
|
161
|
+
if registry_write is not None
|
|
162
|
+
else "",
|
|
163
|
+
warnings=report.warnings,
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
imported = self.import_use_case.execute(
|
|
167
|
+
ImportSkillCommand(
|
|
168
|
+
path=source_dir,
|
|
169
|
+
scope=validated.scope,
|
|
170
|
+
origin=validated.origin,
|
|
171
|
+
replace_native=validated.replace_native,
|
|
172
|
+
sync_after_import=validated.sync_after_adopt,
|
|
173
|
+
slug=slug,
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
skill = imported.agent_skill.model_copy(
|
|
177
|
+
update={"metadata": {**imported.agent_skill.metadata, "creation_flow": "adopt"}}
|
|
178
|
+
)
|
|
179
|
+
self.repository.replace(skill, origin=validated.origin)
|
|
180
|
+
return AdoptSkillResult(
|
|
181
|
+
agent_skill=skill,
|
|
182
|
+
slug=imported.slug,
|
|
183
|
+
skill_dir=imported.skill_dir,
|
|
184
|
+
skill_file=imported.skill_file,
|
|
185
|
+
adopted_source=_relative_display(self.project_root, source_dir),
|
|
186
|
+
affected_paths=imported.affected_paths,
|
|
187
|
+
audit_reference=imported.audit_reference,
|
|
188
|
+
snapshot_reference=imported.snapshot_reference,
|
|
189
|
+
native_installations=imported.native_installations,
|
|
190
|
+
warnings=[*report.warnings, *imported.warnings],
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def _source_dir(project_root: Path, path: Path) -> Path:
|
|
195
|
+
source = path if path.is_absolute() else project_root / path
|
|
196
|
+
if source.is_file():
|
|
197
|
+
source = source.parent
|
|
198
|
+
if not (source / "SKILL.md").is_file():
|
|
199
|
+
raise ValidationFailedError("Adopt path must be a skill directory or SKILL.md file.")
|
|
200
|
+
return source.resolve()
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def _is_canonical_source(project_root: Path, source_dir: Path, canonical_dir: str) -> bool:
|
|
204
|
+
return source_dir == (project_root / canonical_dir).resolve()
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _skill_dir_for(scope: LatentSkillScope, slug: str) -> str:
|
|
208
|
+
return f"skills/{slug}" if scope == LatentSkillScope.global_ else f".umem/skills/{slug}"
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _relative_display(project_root: Path, path: Path) -> str:
|
|
212
|
+
try:
|
|
213
|
+
return path.resolve().relative_to(project_root.resolve()).as_posix()
|
|
214
|
+
except ValueError:
|
|
215
|
+
return path.as_posix()
|