@looplia/looplia-cli 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +33216 -0
- package/package.json +55 -0
- package/plugins/looplia-core/.claude-plugin/plugin.json +10 -0
- package/plugins/looplia-core/commands/build-workflow.md +92 -0
- package/plugins/looplia-core/commands/build.md +71 -0
- package/plugins/looplia-core/commands/list-workflows.md +55 -0
- package/plugins/looplia-core/commands/run.md +50 -0
- package/plugins/looplia-core/hooks/hooks.json +27 -0
- package/plugins/looplia-core/scripts/hooks/compact-inject-state.sh +36 -0
- package/plugins/looplia-core/scripts/hooks/post-write-validate.sh +81 -0
- package/plugins/looplia-core/scripts/hooks/stop-guard.sh +56 -0
- package/plugins/looplia-core/skills/plugin-registry-scanner/SKILL.md +108 -0
- package/plugins/looplia-core/skills/plugin-registry-scanner/scripts/scan-plugins.ts +221 -0
- package/plugins/looplia-core/skills/plugin-registry-scanner/test/scan-plugins.test.ts +256 -0
- package/plugins/looplia-core/skills/search/SKILL.md +174 -0
- package/plugins/looplia-core/skills/skill-capability-matcher/SKILL.md +378 -0
- package/plugins/looplia-core/skills/workflow-executor/SKILL.md +469 -0
- package/plugins/looplia-core/skills/workflow-executor-inline/SKILL.md +217 -0
- package/plugins/looplia-core/skills/workflow-schema-composer/SCHEMA.md +214 -0
- package/plugins/looplia-core/skills/workflow-schema-composer/SKILL.md +373 -0
- package/plugins/looplia-core/skills/workflow-schema-composer/templates/workflow.md.template +44 -0
- package/plugins/looplia-core/skills/workflow-validator/SKILL.md +171 -0
- package/plugins/looplia-core/skills/workflow-validator/scripts/validate.ts +244 -0
- package/plugins/looplia-writer/.claude-plugin/plugin.json +10 -0
- package/plugins/looplia-writer/README.md +107 -0
- package/plugins/looplia-writer/skills/content-documenter/SKILL.md +189 -0
- package/plugins/looplia-writer/skills/id-generator/SKILL.md +120 -0
- package/plugins/looplia-writer/skills/idea-synthesis/SKILL.md +162 -0
- package/plugins/looplia-writer/skills/media-reviewer/SKILL.md +105 -0
- package/plugins/looplia-writer/skills/user-profile-reader/SKILL.md +94 -0
- package/plugins/looplia-writer/skills/writing-enhancer/SKILL.md +34 -0
- package/plugins/looplia-writer/skills/writing-kit-assembler/SKILL.md +206 -0
- package/plugins/looplia-writer/workflows/writing-kit.md +134 -0
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@looplia/looplia-cli",
|
|
3
|
+
"version": "0.6.6",
|
|
4
|
+
"description": "Looplia CLI - AI-powered workflow automation tool",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "Elastic-2.0",
|
|
7
|
+
"author": "Looplia",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/memorysaver/looplia-core"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/memorysaver/looplia-core",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/memorysaver/looplia-core/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"cli",
|
|
18
|
+
"ai",
|
|
19
|
+
"workflow",
|
|
20
|
+
"automation",
|
|
21
|
+
"looplia"
|
|
22
|
+
],
|
|
23
|
+
"bin": {
|
|
24
|
+
"looplia": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"plugins"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsup",
|
|
32
|
+
"dev": "tsup --watch",
|
|
33
|
+
"start": "node dist/index.js",
|
|
34
|
+
"test": "bun run build && bun test",
|
|
35
|
+
"test:watch": "bun test --watch",
|
|
36
|
+
"test:unit": "bun test commands/",
|
|
37
|
+
"test:e2e": "bun run build && bun test e2e/",
|
|
38
|
+
"check-types": "tsc --noEmit",
|
|
39
|
+
"copy-plugins": "rm -rf plugins && cp -r ../../plugins ./plugins",
|
|
40
|
+
"prepublishOnly": "bun run copy-plugins && bun run build"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"ink": "^6.5.1",
|
|
44
|
+
"react": "^19.2.1"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@looplia-core/config": "workspace:*",
|
|
48
|
+
"@looplia-core/core": "workspace:*",
|
|
49
|
+
"@looplia-core/provider": "workspace:*",
|
|
50
|
+
"@types/node": "^22.0.0",
|
|
51
|
+
"@types/react": "^19.2.7",
|
|
52
|
+
"tsup": "^8.5.1",
|
|
53
|
+
"typescript": "^5.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "looplia",
|
|
3
|
+
"description": "Core workflow engine - Execute workflow-as-markdown definitions with validation-driven completion",
|
|
4
|
+
"version": "0.6.5",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Looplia"
|
|
7
|
+
},
|
|
8
|
+
"keywords": ["workflow", "agentic", "automation", "validation"],
|
|
9
|
+
"homepage": "https://github.com/memorysaver/looplia-core"
|
|
10
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scaffold a new workflow definition
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Build Workflow
|
|
6
|
+
|
|
7
|
+
Create a new workflow-as-markdown file with the proper structure.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/build-workflow <name>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Arguments
|
|
16
|
+
|
|
17
|
+
| Argument | Description |
|
|
18
|
+
|----------|-------------|
|
|
19
|
+
| `name` | Name for the new workflow (e.g., "research-kit") |
|
|
20
|
+
|
|
21
|
+
## Example
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
/build-workflow research-kit
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Execution
|
|
28
|
+
|
|
29
|
+
1. **Validate name**
|
|
30
|
+
- Check name is valid (lowercase, hyphens allowed)
|
|
31
|
+
- Check `workflows/{name}.md` doesn't already exist
|
|
32
|
+
|
|
33
|
+
2. **Gather requirements**
|
|
34
|
+
- Ask user about workflow purpose
|
|
35
|
+
- Ask about expected outputs
|
|
36
|
+
- Ask about required agents
|
|
37
|
+
|
|
38
|
+
3. **Generate workflow file**
|
|
39
|
+
- Create `workflows/{name}.md`
|
|
40
|
+
- Include YAML frontmatter with:
|
|
41
|
+
- name, description
|
|
42
|
+
- outputs with artifacts, agents, dependencies
|
|
43
|
+
- validation criteria placeholders
|
|
44
|
+
- Include markdown body with instructions
|
|
45
|
+
|
|
46
|
+
4. **Generate agent stubs** (optional)
|
|
47
|
+
- Create `.claude/agents/{agent-name}.md` for each agent
|
|
48
|
+
- Include skills frontmatter
|
|
49
|
+
- Include task instructions
|
|
50
|
+
|
|
51
|
+
## Template Structure
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
---
|
|
55
|
+
name: {name}
|
|
56
|
+
description: {user-provided description}
|
|
57
|
+
|
|
58
|
+
outputs:
|
|
59
|
+
first-step:
|
|
60
|
+
artifact: step1.json
|
|
61
|
+
agent: step1-agent
|
|
62
|
+
validate:
|
|
63
|
+
required_fields: [field1]
|
|
64
|
+
|
|
65
|
+
final-step:
|
|
66
|
+
artifact: final.json
|
|
67
|
+
agent: final-agent
|
|
68
|
+
requires: [first-step]
|
|
69
|
+
final: true
|
|
70
|
+
validate:
|
|
71
|
+
required_fields: [result]
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
# {Name} Workflow
|
|
75
|
+
|
|
76
|
+
{Custom instructions for this workflow}
|
|
77
|
+
|
|
78
|
+
## Context
|
|
79
|
+
|
|
80
|
+
{What this workflow is for}
|
|
81
|
+
|
|
82
|
+
## Expected Outputs
|
|
83
|
+
|
|
84
|
+
{Description of each output}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Output
|
|
88
|
+
|
|
89
|
+
Report success with:
|
|
90
|
+
- Path to created workflow file
|
|
91
|
+
- Paths to any created agent files
|
|
92
|
+
- Suggested next steps (customize, test with `/run`)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Build a looplia workflow from natural language. Create looplia pipeline, generate workflow automation.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Build Looplia Workflow
|
|
6
|
+
|
|
7
|
+
Create a looplia workflow definition from natural language using the skills-first architecture.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/build [--name <name>] [description]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Arguments
|
|
16
|
+
|
|
17
|
+
| Argument | Description |
|
|
18
|
+
|----------|-------------|
|
|
19
|
+
| `description` | (Optional) Natural language description of what the workflow should do |
|
|
20
|
+
| `--name <name>` | (Optional) Explicit workflow filename. If provided, use this exact name |
|
|
21
|
+
|
|
22
|
+
## Execution
|
|
23
|
+
|
|
24
|
+
**Use three skills in sequence:**
|
|
25
|
+
|
|
26
|
+
1. `Skill("plugin-registry-scanner")` → Discover available skills from plugins
|
|
27
|
+
2. `Skill("skill-capability-matcher")` → Match requirements to skills
|
|
28
|
+
3. `Skill("workflow-schema-composer")` → Generate workflow file
|
|
29
|
+
|
|
30
|
+
Each skill's SKILL.md contains implementation details. See `plugins/looplia-core/skills/` for full documentation.
|
|
31
|
+
|
|
32
|
+
### Workflow
|
|
33
|
+
|
|
34
|
+
1. Gather requirements (if no description provided, ask user)
|
|
35
|
+
2. Call `Skill("plugin-registry-scanner")`
|
|
36
|
+
3. Call `Skill("skill-capability-matcher")` with registry + requirements
|
|
37
|
+
4. Call `Skill("workflow-schema-composer")` with matched skills + `--name` flag if provided
|
|
38
|
+
5. Save generated workflow to `~/.looplia/workflows/{name}.md`
|
|
39
|
+
6. Report success with run command example
|
|
40
|
+
|
|
41
|
+
## Examples
|
|
42
|
+
|
|
43
|
+
### Interactive Mode
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
User: /build
|
|
47
|
+
Claude: What should this workflow do?
|
|
48
|
+
User: Analyze YouTube videos and create blog outlines
|
|
49
|
+
Claude: Created: ~/.looplia/workflows/video-to-blog.md (3 steps)
|
|
50
|
+
Run with: looplia run video-to-blog --file <transcript.md>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Direct Mode
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
/build analyze videos and create blog outlines with key quotes
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### With Explicit Name
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
/build --name article-summary summarize articles and extract key points
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Error Handling
|
|
66
|
+
|
|
67
|
+
| Scenario | Response |
|
|
68
|
+
|----------|----------|
|
|
69
|
+
| No plugins installed | Error: "No skills found. Install looplia-writer plugin." |
|
|
70
|
+
| No matching skills | Warning: Show capability gaps, offer partial workflow |
|
|
71
|
+
| Invalid workflow generated | Retry generation with schema reminder |
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: List available Looplia workflows
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# List Workflows
|
|
6
|
+
|
|
7
|
+
Show all available workflows in the `workflows/` directory.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/list-workflows
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Execution
|
|
16
|
+
|
|
17
|
+
1. **Scan workflows directory**
|
|
18
|
+
- Read all `*.md` files in `workflows/`
|
|
19
|
+
- Parse YAML frontmatter from each
|
|
20
|
+
|
|
21
|
+
2. **Extract metadata**
|
|
22
|
+
- name
|
|
23
|
+
- description
|
|
24
|
+
- outputs (list of step names)
|
|
25
|
+
- final output name
|
|
26
|
+
|
|
27
|
+
3. **Display results**
|
|
28
|
+
- Table format with workflow info
|
|
29
|
+
- Show example usage
|
|
30
|
+
|
|
31
|
+
## Example Output
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Available Workflows
|
|
35
|
+
===================
|
|
36
|
+
|
|
37
|
+
| Workflow | Description | Steps |
|
|
38
|
+
|--------------|------------------------------|--------------------------------|
|
|
39
|
+
| writing-kit | Generate content writing kit | summary → ideas → writing-kit |
|
|
40
|
+
|
|
41
|
+
Usage:
|
|
42
|
+
/run writing-kit --file <path>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## No Workflows Found
|
|
46
|
+
|
|
47
|
+
If no workflows exist:
|
|
48
|
+
1. Report that no workflows are available
|
|
49
|
+
2. Suggest using `/build-workflow` to create one
|
|
50
|
+
3. Provide example: `/build-workflow my-workflow`
|
|
51
|
+
|
|
52
|
+
## Related Commands
|
|
53
|
+
|
|
54
|
+
- `/run <workflow-id> --file <path>` - Execute a workflow
|
|
55
|
+
- `/build-workflow <name>` - Create a new workflow
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Execute a looplia workflow on content. Run looplia pipeline, start workflow automation.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Execute Looplia Workflow
|
|
6
|
+
|
|
7
|
+
Run a looplia workflow from `workflows/` on provided content.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/run <workflow-id> --file <path>
|
|
13
|
+
/run <workflow-id> --sandbox-id <id>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Arguments
|
|
17
|
+
|
|
18
|
+
| Argument | Description |
|
|
19
|
+
|----------|-------------|
|
|
20
|
+
| `workflow-id` | Name of workflow (e.g., "writing-kit") |
|
|
21
|
+
| `--file <path>` | Path to content file (creates new sandbox) |
|
|
22
|
+
| `--sandbox-id <id>` | Resume existing sandbox |
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
/run writing-kit --file ~/articles/draft.md
|
|
28
|
+
/run writing-kit --sandbox-id draft-2025-12-18-abc123
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Execution
|
|
32
|
+
|
|
33
|
+
**Use the `Skill("workflow-executor")` to handle all execution.**
|
|
34
|
+
|
|
35
|
+
The workflow-executor skill:
|
|
36
|
+
1. Parses workflow YAML from `workflows/{workflow-id}.md`
|
|
37
|
+
2. Creates/resumes sandbox
|
|
38
|
+
3. Executes each step via `Task(skill-executor)`
|
|
39
|
+
4. Manages validation state
|
|
40
|
+
5. Returns final artifact
|
|
41
|
+
|
|
42
|
+
See `plugins/looplia-core/skills/workflow-executor/SKILL.md` for implementation details.
|
|
43
|
+
|
|
44
|
+
## Error Handling
|
|
45
|
+
|
|
46
|
+
| Error | Action |
|
|
47
|
+
|-------|--------|
|
|
48
|
+
| Workflow not found | Report available workflows via `/list-workflows` |
|
|
49
|
+
| File not found | Report specific error with path |
|
|
50
|
+
| Sandbox not found | Report available sandboxes |
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://code.claude.com/schemas/hooks.json",
|
|
3
|
+
"hooks": [
|
|
4
|
+
{
|
|
5
|
+
"event": "SessionStart",
|
|
6
|
+
"command": "echo '🚀 Looplia session started'",
|
|
7
|
+
"description": "Log session start"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"event": "PostToolUse",
|
|
11
|
+
"matcher": "Write",
|
|
12
|
+
"command": "./scripts/hooks/post-write-validate.sh",
|
|
13
|
+
"description": "Auto-validate artifacts written to sandbox outputs"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"event": "Stop",
|
|
17
|
+
"command": "./scripts/hooks/stop-guard.sh",
|
|
18
|
+
"description": "Guard workflow completion - block until all validated"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"event": "SessionStart",
|
|
22
|
+
"matcher": "compact",
|
|
23
|
+
"command": "./scripts/hooks/compact-inject-state.sh",
|
|
24
|
+
"description": "Re-inject sandbox state after context compact"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Context Compact State Injection Hook (v0.6.0)
|
|
3
|
+
# Triggered: When context is compacted (SessionStart:compact)
|
|
4
|
+
# Action: Re-inject current sandbox progress into new context
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Find active sandbox
|
|
9
|
+
SANDBOX_BASE="${HOME}/.looplia/sandbox"
|
|
10
|
+
if [[ ! -d "$SANDBOX_BASE" ]]; then
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# Sort by modification time (newest first) to get most recent sandbox
|
|
15
|
+
SANDBOX_DIR=$(ls -td "$SANDBOX_BASE"/*/ 2>/dev/null | head -1 | sed 's:/$::')
|
|
16
|
+
if [[ -z "$SANDBOX_DIR" ]]; then
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
VALIDATION_JSON="$SANDBOX_DIR/validation.json"
|
|
21
|
+
SANDBOX_ID=$(basename "$SANDBOX_DIR")
|
|
22
|
+
|
|
23
|
+
if [[ ! -f "$VALIDATION_JSON" ]]; then
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
WORKFLOW=$(jq -r '.workflow // "unknown"' "$VALIDATION_JSON")
|
|
28
|
+
|
|
29
|
+
# Build progress summary (v0.6.0 uses "steps" not "outputs")
|
|
30
|
+
echo "=== Active Sandbox: $SANDBOX_ID ==="
|
|
31
|
+
echo "Workflow: $WORKFLOW"
|
|
32
|
+
echo ""
|
|
33
|
+
echo "Progress:"
|
|
34
|
+
jq -r '.steps | to_entries[] | " - \(.key): \(if .value.validated then "✓ validated" else "⏳ pending" end)"' "$VALIDATION_JSON"
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Next: Complete pending steps in dependency order."
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Post-Write Artifact Validator Hook (v0.6.0)
|
|
3
|
+
# Triggered: When Write tool completes
|
|
4
|
+
# Action: Run semantic validation via validate.ts for sandbox outputs
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Read JSON input from stdin
|
|
9
|
+
INPUT=$(cat)
|
|
10
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
11
|
+
|
|
12
|
+
# Only process sandbox/ files (matches sandbox/{id}/outputs/*.json pattern)
|
|
13
|
+
if [[ "$FILE_PATH" != *"/sandbox/"* ]]; then
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Check if it's in outputs/ directory
|
|
18
|
+
if [[ "$FILE_PATH" != *"/outputs/"* ]]; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Extract sandbox directory and artifact name
|
|
23
|
+
SANDBOX_DIR=$(dirname "$(dirname "$FILE_PATH")")
|
|
24
|
+
ARTIFACT=$(basename "$FILE_PATH" .json)
|
|
25
|
+
VALIDATION_JSON="$SANDBOX_DIR/validation.json"
|
|
26
|
+
|
|
27
|
+
# Check for validation.json
|
|
28
|
+
if [[ ! -f "$VALIDATION_JSON" ]]; then
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Use file locking to prevent race conditions when multiple writes happen concurrently
|
|
33
|
+
# flock ensures exclusive access to validation.json during read-modify-write cycle
|
|
34
|
+
LOCK_FILE="${VALIDATION_JSON}.lock"
|
|
35
|
+
|
|
36
|
+
(
|
|
37
|
+
# Acquire exclusive lock (wait up to 30 seconds)
|
|
38
|
+
if ! flock -x -w 30 200; then
|
|
39
|
+
echo "Failed to acquire lock on validation.json" >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Get validation criteria from validation.json (v0.6.0 uses "steps" not "outputs")
|
|
44
|
+
CRITERIA=$(jq -r --arg art "$ARTIFACT" '.steps[$art].validate // empty' "$VALIDATION_JSON" 2>/dev/null)
|
|
45
|
+
|
|
46
|
+
if [[ -z "$CRITERIA" || "$CRITERIA" == "null" ]]; then
|
|
47
|
+
# No criteria defined - just check JSON validity
|
|
48
|
+
if ! jq empty "$FILE_PATH" 2>/dev/null; then
|
|
49
|
+
echo "Validation failed for $ARTIFACT: Invalid JSON" >&2
|
|
50
|
+
exit 2
|
|
51
|
+
fi
|
|
52
|
+
else
|
|
53
|
+
# Run full semantic validation via validate.ts
|
|
54
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
55
|
+
VALIDATOR_SCRIPT="$SCRIPT_DIR/../../skills/workflow-validator/scripts/validate.ts"
|
|
56
|
+
|
|
57
|
+
if [[ -f "$VALIDATOR_SCRIPT" ]]; then
|
|
58
|
+
# Run the validation script
|
|
59
|
+
RESULT=$(bun "$VALIDATOR_SCRIPT" "$FILE_PATH" "$CRITERIA" 2>&1) || true
|
|
60
|
+
PASSED=$(echo "$RESULT" | jq -r '.passed // false' 2>/dev/null) || PASSED="false"
|
|
61
|
+
|
|
62
|
+
if [[ "$PASSED" != "true" ]]; then
|
|
63
|
+
echo "Semantic validation failed for $ARTIFACT:" >&2
|
|
64
|
+
echo "$RESULT" >&2
|
|
65
|
+
exit 2
|
|
66
|
+
fi
|
|
67
|
+
else
|
|
68
|
+
# Fallback to basic JSON check if validator script not found
|
|
69
|
+
if ! jq empty "$FILE_PATH" 2>/dev/null; then
|
|
70
|
+
echo "Validation failed for $ARTIFACT: Invalid JSON" >&2
|
|
71
|
+
exit 2
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Update validation.json to mark step as validated (v0.6.0 uses "steps")
|
|
77
|
+
jq --arg art "$ARTIFACT" '.steps[$art].validated = true' "$VALIDATION_JSON" > "${VALIDATION_JSON}.tmp"
|
|
78
|
+
mv "${VALIDATION_JSON}.tmp" "$VALIDATION_JSON"
|
|
79
|
+
echo "✓ Validated: $ARTIFACT.json"
|
|
80
|
+
|
|
81
|
+
) 200>"$LOCK_FILE"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Workflow Completion Guard Hook (v0.6.1)
|
|
3
|
+
# Triggered: When main agent attempts to stop
|
|
4
|
+
# Action: Block if any step has validated: false OR output files missing
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
INPUT=$(cat)
|
|
9
|
+
STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false')
|
|
10
|
+
|
|
11
|
+
# Prevent infinite loop
|
|
12
|
+
if [[ "$STOP_HOOK_ACTIVE" == "true" ]]; then
|
|
13
|
+
exit 0
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
# Find active sandbox (most recently modified sandbox directory)
|
|
17
|
+
SANDBOX_BASE="${HOME}/.looplia/sandbox"
|
|
18
|
+
if [[ ! -d "$SANDBOX_BASE" ]]; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Sort by modification time (newest first) to get most recent sandbox
|
|
23
|
+
SANDBOX_DIR=$(ls -td "$SANDBOX_BASE"/*/ 2>/dev/null | head -1 | sed 's:/$::')
|
|
24
|
+
if [[ -z "$SANDBOX_DIR" ]]; then
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
VALIDATION_JSON="$SANDBOX_DIR/validation.json"
|
|
29
|
+
if [[ ! -f "$VALIDATION_JSON" ]]; then
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Check for missing output files first (more actionable feedback)
|
|
34
|
+
MISSING=""
|
|
35
|
+
for step in $(jq -r '.steps | keys[]' "$VALIDATION_JSON" 2>/dev/null); do
|
|
36
|
+
OUTPUT_PATH=$(jq -r --arg s "$step" '.steps[$s].output // empty' "$VALIDATION_JSON" 2>/dev/null)
|
|
37
|
+
if [[ -n "$OUTPUT_PATH" && ! -f "$OUTPUT_PATH" ]]; then
|
|
38
|
+
MISSING="$MISSING $step"
|
|
39
|
+
fi
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
if [[ -n "$MISSING" ]]; then
|
|
43
|
+
echo "{\"decision\": \"block\", \"reason\": \"Missing output files for steps:$MISSING. You MUST call the Write tool to create these files at the paths specified in the workflow.\"}"
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Check all steps are validated (v0.6.0 uses "steps" not "outputs")
|
|
48
|
+
PENDING=$(jq -r '.steps | to_entries[] | select(.value.validated == false) | .key' "$VALIDATION_JSON" 2>/dev/null | tr '\n' ', ' | sed 's/,$//')
|
|
49
|
+
|
|
50
|
+
if [[ -n "$PENDING" ]]; then
|
|
51
|
+
echo "{\"decision\": \"block\", \"reason\": \"Workflow incomplete. Pending validation for steps: $PENDING. Output files exist but need validation - re-write them to trigger validation.\"}"
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# All validated - allow stop
|
|
56
|
+
exit 0
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plugin-registry-scanner
|
|
3
|
+
description: |
|
|
4
|
+
This skill should be used when the user wants to discover available looplia skills,
|
|
5
|
+
scan installed plugins, or list what capabilities are available. Use when someone says
|
|
6
|
+
"what looplia skills are installed", "list available skills", "scan plugins", "/build",
|
|
7
|
+
"what can looplia do", or "show me all looplia capabilities".
|
|
8
|
+
|
|
9
|
+
First step in looplia workflow building: scans plugins/*/skills/*/SKILL.md to build
|
|
10
|
+
a registry of available skills. Part of the skills-first architecture where one workflow
|
|
11
|
+
step invokes one skill-executor to orchestrate multiple skills.
|
|
12
|
+
tools: Bash, Read, Glob
|
|
13
|
+
model: claude-haiku-4-5-20251001
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Plugin Registry Scanner
|
|
17
|
+
|
|
18
|
+
Discover and catalog all skills from installed looplia plugins.
|
|
19
|
+
|
|
20
|
+
## Purpose
|
|
21
|
+
|
|
22
|
+
Scan the `plugins/*/skills/*/SKILL.md` directory structure to build a registry of available skills with their capabilities.
|
|
23
|
+
|
|
24
|
+
## Process
|
|
25
|
+
|
|
26
|
+
### 1. Scan Plugin Directories
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
bun plugins/looplia-core/skills/plugin-registry-scanner/scripts/scan-plugins.ts
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
This deterministic script returns a JSON registry of all discovered skills.
|
|
33
|
+
|
|
34
|
+
### 2. Parse the Registry
|
|
35
|
+
|
|
36
|
+
The script output contains:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"plugins": [
|
|
41
|
+
{
|
|
42
|
+
"name": "looplia-writer",
|
|
43
|
+
"path": "plugins/looplia-writer",
|
|
44
|
+
"skills": [
|
|
45
|
+
{
|
|
46
|
+
"name": "media-reviewer",
|
|
47
|
+
"description": "Deep content analysis (structure, themes, narrative)",
|
|
48
|
+
"tools": ["Read", "Grep", "Glob"],
|
|
49
|
+
"model": "haiku",
|
|
50
|
+
"capabilities": ["content analysis", "theme extraction", "quote identification"]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"summary": {
|
|
56
|
+
"totalPlugins": 2,
|
|
57
|
+
"totalSkills": 7
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 3. Infer Capabilities (Optional LLM Step)
|
|
63
|
+
|
|
64
|
+
If capability inference is needed beyond what the script provides, analyze skill descriptions to extract:
|
|
65
|
+
- Input types handled (video, audio, text, etc.)
|
|
66
|
+
- Processing capabilities (analyze, transform, generate, etc.)
|
|
67
|
+
- Output formats (JSON, markdown, structured data)
|
|
68
|
+
|
|
69
|
+
## Output Schema
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"plugins": [
|
|
74
|
+
{
|
|
75
|
+
"name": "string",
|
|
76
|
+
"path": "string",
|
|
77
|
+
"skills": [
|
|
78
|
+
{
|
|
79
|
+
"name": "string",
|
|
80
|
+
"description": "string",
|
|
81
|
+
"tools": ["string"],
|
|
82
|
+
"model": "string",
|
|
83
|
+
"capabilities": ["string"]
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
"summary": {
|
|
89
|
+
"totalPlugins": "number",
|
|
90
|
+
"totalSkills": "number"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Usage
|
|
96
|
+
|
|
97
|
+
This skill is typically invoked as the first step in workflow building:
|
|
98
|
+
|
|
99
|
+
1. Scan available plugins and skills
|
|
100
|
+
2. Pass registry to skill-capability-matcher
|
|
101
|
+
3. Use matched skills in workflow-schema-composer
|
|
102
|
+
|
|
103
|
+
## Notes
|
|
104
|
+
|
|
105
|
+
- The scan script is deterministic (no LLM tokens)
|
|
106
|
+
- Capabilities can be inferred from descriptions if not explicitly declared
|
|
107
|
+
- Skills without SKILL.md files are skipped
|
|
108
|
+
- Invalid frontmatter generates warnings but doesn't halt scanning
|