@looplia/looplia-cli 0.7.3 → 0.7.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/dist/chunk-4TKNQ5RW.js +305 -0
- package/dist/{chunk-MHR5TPHE.js → chunk-GIZRTNY3.js} +1991 -417
- package/dist/{claude-agent-sdk-SQ6YU4VE.js → claude-agent-sdk-W5MXMV4Q.js} +5 -1
- package/dist/cli.js +157 -35
- package/dist/{dist-PMEIK6PJ.js → dist-3XSIQAV3.js} +2 -2
- package/package.json +1 -1
- package/plugins/looplia-core/skills/workflow-executor/SKILL.md +73 -18
- package/plugins/looplia-writer/workflows/writing-kit.md +1 -3
- package/dist/chunk-VYGRYFSY.js +0 -1148
- package/plugins/looplia-core/hooks/hooks.json +0 -22
- package/plugins/looplia-core/scripts/hooks/compact-inject-state.sh +0 -36
- package/plugins/looplia-core/scripts/hooks/post-write-validate.sh +0 -81
- package/plugins/looplia-core/scripts/hooks/stop-guard.sh +0 -56
- package/plugins/looplia-core/skills/workflow-executor-inline/SKILL.md +0 -217
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://code.claude.com/schemas/hooks.json",
|
|
3
|
-
"hooks": [
|
|
4
|
-
{
|
|
5
|
-
"event": "PostToolUse",
|
|
6
|
-
"matcher": "Write",
|
|
7
|
-
"command": "./scripts/hooks/post-write-validate.sh",
|
|
8
|
-
"description": "Auto-validate artifacts written to sandbox outputs"
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
"event": "Stop",
|
|
12
|
-
"command": "./scripts/hooks/stop-guard.sh",
|
|
13
|
-
"description": "Guard workflow completion - block until all validated"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"event": "SessionStart",
|
|
17
|
-
"matcher": "compact",
|
|
18
|
-
"command": "./scripts/hooks/compact-inject-state.sh",
|
|
19
|
-
"description": "Re-inject sandbox state after context compact"
|
|
20
|
-
}
|
|
21
|
-
]
|
|
22
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
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."
|
|
@@ -1,81 +0,0 @@
|
|
|
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" >&2
|
|
80
|
-
|
|
81
|
-
) 200>"$LOCK_FILE"
|
|
@@ -1,56 +0,0 @@
|
|
|
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
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: workflow-executor-inline
|
|
3
|
-
description: |
|
|
4
|
-
Inline workflow executor for proxy providers (ZenMux, custom API providers).
|
|
5
|
-
Executes workflow steps directly in the main context WITHOUT spawning Task subagents.
|
|
6
|
-
|
|
7
|
-
Use this skill when:
|
|
8
|
-
- Running looplia workflows via ZenMux or other proxy providers
|
|
9
|
-
- Task subagents fail with "invalid_model" errors
|
|
10
|
-
- You need inline execution without context isolation
|
|
11
|
-
|
|
12
|
-
Architecture: Each workflow step is executed INLINE (no Task tool) - read skill, execute
|
|
13
|
-
mission, write output, then proceed to next step. All steps share the main context.
|
|
14
|
-
|
|
15
|
-
v0.6.6: Created for cross-provider compatibility with ZenMux.
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
# Workflow Executor Inline (v0.6.6)
|
|
19
|
-
|
|
20
|
-
Execute looplia workflows **without Task subagents**. This skill is specifically designed for proxy providers (ZenMux, custom) where the Claude Agent SDK's subagent spawning doesn't work due to model name incompatibility.
|
|
21
|
-
|
|
22
|
-
## When to Use
|
|
23
|
-
|
|
24
|
-
Use this skill when:
|
|
25
|
-
- The system has injected a hint to use inline execution
|
|
26
|
-
- Running workflows via ZenMux or other proxy providers
|
|
27
|
-
- Task subagents fail with "invalid_model" errors
|
|
28
|
-
|
|
29
|
-
## CRITICAL: Inline Execution (No Subagents)
|
|
30
|
-
|
|
31
|
-
**DO NOT spawn Task subagents.** Execute all workflow steps directly in the main context.
|
|
32
|
-
|
|
33
|
-
For each workflow step:
|
|
34
|
-
|
|
35
|
-
1. **Read the skill definition** using Skill tool: `Skill("{step.skill}")`
|
|
36
|
-
2. **Read input file(s)** if specified using Read tool
|
|
37
|
-
3. **Execute the mission** following skill instructions
|
|
38
|
-
4. **Write JSON output** to specified path using Write tool
|
|
39
|
-
5. **Validate output** (if validation rules defined)
|
|
40
|
-
6. **Proceed to next step**
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Execution Protocol
|
|
45
|
-
|
|
46
|
-
### Phase 1: Sandbox Setup
|
|
47
|
-
|
|
48
|
-
Same as standard workflow-executor:
|
|
49
|
-
|
|
50
|
-
1. Generate sandbox ID:
|
|
51
|
-
```
|
|
52
|
-
{first-input-name}-{YYYY-MM-DD}-{random4chars}
|
|
53
|
-
Example: video-transcript-2025-12-18-xk7m
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
2. Create folder structure:
|
|
57
|
-
```
|
|
58
|
-
sandbox/{sandbox-id}/
|
|
59
|
-
├── inputs/
|
|
60
|
-
│ └── {input-files}.md
|
|
61
|
-
├── outputs/
|
|
62
|
-
├── logs/
|
|
63
|
-
└── validation.json
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
3. Copy input files to `inputs/`
|
|
67
|
-
|
|
68
|
-
### Phase 2: Workflow Parsing
|
|
69
|
-
|
|
70
|
-
1. Read workflow file: `workflows/{workflow-id}.md`
|
|
71
|
-
2. Parse YAML frontmatter for steps
|
|
72
|
-
3. Validate each step has `skill:` and `mission:` fields
|
|
73
|
-
4. Build dependency graph from `needs:` fields
|
|
74
|
-
|
|
75
|
-
### Phase 3: Inline Step Execution
|
|
76
|
-
|
|
77
|
-
**Execute steps ONE AT A TIME, INLINE (no Task tool):**
|
|
78
|
-
|
|
79
|
-
```
|
|
80
|
-
FOR EACH step in dependency order:
|
|
81
|
-
│
|
|
82
|
-
▼
|
|
83
|
-
┌─────────────────────────────────────────┐
|
|
84
|
-
│ 1. INVOKE skill: Skill("{step.skill}") │
|
|
85
|
-
│ → This loads skill context │
|
|
86
|
-
│ │
|
|
87
|
-
│ 2. READ input file (if provided) │
|
|
88
|
-
│ → Use Read tool │
|
|
89
|
-
│ │
|
|
90
|
-
│ 3. EXECUTE mission │
|
|
91
|
-
│ → Follow skill instructions │
|
|
92
|
-
│ → Generate JSON output │
|
|
93
|
-
│ │
|
|
94
|
-
│ 4. WRITE output file │
|
|
95
|
-
│ → Use Write tool │
|
|
96
|
-
│ → Output to step.output path │
|
|
97
|
-
│ │
|
|
98
|
-
│ 5. VALIDATE output │
|
|
99
|
-
│ → Check required_fields │
|
|
100
|
-
│ → Retry if failed (max 2x) │
|
|
101
|
-
│ │
|
|
102
|
-
│ 6. UPDATE validation.json │
|
|
103
|
-
│ → Mark step as validated: true │
|
|
104
|
-
└─────────────────────────────────────────┘
|
|
105
|
-
│
|
|
106
|
-
▼
|
|
107
|
-
NEXT STEP
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Example: Inline Execution
|
|
111
|
-
|
|
112
|
-
For step:
|
|
113
|
-
```yaml
|
|
114
|
-
- id: analyze-content
|
|
115
|
-
skill: media-reviewer
|
|
116
|
-
mission: |
|
|
117
|
-
Deep analysis of video transcript. Extract key themes,
|
|
118
|
-
important quotes, and narrative structure.
|
|
119
|
-
input: ${{ sandbox }}/inputs/content.md
|
|
120
|
-
output: ${{ sandbox }}/outputs/analysis.json
|
|
121
|
-
validate:
|
|
122
|
-
required_fields: [contentId, headline, keyThemes]
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
**Inline execution sequence:**
|
|
126
|
-
|
|
127
|
-
1. **Invoke skill:**
|
|
128
|
-
```
|
|
129
|
-
Skill("media-reviewer")
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
2. **Read input:**
|
|
133
|
-
```
|
|
134
|
-
Read("sandbox/video-2025-12-18-xk7m/inputs/content.md")
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
3. **Execute mission:**
|
|
138
|
-
- Follow media-reviewer skill instructions
|
|
139
|
-
- Analyze the content
|
|
140
|
-
- Generate structured JSON output
|
|
141
|
-
|
|
142
|
-
4. **Write output:**
|
|
143
|
-
```
|
|
144
|
-
Write("sandbox/video-2025-12-18-xk7m/outputs/analysis.json", jsonContent)
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
5. **Validate:**
|
|
148
|
-
- Check contentId, headline, keyThemes exist
|
|
149
|
-
- Update validation.json
|
|
150
|
-
|
|
151
|
-
6. **Proceed to next step**
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## Anti-Patterns
|
|
156
|
-
|
|
157
|
-
❌ **WRONG - Spawning Task subagents:**
|
|
158
|
-
```json
|
|
159
|
-
{
|
|
160
|
-
"subagent_type": "workflow-step",
|
|
161
|
-
"description": "Execute step...",
|
|
162
|
-
"prompt": "..."
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
Task subagents don't work with proxy providers.
|
|
166
|
-
|
|
167
|
-
❌ **WRONG - Batching all steps:**
|
|
168
|
-
Execute all steps at once without validation between them.
|
|
169
|
-
|
|
170
|
-
✅ **CORRECT - Inline step-by-step:**
|
|
171
|
-
1. Skill("media-reviewer")
|
|
172
|
-
2. Read input
|
|
173
|
-
3. Execute mission
|
|
174
|
-
4. Write output
|
|
175
|
-
5. Validate
|
|
176
|
-
6. Proceed to next
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
## Variable Substitution
|
|
181
|
-
|
|
182
|
-
Same as standard workflow-executor:
|
|
183
|
-
|
|
184
|
-
| Variable | Resolution |
|
|
185
|
-
|----------|------------|
|
|
186
|
-
| `${{ sandbox }}` | `sandbox/{sandbox-id}` |
|
|
187
|
-
| `${{ inputs.{name} }}` | `sandbox/{id}/inputs/{name}.md` |
|
|
188
|
-
| `${{ steps.{id}.output }}` | Output path of step `{id}` |
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
## Error Handling
|
|
193
|
-
|
|
194
|
-
| Scenario | Action |
|
|
195
|
-
|----------|--------|
|
|
196
|
-
| Workflow not found | Error with available workflows |
|
|
197
|
-
| Step missing `skill:` | Error: "Step missing required 'skill' field" |
|
|
198
|
-
| Step missing `mission:` | Error: "Step missing required 'mission' field" |
|
|
199
|
-
| Validation fails | Retry inline with feedback (max 2 retries) |
|
|
200
|
-
| Max retries exceeded | Report failure with details |
|
|
201
|
-
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
## Key Differences from Standard workflow-executor
|
|
205
|
-
|
|
206
|
-
| Aspect | workflow-executor | workflow-executor-inline |
|
|
207
|
-
|--------|------------------|--------------------------|
|
|
208
|
-
| Execution | Task subagent per step | Inline in main context |
|
|
209
|
-
| Context | Isolated per step | Shared main context |
|
|
210
|
-
| Provider Support | Anthropic Direct only | All providers |
|
|
211
|
-
| Use Case | Production (Anthropic) | Proxy providers (ZenMux) |
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
## Version History
|
|
216
|
-
|
|
217
|
-
- **v0.6.6**: Created for ZenMux cross-provider compatibility
|