@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
|
@@ -8,8 +8,10 @@ import {
|
|
|
8
8
|
applyPreset,
|
|
9
9
|
buildSummarizePrompt,
|
|
10
10
|
clearClaudeCodePathCache,
|
|
11
|
+
createBuildHooks,
|
|
11
12
|
createClaudeAgentExecutor,
|
|
12
13
|
createQueryLogger,
|
|
14
|
+
createWorkflowHooks,
|
|
13
15
|
ensureWorkspace,
|
|
14
16
|
executeAgenticQueryStreaming,
|
|
15
17
|
executeInteractiveQueryStreaming,
|
|
@@ -31,7 +33,7 @@ import {
|
|
|
31
33
|
validateConfig,
|
|
32
34
|
writeLoopliaSettings,
|
|
33
35
|
writeUserProfile
|
|
34
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-GIZRTNY3.js";
|
|
35
37
|
import "./chunk-VRBGWKZ6.js";
|
|
36
38
|
import "./chunk-Y55L47HC.js";
|
|
37
39
|
export {
|
|
@@ -42,8 +44,10 @@ export {
|
|
|
42
44
|
applyPreset,
|
|
43
45
|
buildSummarizePrompt,
|
|
44
46
|
clearClaudeCodePathCache,
|
|
47
|
+
createBuildHooks,
|
|
45
48
|
createClaudeAgentExecutor,
|
|
46
49
|
createQueryLogger,
|
|
50
|
+
createWorkflowHooks,
|
|
47
51
|
ensureWorkspace,
|
|
48
52
|
executeAgenticQueryStreaming,
|
|
49
53
|
executeInteractiveQueryStreaming,
|
package/dist/cli.js
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import {
|
|
3
3
|
ensureWorkflowSkills,
|
|
4
|
-
extractWorkflowSkills,
|
|
5
4
|
findSkill,
|
|
6
5
|
getAvailableSkills,
|
|
7
6
|
getInstalledSkills,
|
|
8
7
|
installSkill,
|
|
9
|
-
isInputlessWorkflow,
|
|
10
8
|
loadCompiledRegistry,
|
|
11
|
-
parseWorkflow,
|
|
12
9
|
removeSkill,
|
|
13
|
-
updateSkill
|
|
14
|
-
|
|
15
|
-
} from "./chunk-VYGRYFSY.js";
|
|
10
|
+
updateSkill
|
|
11
|
+
} from "./chunk-4TKNQ5RW.js";
|
|
16
12
|
import "./chunk-QQGRKUSM.js";
|
|
17
13
|
import {
|
|
18
14
|
addSource,
|
|
@@ -28,21 +24,29 @@ import {
|
|
|
28
24
|
PRESETS,
|
|
29
25
|
applyPreset,
|
|
30
26
|
copyPlugins,
|
|
27
|
+
createBuildHooks,
|
|
31
28
|
createClaudeAgentExecutor,
|
|
29
|
+
createWorkflowHooks,
|
|
32
30
|
downloadRemotePlugins,
|
|
33
31
|
ensureWorkspace,
|
|
32
|
+
extractWorkflowSkills,
|
|
33
|
+
generateValidationManifest,
|
|
34
34
|
getConfigPath,
|
|
35
|
+
getFinalStep,
|
|
35
36
|
getLoopliaPluginPath,
|
|
36
37
|
getSettingsDisplayInfo,
|
|
37
38
|
initializeCommandEnvironment,
|
|
39
|
+
isInputlessWorkflow,
|
|
38
40
|
isLoopliaInitialized,
|
|
39
41
|
maskAuthToken,
|
|
42
|
+
parseWorkflow,
|
|
40
43
|
readLoopliaSettings,
|
|
41
44
|
readUserProfile,
|
|
42
45
|
removeLoopliaSettings,
|
|
46
|
+
validateUserProfile,
|
|
43
47
|
writeLoopliaSettings,
|
|
44
48
|
writeUserProfile
|
|
45
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-GIZRTNY3.js";
|
|
46
50
|
import "./chunk-VRBGWKZ6.js";
|
|
47
51
|
import {
|
|
48
52
|
copyOutputsToDestination,
|
|
@@ -24968,9 +24972,9 @@ init_esm_shims();
|
|
|
24968
24972
|
|
|
24969
24973
|
// src/commands/build.ts
|
|
24970
24974
|
init_esm_shims();
|
|
24971
|
-
import { existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
|
|
24975
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
24972
24976
|
import { homedir as homedir2 } from "os";
|
|
24973
|
-
import { resolve } from "path";
|
|
24977
|
+
import { join as join2, resolve } from "path";
|
|
24974
24978
|
|
|
24975
24979
|
// src/components/index.ts
|
|
24976
24980
|
init_esm_shims();
|
|
@@ -32868,7 +32872,7 @@ async function* analyzeDescriptionStreaming(description, workspace, questionCall
|
|
|
32868
32872
|
const { createSandboxDirectories: createSandboxDirectories2, generateSandboxId: generateSandboxId2 } = await import("./sandbox-XVMNWAJO.js");
|
|
32869
32873
|
const sandboxId = generateSandboxId2("build");
|
|
32870
32874
|
createSandboxDirectories2(workspace, sandboxId);
|
|
32871
|
-
const { executeInteractiveQueryStreaming } = await import("./claude-agent-sdk-
|
|
32875
|
+
const { executeInteractiveQueryStreaming } = await import("./claude-agent-sdk-W5MXMV4Q.js");
|
|
32872
32876
|
const prompt = `${buildAnalysisPrompt(description)} --sandbox-id ${sandboxId}`;
|
|
32873
32877
|
const generator = executeInteractiveQueryStreaming(
|
|
32874
32878
|
prompt,
|
|
@@ -34115,9 +34119,13 @@ async function executeBatch(prompt, workspace, executor) {
|
|
|
34115
34119
|
console.error("\u23F3 Building workflow...");
|
|
34116
34120
|
const { createSandboxDirectories: createSandboxDirectories2, generateSandboxId: generateSandboxId2 } = await import("./sandbox-XVMNWAJO.js");
|
|
34117
34121
|
const sandboxId = generateSandboxId2("build");
|
|
34122
|
+
const sandboxDir = join2(workspace, "sandbox", sandboxId);
|
|
34118
34123
|
createSandboxDirectories2(workspace, sandboxId);
|
|
34124
|
+
createBuildValidationJson(sandboxDir, sandboxId, "untitled");
|
|
34125
|
+
process.env.LOOPLIA_SANDBOX_ID = sandboxId;
|
|
34126
|
+
process.env.LOOPLIA_SANDBOX_ROOT = join2(workspace, "sandbox");
|
|
34119
34127
|
const promptWithSandbox = `${prompt} --sandbox-id ${sandboxId}`;
|
|
34120
|
-
const exec2 = executor ?? createClaudeAgentExecutor({ workspace });
|
|
34128
|
+
const exec2 = executor ?? createClaudeAgentExecutor({ workspace, buildHooks: createBuildHooks() });
|
|
34121
34129
|
const result = await exec2.executePrompt(promptWithSandbox, {
|
|
34122
34130
|
workspace,
|
|
34123
34131
|
contentId: sandboxId
|
|
@@ -34125,17 +34133,65 @@ async function executeBatch(prompt, workspace, executor) {
|
|
|
34125
34133
|
if (result.success && result.data) {
|
|
34126
34134
|
return result.data;
|
|
34127
34135
|
}
|
|
34136
|
+
if (result.success && !result.data) {
|
|
34137
|
+
const validation = readBuildValidationSync(sandboxDir);
|
|
34138
|
+
if (validation?.workflowValidated && validation.workflowPath) {
|
|
34139
|
+
return {
|
|
34140
|
+
status: "success",
|
|
34141
|
+
workflowPath: validation.workflowPath,
|
|
34142
|
+
workflowName: validation.workflowName ?? void 0
|
|
34143
|
+
};
|
|
34144
|
+
}
|
|
34145
|
+
}
|
|
34128
34146
|
return {
|
|
34129
34147
|
status: "error",
|
|
34130
34148
|
error: result.error?.message ?? "Unknown error"
|
|
34131
34149
|
};
|
|
34132
34150
|
}
|
|
34151
|
+
function createBuildValidationJson(sandboxDir, sandboxId, workflowName) {
|
|
34152
|
+
const validation = {
|
|
34153
|
+
type: "build",
|
|
34154
|
+
workflow: workflowName,
|
|
34155
|
+
version: "1.0.0",
|
|
34156
|
+
sandboxId,
|
|
34157
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34158
|
+
status: "building",
|
|
34159
|
+
workflowValidated: false,
|
|
34160
|
+
workflowPath: null,
|
|
34161
|
+
workflowName: null
|
|
34162
|
+
};
|
|
34163
|
+
writeFileSync2(
|
|
34164
|
+
join2(sandboxDir, "validation.json"),
|
|
34165
|
+
JSON.stringify(validation, null, 2),
|
|
34166
|
+
"utf-8"
|
|
34167
|
+
);
|
|
34168
|
+
}
|
|
34169
|
+
function readBuildValidationSync(sandboxDir) {
|
|
34170
|
+
try {
|
|
34171
|
+
const { readFileSync: readFileSync3 } = __require("fs");
|
|
34172
|
+
const content = readFileSync3(
|
|
34173
|
+
join2(sandboxDir, "validation.json"),
|
|
34174
|
+
"utf-8"
|
|
34175
|
+
);
|
|
34176
|
+
const manifest = JSON.parse(content);
|
|
34177
|
+
if (manifest.type === "build") {
|
|
34178
|
+
return manifest;
|
|
34179
|
+
}
|
|
34180
|
+
return;
|
|
34181
|
+
} catch {
|
|
34182
|
+
return;
|
|
34183
|
+
}
|
|
34184
|
+
}
|
|
34133
34185
|
async function* executeInteractiveStreamingBatch(prompt, workspace, questionCallback) {
|
|
34134
34186
|
const { createSandboxDirectories: createSandboxDirectories2, generateSandboxId: generateSandboxId2 } = await import("./sandbox-XVMNWAJO.js");
|
|
34135
34187
|
const sandboxId = generateSandboxId2("build");
|
|
34188
|
+
const sandboxDir = join2(workspace, "sandbox", sandboxId);
|
|
34136
34189
|
createSandboxDirectories2(workspace, sandboxId);
|
|
34190
|
+
createBuildValidationJson(sandboxDir, sandboxId, "untitled");
|
|
34191
|
+
process.env.LOOPLIA_SANDBOX_ID = sandboxId;
|
|
34192
|
+
process.env.LOOPLIA_SANDBOX_ROOT = join2(workspace, "sandbox");
|
|
34137
34193
|
const promptWithSandbox = `${prompt} --sandbox-id ${sandboxId}`;
|
|
34138
|
-
const { executeInteractiveQueryStreaming } = await import("./claude-agent-sdk-
|
|
34194
|
+
const { executeInteractiveQueryStreaming } = await import("./claude-agent-sdk-W5MXMV4Q.js");
|
|
34139
34195
|
const schema = {
|
|
34140
34196
|
type: "object",
|
|
34141
34197
|
properties: {
|
|
@@ -34149,7 +34205,7 @@ async function* executeInteractiveStreamingBatch(prompt, workspace, questionCall
|
|
|
34149
34205
|
const generator = executeInteractiveQueryStreaming(
|
|
34150
34206
|
promptWithSandbox,
|
|
34151
34207
|
schema,
|
|
34152
|
-
{ workspace },
|
|
34208
|
+
{ workspace, buildHooks: createBuildHooks() },
|
|
34153
34209
|
questionCallback
|
|
34154
34210
|
);
|
|
34155
34211
|
let iterResult = await generator.next();
|
|
@@ -34158,6 +34214,19 @@ async function* executeInteractiveStreamingBatch(prompt, workspace, questionCall
|
|
|
34158
34214
|
iterResult = await generator.next();
|
|
34159
34215
|
}
|
|
34160
34216
|
const executorResult = iterResult.value;
|
|
34217
|
+
if (executorResult.success && !executorResult.data) {
|
|
34218
|
+
const validation = readBuildValidationSync(sandboxDir);
|
|
34219
|
+
if (validation?.workflowValidated && validation.workflowPath) {
|
|
34220
|
+
return {
|
|
34221
|
+
success: true,
|
|
34222
|
+
data: {
|
|
34223
|
+
status: "success",
|
|
34224
|
+
workflowPath: validation.workflowPath,
|
|
34225
|
+
workflowName: validation.workflowName ?? void 0
|
|
34226
|
+
}
|
|
34227
|
+
};
|
|
34228
|
+
}
|
|
34229
|
+
}
|
|
34161
34230
|
if (executorResult.success) {
|
|
34162
34231
|
return {
|
|
34163
34232
|
success: true,
|
|
@@ -34456,8 +34525,12 @@ Usage:
|
|
|
34456
34525
|
Available presets:
|
|
34457
34526
|
ANTHROPIC_CLAUDE_HAIKU Anthropic Claude Haiku (default)
|
|
34458
34527
|
ANTHROPIC_CLAUDE_SONNET Anthropic Claude Sonnet
|
|
34528
|
+
CLAUDE_CODE_SUBSCRIPTION_HAIKU Claude Haiku via subscription (macOS)
|
|
34529
|
+
CLAUDE_CODE_SUBSCRIPTION_SONNET Claude Sonnet via subscription (macOS)
|
|
34530
|
+
CLAUDE_CODE_SUBSCRIPTION_OPUS Claude Opus via subscription (macOS)
|
|
34459
34531
|
ZENMUX_ANTHROPIC_HAIKU45 ZenMux Claude Haiku 4.5
|
|
34460
34532
|
ZENMUX_ZAI_GLM47 ZenMux GLM-4.7
|
|
34533
|
+
ZENMUX_ZAI_GLM47FLASHX ZenMux GLM-4.7-FlashX
|
|
34461
34534
|
ZENMUX_ZAI_GLM46VFLASH ZenMux GLM-4.6v-Flash
|
|
34462
34535
|
ZENMUX_MINIMAX_M21 ZenMux MiniMax-M2.1
|
|
34463
34536
|
ZENMUX_GOOGLE_GEMINI3FLASH ZenMux Gemini-3-Flash
|
|
@@ -34466,10 +34539,14 @@ Available presets:
|
|
|
34466
34539
|
ZENMUX_XAI_GROK41FAST ZenMux Grok-4.1-Fast
|
|
34467
34540
|
ZENMUX_DEEPSEEK_V32 ZenMux DeepSeek-v3.2
|
|
34468
34541
|
ZENMUX_MISTRAL_LARGE2512 ZenMux Mistral-Large-2512
|
|
34542
|
+
OPENROUTER_PRESET OpenRouter (user-configured preset)
|
|
34543
|
+
OPENROUTER_ZAI_GLM47FLASH OpenRouter GLM-4.7-Flash
|
|
34544
|
+
OLLAMA_GLM47_CLOUD Ollama GLM-4.7 Cloud
|
|
34545
|
+
OLLAMA_MINIMAX_M21_CLOUD Ollama MiniMax-M2.1 Cloud
|
|
34469
34546
|
|
|
34470
34547
|
Configuration keys for 'set':
|
|
34471
|
-
api-provider Provider type: anthropic, zenmux, custom
|
|
34472
|
-
base-url API base URL (for zenmux/custom)
|
|
34548
|
+
api-provider Provider type: anthropic, zenmux, openrouter, ollama, custom
|
|
34549
|
+
base-url API base URL (for zenmux/openrouter/ollama/custom)
|
|
34473
34550
|
auth-token Authentication token (fallback if env var not set)
|
|
34474
34551
|
main-model Model for main agent
|
|
34475
34552
|
executor-model Model for skill executor
|
|
@@ -34477,9 +34554,13 @@ Configuration keys for 'set':
|
|
|
34477
34554
|
API keys (set in .env - looplia auto-maps based on provider):
|
|
34478
34555
|
ANTHROPIC_API_KEY For Anthropic (direct)
|
|
34479
34556
|
ZENMUX_API_KEY For ZenMux (auto-mapped to ANTHROPIC_API_KEY)
|
|
34557
|
+
OPENROUTER_API_KEY For OpenRouter (auto-mapped to ANTHROPIC_AUTH_TOKEN)
|
|
34558
|
+
OLLAMA_API_KEY For Ollama (optional, defaults to "ollama")
|
|
34480
34559
|
|
|
34481
34560
|
Examples:
|
|
34482
34561
|
looplia config provider preset ZENMUX_ZAI_GLM47
|
|
34562
|
+
looplia config provider preset OPENROUTER_PRESET
|
|
34563
|
+
looplia config provider preset OLLAMA_GLM47_CLOUD
|
|
34483
34564
|
looplia config provider show
|
|
34484
34565
|
`);
|
|
34485
34566
|
}
|
|
@@ -34605,7 +34686,9 @@ async function showProviderConfig() {
|
|
|
34605
34686
|
console.log(` Preset: ${info.preset}`);
|
|
34606
34687
|
}
|
|
34607
34688
|
console.log(` Provider: ${info.provider}`);
|
|
34608
|
-
if (info.
|
|
34689
|
+
if (info.authTokenSource === "subscription") {
|
|
34690
|
+
console.log(" Auth Source: Claude Code Subscription (OAuth)");
|
|
34691
|
+
} else if (info.authToken) {
|
|
34609
34692
|
console.log(` Auth Token: ${maskAuthToken(info.authToken)}`);
|
|
34610
34693
|
}
|
|
34611
34694
|
console.log("\n Agent Models:");
|
|
@@ -34772,7 +34855,7 @@ async function runConfigCommand(args) {
|
|
|
34772
34855
|
|
|
34773
34856
|
// src/commands/init.ts
|
|
34774
34857
|
init_esm_shims();
|
|
34775
|
-
import { dirname, join as
|
|
34858
|
+
import { dirname, join as join3 } from "path";
|
|
34776
34859
|
import { createInterface } from "readline";
|
|
34777
34860
|
import { fileURLToPath } from "url";
|
|
34778
34861
|
|
|
@@ -34782,7 +34865,7 @@ init_esm_shims();
|
|
|
34782
34865
|
// src/commands/init.ts
|
|
34783
34866
|
function getCliBundledPluginsPath() {
|
|
34784
34867
|
const currentFile = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
|
|
34785
|
-
return
|
|
34868
|
+
return join3(currentFile, "..", "plugins");
|
|
34786
34869
|
}
|
|
34787
34870
|
function printInitHelp() {
|
|
34788
34871
|
console.log(`
|
|
@@ -35092,10 +35175,10 @@ import {
|
|
|
35092
35175
|
existsSync as existsSync4,
|
|
35093
35176
|
mkdirSync as mkdirSync3,
|
|
35094
35177
|
readFileSync as readFileSync2,
|
|
35095
|
-
writeFileSync as
|
|
35178
|
+
writeFileSync as writeFileSync3
|
|
35096
35179
|
} from "fs";
|
|
35097
35180
|
import { homedir as homedir3 } from "os";
|
|
35098
|
-
import { basename, join as
|
|
35181
|
+
import { basename, join as join4, resolve as resolve2 } from "path";
|
|
35099
35182
|
var RUN_COMMAND = COMMANDS.RUN;
|
|
35100
35183
|
function generateSandboxIdFromFile(filePath) {
|
|
35101
35184
|
const filename = basename(filePath, ".md");
|
|
@@ -35112,8 +35195,8 @@ function createInitialValidationJson(sandboxDir, sandboxId, workflowId) {
|
|
|
35112
35195
|
status: "pending",
|
|
35113
35196
|
steps: {}
|
|
35114
35197
|
};
|
|
35115
|
-
|
|
35116
|
-
|
|
35198
|
+
writeFileSync3(
|
|
35199
|
+
join4(sandboxDir, "validation.json"),
|
|
35117
35200
|
JSON.stringify(validation, null, 2),
|
|
35118
35201
|
"utf-8"
|
|
35119
35202
|
);
|
|
@@ -35125,7 +35208,7 @@ function createSandbox(workspace, filePath, workflowId) {
|
|
|
35125
35208
|
const absolutePath = resolve2(filePath);
|
|
35126
35209
|
copyFileSync(
|
|
35127
35210
|
absolutePath,
|
|
35128
|
-
|
|
35211
|
+
join4(sandboxDir, "inputs", SANDBOX_CONTENT_FILENAME)
|
|
35129
35212
|
);
|
|
35130
35213
|
createInitialValidationJson(sandboxDir, sandboxId, workflowId);
|
|
35131
35214
|
} catch (error) {
|
|
@@ -35143,8 +35226,8 @@ function createSandboxWithInputs(workspace, workflowId, inputs) {
|
|
|
35143
35226
|
const sandboxDir = createSandboxDirectories(workspace, sandboxId);
|
|
35144
35227
|
for (const [name, parsedInput] of Object.entries(inputs)) {
|
|
35145
35228
|
if (parsedInput.type === "json") {
|
|
35146
|
-
|
|
35147
|
-
|
|
35229
|
+
writeFileSync3(
|
|
35230
|
+
join4(sandboxDir, "inputs", `${name}.json`),
|
|
35148
35231
|
parsedInput.value,
|
|
35149
35232
|
"utf-8"
|
|
35150
35233
|
);
|
|
@@ -35153,7 +35236,7 @@ function createSandboxWithInputs(workspace, workflowId, inputs) {
|
|
|
35153
35236
|
if (!existsSync4(absolutePath)) {
|
|
35154
35237
|
throw new Error(`Input file not found: ${parsedInput.value}`);
|
|
35155
35238
|
}
|
|
35156
|
-
copyFileSync(absolutePath,
|
|
35239
|
+
copyFileSync(absolutePath, join4(sandboxDir, "inputs", `${name}.md`));
|
|
35157
35240
|
}
|
|
35158
35241
|
}
|
|
35159
35242
|
createInitialValidationJson(sandboxDir, sandboxId, workflowId);
|
|
@@ -35326,7 +35409,7 @@ function ensureWorkspace3(mock) {
|
|
|
35326
35409
|
const workspace = getWorkspacePath2();
|
|
35327
35410
|
if (!existsSync4(workspace)) {
|
|
35328
35411
|
if (mock) {
|
|
35329
|
-
mkdirSync3(
|
|
35412
|
+
mkdirSync3(join4(workspace, "sandbox"), { recursive: true });
|
|
35330
35413
|
} else {
|
|
35331
35414
|
console.error("Workspace not initialized. Run: looplia init");
|
|
35332
35415
|
process.exit(1);
|
|
@@ -35338,7 +35421,7 @@ function buildRunPrompt(workflowId, sandboxId) {
|
|
|
35338
35421
|
return `${RUN_COMMAND} ${workflowId} --sandbox-id ${sandboxId}`;
|
|
35339
35422
|
}
|
|
35340
35423
|
function parseWorkflowFile(workspace, workflowId) {
|
|
35341
|
-
const workflowPath =
|
|
35424
|
+
const workflowPath = join4(workspace, "workflows", `${workflowId}.md`);
|
|
35342
35425
|
if (!existsSync4(workflowPath)) {
|
|
35343
35426
|
return null;
|
|
35344
35427
|
}
|
|
@@ -35366,7 +35449,10 @@ function executeMock2(args) {
|
|
|
35366
35449
|
}
|
|
35367
35450
|
async function executeStreaming(prompt, workspace, workflowId, requiredSkills) {
|
|
35368
35451
|
const contentId = crypto.randomUUID();
|
|
35369
|
-
const executor = createClaudeAgentExecutor({
|
|
35452
|
+
const executor = createClaudeAgentExecutor({
|
|
35453
|
+
workspace,
|
|
35454
|
+
runHooks: createWorkflowHooks()
|
|
35455
|
+
});
|
|
35370
35456
|
const generator = executor.executePromptStreaming(prompt, {
|
|
35371
35457
|
workspace,
|
|
35372
35458
|
contentId,
|
|
@@ -35394,14 +35480,21 @@ async function executeStreaming(prompt, workspace, workflowId, requiredSkills) {
|
|
|
35394
35480
|
async function executeBatch2(prompt, workspace, workflowId, requiredSkills) {
|
|
35395
35481
|
console.error("\u23F3 Processing...");
|
|
35396
35482
|
const contentId = crypto.randomUUID();
|
|
35397
|
-
const executor = createClaudeAgentExecutor({
|
|
35483
|
+
const executor = createClaudeAgentExecutor({
|
|
35484
|
+
workspace,
|
|
35485
|
+
runHooks: createWorkflowHooks()
|
|
35486
|
+
});
|
|
35398
35487
|
const result = await executor.executePrompt(prompt, {
|
|
35399
35488
|
workspace,
|
|
35400
35489
|
contentId,
|
|
35401
35490
|
requiredSkills
|
|
35402
35491
|
});
|
|
35403
|
-
if (result.success
|
|
35404
|
-
return result.data
|
|
35492
|
+
if (result.success) {
|
|
35493
|
+
return result.data ?? {
|
|
35494
|
+
status: "success",
|
|
35495
|
+
workflowId,
|
|
35496
|
+
sessionId: result.sessionId
|
|
35497
|
+
};
|
|
35405
35498
|
}
|
|
35406
35499
|
return {
|
|
35407
35500
|
status: "error",
|
|
@@ -35411,7 +35504,7 @@ async function executeBatch2(prompt, workspace, workflowId, requiredSkills) {
|
|
|
35411
35504
|
}
|
|
35412
35505
|
function resolveSandboxId(workspace, parsed, allowInputless) {
|
|
35413
35506
|
if (parsed.sandboxId) {
|
|
35414
|
-
const sandboxDir =
|
|
35507
|
+
const sandboxDir = join4(workspace, "sandbox", parsed.sandboxId);
|
|
35415
35508
|
if (!existsSync4(sandboxDir)) {
|
|
35416
35509
|
console.error(`Error: Sandbox not found: ${parsed.sandboxId}`);
|
|
35417
35510
|
console.error(`Path: ${sandboxDir}`);
|
|
@@ -35508,6 +35601,27 @@ async function handleJitInstallation(workflowInfo) {
|
|
|
35508
35601
|
return true;
|
|
35509
35602
|
}
|
|
35510
35603
|
}
|
|
35604
|
+
function populateValidationManifest(workspace, sandboxId, workflowId, workflowInfo) {
|
|
35605
|
+
if (!workflowInfo?.parsed?.definition) {
|
|
35606
|
+
return;
|
|
35607
|
+
}
|
|
35608
|
+
const manifest = generateValidationManifest(workflowInfo.parsed.definition);
|
|
35609
|
+
const finalStepId = getFinalStep(workflowInfo.parsed.definition);
|
|
35610
|
+
const sandboxDir = join4(workspace, "sandbox", sandboxId);
|
|
35611
|
+
const validationPath = join4(sandboxDir, "validation.json");
|
|
35612
|
+
if (!existsSync4(validationPath)) {
|
|
35613
|
+
createInitialValidationJson(sandboxDir, sandboxId, workflowId);
|
|
35614
|
+
}
|
|
35615
|
+
if (!existsSync4(validationPath)) {
|
|
35616
|
+
return;
|
|
35617
|
+
}
|
|
35618
|
+
const existing = JSON.parse(
|
|
35619
|
+
readFileSync2(validationPath, "utf-8")
|
|
35620
|
+
);
|
|
35621
|
+
existing.steps = manifest.steps;
|
|
35622
|
+
existing.finalStepId = finalStepId;
|
|
35623
|
+
writeFileSync3(validationPath, JSON.stringify(existing, null, 2), "utf-8");
|
|
35624
|
+
}
|
|
35511
35625
|
async function runRunCommand(args) {
|
|
35512
35626
|
const parsed = parseArgs3(args);
|
|
35513
35627
|
if (parsed.help) {
|
|
@@ -35524,6 +35638,14 @@ async function runRunCommand(args) {
|
|
|
35524
35638
|
const workflowInfo = parseWorkflowFile(workspace, parsed.workflowId);
|
|
35525
35639
|
const allowInputless = workflowInfo?.isInputless ?? false;
|
|
35526
35640
|
const sandboxId = resolveSandboxId(workspace, parsed, allowInputless);
|
|
35641
|
+
process.env.LOOPLIA_SANDBOX_ID = sandboxId;
|
|
35642
|
+
process.env.LOOPLIA_SANDBOX_ROOT = join4(workspace, "sandbox");
|
|
35643
|
+
populateValidationManifest(
|
|
35644
|
+
workspace,
|
|
35645
|
+
sandboxId,
|
|
35646
|
+
parsed.workflowId,
|
|
35647
|
+
workflowInfo
|
|
35648
|
+
);
|
|
35527
35649
|
if (!(parsed.mock || await handleJitInstallation(workflowInfo))) {
|
|
35528
35650
|
process.exit(1);
|
|
35529
35651
|
}
|
|
@@ -35622,7 +35744,7 @@ async function skillAdd(nameOrUrl, from) {
|
|
|
35622
35744
|
}
|
|
35623
35745
|
if (GITHUB_URL_PATTERN.test(nameOrUrl)) {
|
|
35624
35746
|
console.log(`Installing skill from URL: ${nameOrUrl}...`);
|
|
35625
|
-
const { installSkillFromUrl } = await import("./dist-
|
|
35747
|
+
const { installSkillFromUrl } = await import("./dist-3XSIQAV3.js");
|
|
35626
35748
|
const result2 = await installSkillFromUrl(nameOrUrl, true);
|
|
35627
35749
|
switch (result2.status) {
|
|
35628
35750
|
case "installed":
|
|
@@ -35859,7 +35981,7 @@ async function runSkillCommand(args) {
|
|
|
35859
35981
|
}
|
|
35860
35982
|
|
|
35861
35983
|
// src/index.ts
|
|
35862
|
-
var VERSION = "0.7.
|
|
35984
|
+
var VERSION = "0.7.5";
|
|
35863
35985
|
function printHelp5() {
|
|
35864
35986
|
console.log(`
|
|
35865
35987
|
looplia - Content intelligence CLI (v${VERSION})
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
loadCompiledRegistry,
|
|
12
12
|
removeSkill,
|
|
13
13
|
updateSkill
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-4TKNQ5RW.js";
|
|
15
15
|
import {
|
|
16
16
|
syncRegistrySources,
|
|
17
17
|
syncSource
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
CORE_SKILLS,
|
|
33
33
|
ensureWorkspace,
|
|
34
34
|
isCoreSkill
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-GIZRTNY3.js";
|
|
36
36
|
import "./chunk-VRBGWKZ6.js";
|
|
37
37
|
import "./chunk-Y55L47HC.js";
|
|
38
38
|
export {
|
package/package.json
CHANGED
|
@@ -26,6 +26,29 @@ Use this skill when:
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
+
## ⚠️ CRITICAL EXECUTION MODEL - READ FIRST
|
|
30
|
+
|
|
31
|
+
**YOU (the model reading this skill) must execute the step loop directly. DO NOT delegate.**
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
35
|
+
│ YOU (main agent) iterate through steps, making ONE Task call each │
|
|
36
|
+
│ │
|
|
37
|
+
│ FOR step IN workflow.steps: │
|
|
38
|
+
│ 1. Call Task(general-purpose) for THIS STEP ONLY │
|
|
39
|
+
│ 2. WAIT for Task to complete │
|
|
40
|
+
│ 3. Validate output │
|
|
41
|
+
│ 4. THEN move to next step │
|
|
42
|
+
│ │
|
|
43
|
+
│ ❌ WRONG: Task("Execute all workflow steps...") │
|
|
44
|
+
│ ✅ RIGHT: Task("Execute step: summary"), Task("Execute step: ideas")│
|
|
45
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**3 steps = 3 Task calls. You MUST make 3 separate Task tool invocations.**
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
29
52
|
## CRITICAL: Task Invocation with general-purpose Subagent
|
|
30
53
|
|
|
31
54
|
**v0.6.9:** Using built-in `general-purpose` subagent for ALL workflow steps (all providers).
|
|
@@ -76,25 +99,37 @@ Each `Task(general-purpose)` creates a **separate context window**:
|
|
|
76
99
|
|
|
77
100
|
**NEVER batch multiple steps** - this defeats context isolation.
|
|
78
101
|
|
|
79
|
-
### Anti-Patterns
|
|
102
|
+
### Anti-Patterns (VIOLATIONS = TEST FAILURE)
|
|
80
103
|
|
|
81
|
-
❌ **
|
|
104
|
+
❌ **FATAL ERROR - Delegating entire workflow to one Task:**
|
|
82
105
|
```json
|
|
83
106
|
{
|
|
84
107
|
"description": "Execute workflow: writing-kit",
|
|
85
108
|
"prompt": "Run all workflow steps..."
|
|
86
109
|
}
|
|
87
110
|
```
|
|
88
|
-
This
|
|
111
|
+
**This is WRONG.** You made 1 Task call. Tests expect 3. TEST WILL FAIL.
|
|
89
112
|
|
|
90
|
-
|
|
91
|
-
```json
|
|
92
|
-
{
|
|
93
|
-
"description": "Execute step: summary",
|
|
94
|
-
"prompt": "Execute skill 'media-reviewer' for step 'summary'..."
|
|
95
|
-
}
|
|
113
|
+
❌ **FATAL ERROR - Executing skills inline without Task:**
|
|
96
114
|
```
|
|
97
|
-
|
|
115
|
+
Skill("media-reviewer") // NO! You must use Task wrapper
|
|
116
|
+
Skill("idea-synthesis") // NO! You must use Task wrapper
|
|
117
|
+
```
|
|
118
|
+
**This is WRONG.** Each step MUST be wrapped in a Task call.
|
|
119
|
+
|
|
120
|
+
✅ **CORRECT - One Task call per step (3 steps = 3 Task calls):**
|
|
121
|
+
```
|
|
122
|
+
Task("Execute step: summary") // Task #1
|
|
123
|
+
→ Subagent invokes Skill("media-reviewer")
|
|
124
|
+
|
|
125
|
+
Task("Execute step: ideas") // Task #2
|
|
126
|
+
→ Subagent invokes Skill("idea-synthesis")
|
|
127
|
+
|
|
128
|
+
Task("Execute step: writing-kit") // Task #3
|
|
129
|
+
→ Subagent invokes Skill("writing-kit-assembler")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Verification**: Count your Task tool calls. If workflow has 3 steps, you MUST have 3 Task calls.
|
|
98
133
|
|
|
99
134
|
---
|
|
100
135
|
|
|
@@ -243,18 +278,38 @@ Input:
|
|
|
243
278
|
Computed order: [analyze-content, generate-ideas, build-writing-kit]
|
|
244
279
|
```
|
|
245
280
|
|
|
246
|
-
### Phase 5: Step Execution Loop
|
|
281
|
+
### Phase 5: Step Execution Loop (YOU MUST DO THIS)
|
|
282
|
+
|
|
283
|
+
**YOU execute this loop. DO NOT delegate the loop to a subagent.**
|
|
247
284
|
|
|
248
|
-
|
|
285
|
+
```
|
|
286
|
+
YOU (main agent) must:
|
|
287
|
+
┌────────────────────────────────────────────────────────────────┐
|
|
288
|
+
│ for (const step of steps) { │
|
|
289
|
+
│ // 1. YOU call Task tool │
|
|
290
|
+
│ await Task({ │
|
|
291
|
+
│ subagent_type: "general-purpose", │
|
|
292
|
+
│ description: `Execute step: ${step.id}`, │
|
|
293
|
+
│ prompt: `Execute skill '${step.skill}' for step...` │
|
|
294
|
+
│ }); │
|
|
295
|
+
│ │
|
|
296
|
+
│ // 2. YOU wait for Task to complete │
|
|
297
|
+
│ // 3. YOU validate output │
|
|
298
|
+
│ // 4. YOU update validation.json │
|
|
299
|
+
│ // 5. YOU move to next step │
|
|
300
|
+
│ } │
|
|
301
|
+
└────────────────────────────────────────────────────────────────┘
|
|
302
|
+
```
|
|
249
303
|
|
|
304
|
+
**Execution checklist:**
|
|
250
305
|
1. Get first unvalidated step from dependency order
|
|
251
|
-
2.
|
|
252
|
-
3. WAIT for Task completion before proceeding
|
|
253
|
-
4.
|
|
254
|
-
5. REPEAT for next unvalidated step
|
|
255
|
-
6. STOP when ALL steps are validated
|
|
306
|
+
2. **YOU** make ONE `Task(general-purpose)` call for THIS step only
|
|
307
|
+
3. **YOU** WAIT for Task completion before proceeding
|
|
308
|
+
4. **YOU** validate output, update validation.json
|
|
309
|
+
5. **YOU** REPEAT for next unvalidated step
|
|
310
|
+
6. **YOU** STOP when ALL steps are validated
|
|
256
311
|
|
|
257
|
-
**MANDATORY:**
|
|
312
|
+
**MANDATORY:** 3 steps = 3 Task calls. Count them. If you made fewer, you did it wrong.
|
|
258
313
|
|
|
259
314
|
```
|
|
260
315
|
FOR EACH step in dependency order:
|
|
@@ -39,9 +39,7 @@ steps:
|
|
|
39
39
|
Include meta information (difficulty, time to write, audience).
|
|
40
40
|
Calculate relevance scores based on user profile.
|
|
41
41
|
needs: [summary, ideas]
|
|
42
|
-
input:
|
|
43
|
-
- ${{ steps.summary.output }}
|
|
44
|
-
- ${{ steps.ideas.output }}
|
|
42
|
+
input: ["${{ steps.summary.output }}", "${{ steps.ideas.output }}"]
|
|
45
43
|
output: ${{ sandbox }}/outputs/writing-kit.json
|
|
46
44
|
final: true
|
|
47
45
|
validate:
|