@looplia/looplia-cli 0.6.8 → 0.6.10
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/cli.js
CHANGED
|
@@ -243,11 +243,22 @@ async function getPluginPaths() {
|
|
|
243
243
|
return await getProdPluginPaths();
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
// ../../packages/provider/dist/chunk-
|
|
246
|
+
// ../../packages/provider/dist/chunk-L5AQO6ZO.js
|
|
247
247
|
import { execSync } from "child_process";
|
|
248
248
|
import { existsSync as existsSync3 } from "fs";
|
|
249
|
+
import { createRequire } from "module";
|
|
249
250
|
import { homedir as homedir3 } from "os";
|
|
250
|
-
import { join as join4 } from "path";
|
|
251
|
+
import { dirname as dirname3, join as join4 } from "path";
|
|
252
|
+
import {
|
|
253
|
+
chmod,
|
|
254
|
+
mkdir as mkdir2,
|
|
255
|
+
readFile as readFile2,
|
|
256
|
+
rename,
|
|
257
|
+
rm as rm2,
|
|
258
|
+
writeFile as writeFile2
|
|
259
|
+
} from "fs/promises";
|
|
260
|
+
import { homedir as homedir22 } from "os";
|
|
261
|
+
import { join as join23 } from "path";
|
|
251
262
|
|
|
252
263
|
// ../../node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
253
264
|
var ignoreOverride = /* @__PURE__ */ Symbol("Let zodToJsonSchema decide on which parser to use");
|
|
@@ -5574,7 +5585,7 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
5574
5585
|
return combined;
|
|
5575
5586
|
};
|
|
5576
5587
|
|
|
5577
|
-
// ../../node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
|
|
5588
|
+
// ../../packages/provider/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
|
|
5578
5589
|
import { join as join5 } from "path";
|
|
5579
5590
|
import { fileURLToPath as fileURLToPath23 } from "url";
|
|
5580
5591
|
import { setMaxListeners } from "events";
|
|
@@ -27369,22 +27380,28 @@ function query({
|
|
|
27369
27380
|
return queryInstance;
|
|
27370
27381
|
}
|
|
27371
27382
|
|
|
27372
|
-
// ../../packages/provider/dist/chunk-
|
|
27383
|
+
// ../../packages/provider/dist/chunk-L5AQO6ZO.js
|
|
27373
27384
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
27374
|
-
import { join as join23 } from "path";
|
|
27375
|
-
import {
|
|
27376
|
-
chmod,
|
|
27377
|
-
mkdir as mkdir2,
|
|
27378
|
-
readFile as readFile2,
|
|
27379
|
-
rename,
|
|
27380
|
-
rm as rm2,
|
|
27381
|
-
writeFile as writeFile2
|
|
27382
|
-
} from "fs/promises";
|
|
27383
|
-
import { homedir as homedir22 } from "os";
|
|
27384
27385
|
import { join as join32 } from "path";
|
|
27385
27386
|
import { cp as cp2, mkdir as mkdir22, readFile as readFile22, rm as rm22, stat as stat2, writeFile as writeFile22 } from "fs/promises";
|
|
27386
27387
|
import { homedir as homedir32 } from "os";
|
|
27387
27388
|
import { isAbsolute, join as join42, normalize, resolve } from "path";
|
|
27389
|
+
var LINE_SPLIT_REGEX = /\r?\n/;
|
|
27390
|
+
function findSdkBundledCliPath() {
|
|
27391
|
+
try {
|
|
27392
|
+
const require2 = createRequire(import.meta.url);
|
|
27393
|
+
const sdkPackagePath = require2.resolve(
|
|
27394
|
+
"@anthropic-ai/claude-agent-sdk/package.json"
|
|
27395
|
+
);
|
|
27396
|
+
const sdkDir = dirname3(sdkPackagePath);
|
|
27397
|
+
const cliPath = join4(sdkDir, "cli.js");
|
|
27398
|
+
if (existsSync3(cliPath)) {
|
|
27399
|
+
return cliPath;
|
|
27400
|
+
}
|
|
27401
|
+
} catch {
|
|
27402
|
+
}
|
|
27403
|
+
return;
|
|
27404
|
+
}
|
|
27388
27405
|
var CLAUDE_CODE_PATHS = [
|
|
27389
27406
|
// User's local bin (npm global install location)
|
|
27390
27407
|
join4(homedir3(), ".local", "bin", "claude"),
|
|
@@ -27395,92 +27412,42 @@ var CLAUDE_CODE_PATHS = [
|
|
|
27395
27412
|
// Windows (if applicable)
|
|
27396
27413
|
join4(homedir3(), "AppData", "Local", "Programs", "claude", "claude.exe")
|
|
27397
27414
|
];
|
|
27415
|
+
var cachedClaudeCodePath;
|
|
27398
27416
|
function findClaudeCodePath() {
|
|
27417
|
+
if (cachedClaudeCodePath !== void 0) {
|
|
27418
|
+
return cachedClaudeCodePath ?? void 0;
|
|
27419
|
+
}
|
|
27399
27420
|
const envPath = process.env.CLAUDE_CODE_PATH;
|
|
27400
27421
|
if (envPath && existsSync3(envPath)) {
|
|
27401
|
-
|
|
27422
|
+
cachedClaudeCodePath = envPath;
|
|
27423
|
+
return cachedClaudeCodePath;
|
|
27402
27424
|
}
|
|
27403
27425
|
for (const path3 of CLAUDE_CODE_PATHS) {
|
|
27404
27426
|
if (existsSync3(path3)) {
|
|
27405
|
-
|
|
27427
|
+
cachedClaudeCodePath = path3;
|
|
27428
|
+
return cachedClaudeCodePath;
|
|
27406
27429
|
}
|
|
27407
27430
|
}
|
|
27408
27431
|
try {
|
|
27409
|
-
const
|
|
27432
|
+
const pathLookupCommand = process.platform === "win32" ? "where claude" : "which claude";
|
|
27433
|
+
const rawResult = execSync(pathLookupCommand, {
|
|
27410
27434
|
encoding: "utf-8",
|
|
27411
27435
|
stdio: ["pipe", "pipe", "pipe"]
|
|
27412
27436
|
}).trim();
|
|
27413
|
-
|
|
27414
|
-
|
|
27437
|
+
const firstResult = rawResult.split(LINE_SPLIT_REGEX).find((line) => line.trim().length > 0) ?? "";
|
|
27438
|
+
if (firstResult && existsSync3(firstResult)) {
|
|
27439
|
+
cachedClaudeCodePath = firstResult;
|
|
27440
|
+
return cachedClaudeCodePath;
|
|
27415
27441
|
}
|
|
27416
27442
|
} catch {
|
|
27417
27443
|
}
|
|
27418
|
-
|
|
27419
|
-
|
|
27420
|
-
|
|
27421
|
-
|
|
27422
|
-
|
|
27423
|
-
|
|
27424
|
-
|
|
27425
|
-
|
|
27426
|
-
More info: https://docs.anthropic.com/claude-code`
|
|
27427
|
-
);
|
|
27428
|
-
}
|
|
27429
|
-
var DEFAULT_CONFIG = {
|
|
27430
|
-
model: "claude-haiku-4-5-20251001",
|
|
27431
|
-
workspace: "~/.looplia",
|
|
27432
|
-
useFilesystemExtensions: true,
|
|
27433
|
-
maxRetries: 3,
|
|
27434
|
-
timeout: 6e4
|
|
27435
|
-
};
|
|
27436
|
-
function resolveConfig(config2) {
|
|
27437
|
-
return {
|
|
27438
|
-
...config2,
|
|
27439
|
-
model: config2?.model ?? DEFAULT_CONFIG.model,
|
|
27440
|
-
workspace: config2?.workspace ?? DEFAULT_CONFIG.workspace,
|
|
27441
|
-
useFilesystemExtensions: config2?.useFilesystemExtensions ?? DEFAULT_CONFIG.useFilesystemExtensions,
|
|
27442
|
-
maxRetries: config2?.maxRetries ?? DEFAULT_CONFIG.maxRetries,
|
|
27443
|
-
timeout: config2?.timeout ?? DEFAULT_CONFIG.timeout
|
|
27444
|
-
};
|
|
27445
|
-
}
|
|
27446
|
-
function generateLogFilename() {
|
|
27447
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
27448
|
-
return `query-${timestamp}.log`;
|
|
27449
|
-
}
|
|
27450
|
-
function createQueryLogger(workspace) {
|
|
27451
|
-
let logPath = null;
|
|
27452
|
-
return {
|
|
27453
|
-
init(sandboxId) {
|
|
27454
|
-
const logsDir = join23(workspace, "sandbox", sandboxId, "logs");
|
|
27455
|
-
mkdirSync3(logsDir, { recursive: true });
|
|
27456
|
-
const filename = generateLogFilename();
|
|
27457
|
-
logPath = join23(logsDir, filename);
|
|
27458
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
27459
|
-
writeFileSync2(
|
|
27460
|
-
logPath,
|
|
27461
|
-
`Agent SDK Execution Log - ${timestamp}
|
|
27462
|
-
${"=".repeat(60)}
|
|
27463
|
-
|
|
27464
|
-
`
|
|
27465
|
-
);
|
|
27466
|
-
return logPath;
|
|
27467
|
-
},
|
|
27468
|
-
log(message) {
|
|
27469
|
-
if (!logPath) {
|
|
27470
|
-
return;
|
|
27471
|
-
}
|
|
27472
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
27473
|
-
const logEntry = `[${timestamp}] ${JSON.stringify(message, null, 2)}
|
|
27474
|
-
|
|
27475
|
-
`;
|
|
27476
|
-
appendFileSync3(logPath, logEntry);
|
|
27477
|
-
},
|
|
27478
|
-
close() {
|
|
27479
|
-
},
|
|
27480
|
-
getLogPath() {
|
|
27481
|
-
return logPath;
|
|
27482
|
-
}
|
|
27483
|
-
};
|
|
27444
|
+
const sdkCliPath = findSdkBundledCliPath();
|
|
27445
|
+
if (sdkCliPath) {
|
|
27446
|
+
cachedClaudeCodePath = sdkCliPath;
|
|
27447
|
+
return cachedClaudeCodePath;
|
|
27448
|
+
}
|
|
27449
|
+
cachedClaudeCodePath = null;
|
|
27450
|
+
return;
|
|
27484
27451
|
}
|
|
27485
27452
|
var DEFAULT_SETTINGS = {
|
|
27486
27453
|
version: "1.0",
|
|
@@ -27489,7 +27456,7 @@ var DEFAULT_SETTINGS = {
|
|
|
27489
27456
|
},
|
|
27490
27457
|
agents: {
|
|
27491
27458
|
main: "claude-haiku-4-5-20251001",
|
|
27492
|
-
executor: "haiku"
|
|
27459
|
+
executor: "claude-haiku-4-5-20251001"
|
|
27493
27460
|
}
|
|
27494
27461
|
};
|
|
27495
27462
|
var PRESETS = {
|
|
@@ -27498,13 +27465,19 @@ var PRESETS = {
|
|
|
27498
27465
|
name: "Anthropic Claude Haiku",
|
|
27499
27466
|
apiProvider: "anthropic",
|
|
27500
27467
|
mainModel: "claude-haiku-4-5-20251001",
|
|
27501
|
-
executorModel: "haiku"
|
|
27468
|
+
executorModel: "claude-haiku-4-5-20251001",
|
|
27469
|
+
haikuModel: "claude-haiku-4-5-20251001",
|
|
27470
|
+
sonnetModel: "claude-haiku-4-5-20251001",
|
|
27471
|
+
opusModel: "claude-haiku-4-5-20251001"
|
|
27502
27472
|
},
|
|
27503
27473
|
ANTHROPIC_CLAUDE_SONNET: {
|
|
27504
27474
|
name: "Anthropic Claude Sonnet",
|
|
27505
27475
|
apiProvider: "anthropic",
|
|
27506
27476
|
mainModel: "claude-sonnet-4-5-20250514",
|
|
27507
|
-
executorModel: "
|
|
27477
|
+
executorModel: "claude-sonnet-4-5-20250514",
|
|
27478
|
+
haikuModel: "claude-sonnet-4-5-20250514",
|
|
27479
|
+
sonnetModel: "claude-sonnet-4-5-20250514",
|
|
27480
|
+
opusModel: "claude-sonnet-4-5-20250514"
|
|
27508
27481
|
},
|
|
27509
27482
|
// ZenMux Presets
|
|
27510
27483
|
ZENMUX_ANTHROPIC_HAIKU45: {
|
|
@@ -27512,106 +27485,148 @@ var PRESETS = {
|
|
|
27512
27485
|
apiProvider: "zenmux",
|
|
27513
27486
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27514
27487
|
mainModel: "anthropic/claude-haiku-4.5",
|
|
27515
|
-
executorModel: "anthropic/claude-haiku-4.5"
|
|
27488
|
+
executorModel: "anthropic/claude-haiku-4.5",
|
|
27489
|
+
haikuModel: "anthropic/claude-haiku-4.5",
|
|
27490
|
+
sonnetModel: "anthropic/claude-haiku-4.5",
|
|
27491
|
+
opusModel: "anthropic/claude-haiku-4.5"
|
|
27516
27492
|
},
|
|
27517
27493
|
ZENMUX_ZAI_GLM47: {
|
|
27518
27494
|
name: "ZenMux GLM-4.7",
|
|
27519
27495
|
apiProvider: "zenmux",
|
|
27520
27496
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27521
27497
|
mainModel: "z-ai/glm-4.7",
|
|
27522
|
-
executorModel: "z-ai/glm-4.7"
|
|
27498
|
+
executorModel: "z-ai/glm-4.7",
|
|
27499
|
+
haikuModel: "z-ai/glm-4.7",
|
|
27500
|
+
sonnetModel: "z-ai/glm-4.7",
|
|
27501
|
+
opusModel: "z-ai/glm-4.7"
|
|
27523
27502
|
},
|
|
27524
27503
|
ZENMUX_MINIMAX_M21: {
|
|
27525
27504
|
name: "ZenMux MiniMax-M2.1",
|
|
27526
27505
|
apiProvider: "zenmux",
|
|
27527
27506
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27528
27507
|
mainModel: "minimax/minimax-m2.1",
|
|
27529
|
-
executorModel: "minimax/minimax-m2.1"
|
|
27508
|
+
executorModel: "minimax/minimax-m2.1",
|
|
27509
|
+
haikuModel: "minimax/minimax-m2.1",
|
|
27510
|
+
sonnetModel: "minimax/minimax-m2.1",
|
|
27511
|
+
opusModel: "minimax/minimax-m2.1"
|
|
27530
27512
|
},
|
|
27531
27513
|
ZENMUX_GOOGLE_GEMINI3FLASH: {
|
|
27532
27514
|
name: "ZenMux Gemini-3-Flash",
|
|
27533
27515
|
apiProvider: "zenmux",
|
|
27534
27516
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27535
27517
|
mainModel: "google/gemini-3-flash-preview",
|
|
27536
|
-
executorModel: "google/gemini-3-flash-preview"
|
|
27518
|
+
executorModel: "google/gemini-3-flash-preview",
|
|
27519
|
+
haikuModel: "google/gemini-3-flash-preview",
|
|
27520
|
+
sonnetModel: "google/gemini-3-flash-preview",
|
|
27521
|
+
opusModel: "google/gemini-3-flash-preview"
|
|
27537
27522
|
},
|
|
27538
27523
|
ZENMUX_GOOGLE_GEMINI3FLASH_FREE: {
|
|
27539
27524
|
name: "ZenMux Gemini-3-Flash (Free)",
|
|
27540
27525
|
apiProvider: "zenmux",
|
|
27541
27526
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27542
27527
|
mainModel: "google/gemini-3-flash-preview-free",
|
|
27543
|
-
executorModel: "google/gemini-3-flash-preview-free"
|
|
27528
|
+
executorModel: "google/gemini-3-flash-preview-free",
|
|
27529
|
+
haikuModel: "google/gemini-3-flash-preview-free",
|
|
27530
|
+
sonnetModel: "google/gemini-3-flash-preview-free",
|
|
27531
|
+
opusModel: "google/gemini-3-flash-preview-free"
|
|
27544
27532
|
},
|
|
27545
27533
|
ZENMUX_XIAOMI_MIMOV2FLASH: {
|
|
27546
27534
|
name: "ZenMux MiMo-v2-Flash",
|
|
27547
27535
|
apiProvider: "zenmux",
|
|
27548
27536
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27549
27537
|
mainModel: "xiaomi/mimo-v2-flash",
|
|
27550
|
-
executorModel: "xiaomi/mimo-v2-flash"
|
|
27538
|
+
executorModel: "xiaomi/mimo-v2-flash",
|
|
27539
|
+
haikuModel: "xiaomi/mimo-v2-flash",
|
|
27540
|
+
sonnetModel: "xiaomi/mimo-v2-flash",
|
|
27541
|
+
opusModel: "xiaomi/mimo-v2-flash"
|
|
27551
27542
|
},
|
|
27552
27543
|
ZENMUX_XAI_GROK41FAST: {
|
|
27553
27544
|
name: "ZenMux Grok-4.1-Fast",
|
|
27554
27545
|
apiProvider: "zenmux",
|
|
27555
27546
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27556
27547
|
mainModel: "x-ai/grok-4.1-fast",
|
|
27557
|
-
executorModel: "x-ai/grok-4.1-fast"
|
|
27548
|
+
executorModel: "x-ai/grok-4.1-fast",
|
|
27549
|
+
haikuModel: "x-ai/grok-4.1-fast",
|
|
27550
|
+
sonnetModel: "x-ai/grok-4.1-fast",
|
|
27551
|
+
opusModel: "x-ai/grok-4.1-fast"
|
|
27558
27552
|
},
|
|
27559
27553
|
ZENMUX_DEEPSEEK_V32: {
|
|
27560
27554
|
name: "ZenMux DeepSeek-v3.2",
|
|
27561
27555
|
apiProvider: "zenmux",
|
|
27562
27556
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27563
27557
|
mainModel: "deepseek/deepseek-v3.2",
|
|
27564
|
-
executorModel: "deepseek/deepseek-v3.2"
|
|
27558
|
+
executorModel: "deepseek/deepseek-v3.2",
|
|
27559
|
+
haikuModel: "deepseek/deepseek-v3.2",
|
|
27560
|
+
sonnetModel: "deepseek/deepseek-v3.2",
|
|
27561
|
+
opusModel: "deepseek/deepseek-v3.2"
|
|
27565
27562
|
},
|
|
27566
27563
|
ZENMUX_DEEPSEEK_REASONER: {
|
|
27567
27564
|
name: "ZenMux DeepSeek-Reasoner",
|
|
27568
27565
|
apiProvider: "zenmux",
|
|
27569
27566
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27570
27567
|
mainModel: "deepseek/deepseek-reasoner",
|
|
27571
|
-
executorModel: "deepseek/deepseek-reasoner"
|
|
27568
|
+
executorModel: "deepseek/deepseek-reasoner",
|
|
27569
|
+
haikuModel: "deepseek/deepseek-reasoner",
|
|
27570
|
+
sonnetModel: "deepseek/deepseek-reasoner",
|
|
27571
|
+
opusModel: "deepseek/deepseek-reasoner"
|
|
27572
27572
|
},
|
|
27573
27573
|
ZENMUX_VOLCENGINE_DOUBAO_SEED: {
|
|
27574
27574
|
name: "ZenMux Doubao-Seed-1.8",
|
|
27575
27575
|
apiProvider: "zenmux",
|
|
27576
27576
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27577
27577
|
mainModel: "volcengine/doubao-seed-1.8",
|
|
27578
|
-
executorModel: "volcengine/doubao-seed-1.8"
|
|
27578
|
+
executorModel: "volcengine/doubao-seed-1.8",
|
|
27579
|
+
haikuModel: "volcengine/doubao-seed-1.8",
|
|
27580
|
+
sonnetModel: "volcengine/doubao-seed-1.8",
|
|
27581
|
+
opusModel: "volcengine/doubao-seed-1.8"
|
|
27579
27582
|
},
|
|
27580
27583
|
ZENMUX_MISTRAL_LARGE2512: {
|
|
27581
27584
|
name: "ZenMux Mistral-Large-2512",
|
|
27582
27585
|
apiProvider: "zenmux",
|
|
27583
27586
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27584
27587
|
mainModel: "mistralai/mistral-large-2512",
|
|
27585
|
-
executorModel: "mistralai/mistral-large-2512"
|
|
27588
|
+
executorModel: "mistralai/mistral-large-2512",
|
|
27589
|
+
haikuModel: "mistralai/mistral-large-2512",
|
|
27590
|
+
sonnetModel: "mistralai/mistral-large-2512",
|
|
27591
|
+
opusModel: "mistralai/mistral-large-2512"
|
|
27586
27592
|
},
|
|
27587
27593
|
ZENMUX_ZAI_GLM46VFLASH: {
|
|
27588
27594
|
name: "ZenMux GLM-4.6v-Flash",
|
|
27589
27595
|
apiProvider: "zenmux",
|
|
27590
27596
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27591
27597
|
mainModel: "z-ai/glm-4.6v-flash",
|
|
27592
|
-
executorModel: "z-ai/glm-4.6v-flash"
|
|
27598
|
+
executorModel: "z-ai/glm-4.6v-flash",
|
|
27599
|
+
haikuModel: "z-ai/glm-4.6v-flash",
|
|
27600
|
+
sonnetModel: "z-ai/glm-4.6v-flash",
|
|
27601
|
+
opusModel: "z-ai/glm-4.6v-flash"
|
|
27593
27602
|
},
|
|
27594
27603
|
ZENMUX_ZAI_GLM46V: {
|
|
27595
27604
|
name: "ZenMux GLM-4.6v",
|
|
27596
27605
|
apiProvider: "zenmux",
|
|
27597
27606
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27598
27607
|
mainModel: "z-ai/glm-4.6v",
|
|
27599
|
-
executorModel: "z-ai/glm-4.6v"
|
|
27608
|
+
executorModel: "z-ai/glm-4.6v",
|
|
27609
|
+
haikuModel: "z-ai/glm-4.6v",
|
|
27610
|
+
sonnetModel: "z-ai/glm-4.6v",
|
|
27611
|
+
opusModel: "z-ai/glm-4.6v"
|
|
27600
27612
|
},
|
|
27601
27613
|
ZENMUX_OPENAI_GPT51CODEXMINI: {
|
|
27602
27614
|
name: "ZenMux GPT-5.1 Codex Mini",
|
|
27603
27615
|
apiProvider: "zenmux",
|
|
27604
27616
|
baseUrl: "https://zenmux.ai/api/anthropic",
|
|
27605
27617
|
mainModel: "openai/gpt-5.1-codex-mini",
|
|
27606
|
-
executorModel: "openai/gpt-5.1-codex-mini"
|
|
27618
|
+
executorModel: "openai/gpt-5.1-codex-mini",
|
|
27619
|
+
haikuModel: "openai/gpt-5.1-codex-mini",
|
|
27620
|
+
sonnetModel: "openai/gpt-5.1-codex-mini",
|
|
27621
|
+
opusModel: "openai/gpt-5.1-codex-mini"
|
|
27607
27622
|
}
|
|
27608
27623
|
};
|
|
27609
27624
|
var CONFIG_FILE = "looplia.setting.json";
|
|
27610
27625
|
function getLoopliaHome() {
|
|
27611
|
-
return
|
|
27626
|
+
return join23(homedir22(), ".looplia");
|
|
27612
27627
|
}
|
|
27613
27628
|
function getConfigPath() {
|
|
27614
|
-
return
|
|
27629
|
+
return join23(getLoopliaHome(), CONFIG_FILE);
|
|
27615
27630
|
}
|
|
27616
27631
|
async function readLoopliaSettings() {
|
|
27617
27632
|
const configPath = getConfigPath();
|
|
@@ -27643,23 +27658,33 @@ async function writeLoopliaSettings(settings) {
|
|
|
27643
27658
|
async function removeLoopliaSettings() {
|
|
27644
27659
|
await rm2(getConfigPath(), { force: true });
|
|
27645
27660
|
}
|
|
27661
|
+
function setEnvIfNotSet(key, value) {
|
|
27662
|
+
if (!process.env[key]) {
|
|
27663
|
+
process.env[key] = value;
|
|
27664
|
+
}
|
|
27665
|
+
}
|
|
27666
|
+
function injectModelTierEnv(mainModel, executorModel) {
|
|
27667
|
+
setEnvIfNotSet("ANTHROPIC_DEFAULT_HAIKU_MODEL", mainModel);
|
|
27668
|
+
setEnvIfNotSet("ANTHROPIC_DEFAULT_SONNET_MODEL", mainModel);
|
|
27669
|
+
setEnvIfNotSet("ANTHROPIC_DEFAULT_OPUS_MODEL", mainModel);
|
|
27670
|
+
setEnvIfNotSet("LOOPLIA_AGENT_MODEL_MAIN", mainModel);
|
|
27671
|
+
setEnvIfNotSet("LOOPLIA_AGENT_MODEL_EXECUTOR", executorModel);
|
|
27672
|
+
}
|
|
27646
27673
|
function injectLoopliaSettingsEnv(settings) {
|
|
27647
27674
|
if (settings.apiProvider.type !== "anthropic") {
|
|
27648
27675
|
if (settings.apiProvider.baseUrl && !process.env.ANTHROPIC_BASE_URL) {
|
|
27649
27676
|
process.env.ANTHROPIC_BASE_URL = settings.apiProvider.baseUrl;
|
|
27650
27677
|
}
|
|
27651
|
-
if (settings.apiProvider.
|
|
27652
|
-
process.env.ANTHROPIC_API_KEY = process.env.ZENMUX_API_KEY;
|
|
27653
|
-
} else if (!process.env.ANTHROPIC_API_KEY && settings.apiProvider.authToken) {
|
|
27678
|
+
if (settings.apiProvider.authToken) {
|
|
27654
27679
|
process.env.ANTHROPIC_API_KEY = settings.apiProvider.authToken;
|
|
27680
|
+
} else {
|
|
27681
|
+
const isZenmuxEndpoint = settings.apiProvider.type === "zenmux" || settings.apiProvider.baseUrl?.includes("zenmux.ai");
|
|
27682
|
+
if (isZenmuxEndpoint && process.env.ZENMUX_API_KEY) {
|
|
27683
|
+
process.env.ANTHROPIC_API_KEY = process.env.ZENMUX_API_KEY;
|
|
27684
|
+
}
|
|
27655
27685
|
}
|
|
27656
27686
|
}
|
|
27657
|
-
|
|
27658
|
-
process.env.LOOPLIA_AGENT_MODEL_MAIN = settings.agents.main;
|
|
27659
|
-
}
|
|
27660
|
-
if (!process.env.LOOPLIA_AGENT_MODEL_EXECUTOR) {
|
|
27661
|
-
process.env.LOOPLIA_AGENT_MODEL_EXECUTOR = settings.agents.executor;
|
|
27662
|
-
}
|
|
27687
|
+
injectModelTierEnv(settings.agents.main, settings.agents.executor);
|
|
27663
27688
|
}
|
|
27664
27689
|
function getSettingsDisplayInfo(settings) {
|
|
27665
27690
|
if (!settings) {
|
|
@@ -27709,6 +27734,87 @@ function applyPreset(presetName, existingSettings) {
|
|
|
27709
27734
|
}
|
|
27710
27735
|
};
|
|
27711
27736
|
}
|
|
27737
|
+
async function initializeCommandEnvironment(options = {}) {
|
|
27738
|
+
const settings = await readLoopliaSettings();
|
|
27739
|
+
if (settings) {
|
|
27740
|
+
injectLoopliaSettingsEnv(settings);
|
|
27741
|
+
}
|
|
27742
|
+
if (!options.mock) {
|
|
27743
|
+
validateApiKeyPresence();
|
|
27744
|
+
}
|
|
27745
|
+
return { settings };
|
|
27746
|
+
}
|
|
27747
|
+
function validateApiKeyPresence() {
|
|
27748
|
+
if (!(process.env.ANTHROPIC_API_KEY || process.env.CLAUDE_CODE_OAUTH_TOKEN)) {
|
|
27749
|
+
console.error("Error: API key required");
|
|
27750
|
+
console.error("");
|
|
27751
|
+
console.error("Options:");
|
|
27752
|
+
console.error(" 1. Set ANTHROPIC_API_KEY environment variable");
|
|
27753
|
+
console.error(" 2. Set ZENMUX_API_KEY with a ZenMux preset");
|
|
27754
|
+
console.error(" 3. Configure via: looplia config provider preset <name>");
|
|
27755
|
+
console.error(" 4. Use --mock flag for testing without API");
|
|
27756
|
+
console.error("");
|
|
27757
|
+
console.error("Get your API key from: https://console.anthropic.com");
|
|
27758
|
+
console.error("Or use ZenMux at: https://zenmux.ai");
|
|
27759
|
+
process.exit(1);
|
|
27760
|
+
}
|
|
27761
|
+
}
|
|
27762
|
+
var DEFAULT_CONFIG = {
|
|
27763
|
+
model: "claude-haiku-4-5-20251001",
|
|
27764
|
+
workspace: "~/.looplia",
|
|
27765
|
+
useFilesystemExtensions: true,
|
|
27766
|
+
maxRetries: 3,
|
|
27767
|
+
timeout: 6e4
|
|
27768
|
+
};
|
|
27769
|
+
function resolveConfig(config2) {
|
|
27770
|
+
return {
|
|
27771
|
+
...config2,
|
|
27772
|
+
model: config2?.model ?? DEFAULT_CONFIG.model,
|
|
27773
|
+
workspace: config2?.workspace ?? DEFAULT_CONFIG.workspace,
|
|
27774
|
+
useFilesystemExtensions: config2?.useFilesystemExtensions ?? DEFAULT_CONFIG.useFilesystemExtensions,
|
|
27775
|
+
maxRetries: config2?.maxRetries ?? DEFAULT_CONFIG.maxRetries,
|
|
27776
|
+
timeout: config2?.timeout ?? DEFAULT_CONFIG.timeout
|
|
27777
|
+
};
|
|
27778
|
+
}
|
|
27779
|
+
function generateLogFilename() {
|
|
27780
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
27781
|
+
return `query-${timestamp}.log`;
|
|
27782
|
+
}
|
|
27783
|
+
function createQueryLogger(workspace) {
|
|
27784
|
+
let logPath = null;
|
|
27785
|
+
return {
|
|
27786
|
+
init(sandboxId) {
|
|
27787
|
+
const logsDir = join32(workspace, "sandbox", sandboxId, "logs");
|
|
27788
|
+
mkdirSync3(logsDir, { recursive: true });
|
|
27789
|
+
const filename = generateLogFilename();
|
|
27790
|
+
logPath = join32(logsDir, filename);
|
|
27791
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
27792
|
+
writeFileSync2(
|
|
27793
|
+
logPath,
|
|
27794
|
+
`Agent SDK Execution Log - ${timestamp}
|
|
27795
|
+
${"=".repeat(60)}
|
|
27796
|
+
|
|
27797
|
+
`
|
|
27798
|
+
);
|
|
27799
|
+
return logPath;
|
|
27800
|
+
},
|
|
27801
|
+
log(message) {
|
|
27802
|
+
if (!logPath) {
|
|
27803
|
+
return;
|
|
27804
|
+
}
|
|
27805
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
27806
|
+
const logEntry = `[${timestamp}] ${JSON.stringify(message, null, 2)}
|
|
27807
|
+
|
|
27808
|
+
`;
|
|
27809
|
+
appendFileSync3(logPath, logEntry);
|
|
27810
|
+
},
|
|
27811
|
+
close() {
|
|
27812
|
+
},
|
|
27813
|
+
getLogPath() {
|
|
27814
|
+
return logPath;
|
|
27815
|
+
}
|
|
27816
|
+
};
|
|
27817
|
+
}
|
|
27712
27818
|
var DEFAULT_RATE_LIMIT_RETRY_MS = 6e4;
|
|
27713
27819
|
function mapException(error2) {
|
|
27714
27820
|
if (error2 instanceof Error) {
|
|
@@ -28495,14 +28601,10 @@ async function initializeAndValidateApiKey(config2) {
|
|
|
28495
28601
|
"API key is required. Set ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN environment variable"
|
|
28496
28602
|
);
|
|
28497
28603
|
}
|
|
28498
|
-
|
|
28499
|
-
return { apiKey, isProxyProvider };
|
|
28604
|
+
return apiKey;
|
|
28500
28605
|
}
|
|
28501
|
-
function
|
|
28502
|
-
return
|
|
28503
|
-
mainModel: process.env.LOOPLIA_AGENT_MODEL_MAIN ?? DEFAULT_SETTINGS.agents.main,
|
|
28504
|
-
executorModel: process.env.LOOPLIA_AGENT_MODEL_EXECUTOR ?? DEFAULT_SETTINGS.agents.executor
|
|
28505
|
-
};
|
|
28606
|
+
function getMainModel() {
|
|
28607
|
+
return process.env.LOOPLIA_AGENT_MODEL_MAIN ?? DEFAULT_SETTINGS.agents.main;
|
|
28506
28608
|
}
|
|
28507
28609
|
function* processEvent(event, progressTracker, context) {
|
|
28508
28610
|
if (event.type === "tool_start" && event.tool === "Skill") {
|
|
@@ -28518,8 +28620,8 @@ function* processEvent(event, progressTracker, context) {
|
|
|
28518
28620
|
}
|
|
28519
28621
|
async function* executeAgenticQueryStreaming(prompt, jsonSchema, config2) {
|
|
28520
28622
|
const resolvedConfig = resolveConfig(config2);
|
|
28521
|
-
|
|
28522
|
-
const
|
|
28623
|
+
await initializeAndValidateApiKey(config2);
|
|
28624
|
+
const mainModel = getMainModel();
|
|
28523
28625
|
try {
|
|
28524
28626
|
const workspace = config2?.workspace ?? await getOrInitWorkspace(
|
|
28525
28627
|
resolvedConfig.workspace,
|
|
@@ -28550,51 +28652,12 @@ async function* executeAgenticQueryStreaming(prompt, jsonSchema, config2) {
|
|
|
28550
28652
|
const pluginPaths = await getPluginPaths();
|
|
28551
28653
|
const userCwd = process.cwd();
|
|
28552
28654
|
const loopliaHome = getLoopliaPluginPath();
|
|
28553
|
-
const workflowExecutionHint = isProxyProvider ? `
|
|
28554
|
-
|
|
28555
|
-
## Workflow Execution Mode: Inline (Proxy Provider)
|
|
28556
|
-
|
|
28557
|
-
When executing looplia workflows (/run commands), use the "workflow-executor-inline" skill.
|
|
28558
|
-
Execute all workflow steps INLINE without spawning Task subagents.
|
|
28559
|
-
This ensures compatibility with your current API provider.` : "";
|
|
28560
|
-
const agents = isProxyProvider ? void 0 : {
|
|
28561
|
-
"skill-executor": {
|
|
28562
|
-
description: "Universal skill orchestrator for looplia workflow steps. Executes a single workflow step by invoking skills.",
|
|
28563
|
-
prompt: `You are the looplia skill-executor. Execute ONE workflow step by invoking the specified skill.
|
|
28564
|
-
|
|
28565
|
-
## Execution Protocol
|
|
28566
|
-
1. Read input files (if provided)
|
|
28567
|
-
2. Invoke the skill using the Skill tool
|
|
28568
|
-
3. Execute the mission with skill context
|
|
28569
|
-
4. Write JSON output to the specified path using Write tool
|
|
28570
|
-
|
|
28571
|
-
## CRITICAL: Output Writing is MANDATORY
|
|
28572
|
-
YOU MUST CALL THE WRITE TOOL before completing. If you don't write the file, the workflow fails.
|
|
28573
|
-
|
|
28574
|
-
## Rules
|
|
28575
|
-
- ALWAYS invoke the specified skill using Skill tool
|
|
28576
|
-
- ALWAYS write output to the exact path using Write tool
|
|
28577
|
-
- NEVER return results as text - always write JSON to output file
|
|
28578
|
-
- NEVER spawn Task subagents - execute skills directly
|
|
28579
|
-
- ALWAYS include contentId in JSON outputs`,
|
|
28580
|
-
tools: [
|
|
28581
|
-
"Read",
|
|
28582
|
-
"Write",
|
|
28583
|
-
"Skill",
|
|
28584
|
-
"Glob",
|
|
28585
|
-
"Grep",
|
|
28586
|
-
"WebSearch",
|
|
28587
|
-
"WebFetch"
|
|
28588
|
-
],
|
|
28589
|
-
model: executorModel
|
|
28590
|
-
}
|
|
28591
|
-
};
|
|
28592
28655
|
const claudeCodePath = findClaudeCodePath();
|
|
28593
28656
|
const result = query({
|
|
28594
28657
|
prompt,
|
|
28595
28658
|
options: {
|
|
28596
|
-
// v0.6.8: Use system-installed Claude Code
|
|
28597
|
-
pathToClaudeCodeExecutable: claudeCodePath,
|
|
28659
|
+
// v0.6.8: Use system-installed Claude Code if available, otherwise SDK uses built-in
|
|
28660
|
+
...claudeCodePath && { pathToClaudeCodeExecutable: claudeCodePath },
|
|
28598
28661
|
// v0.6.6: Use configured main model
|
|
28599
28662
|
model: mainModel,
|
|
28600
28663
|
// v0.6.5: SDK works relative to ~/.looplia (sandbox, workflows, etc.)
|
|
@@ -28604,7 +28667,7 @@ YOU MUST CALL THE WRITE TOOL before completing. If you don't write the file, the
|
|
|
28604
28667
|
// v0.6.5: Load plugins from local paths instead of project settings
|
|
28605
28668
|
plugins: pluginPaths,
|
|
28606
28669
|
// v0.6.5: Append looplia system prompt + user context to claude_code preset
|
|
28607
|
-
// v0.6.
|
|
28670
|
+
// v0.6.9: Removed provider-aware hint - unified subagent strategy for all providers
|
|
28608
28671
|
systemPrompt: {
|
|
28609
28672
|
type: "preset",
|
|
28610
28673
|
preset: "claude_code",
|
|
@@ -28614,7 +28677,7 @@ YOU MUST CALL THE WRITE TOOL before completing. If you don't write the file, the
|
|
|
28614
28677
|
|
|
28615
28678
|
User Working Directory: ${userCwd}
|
|
28616
28679
|
|
|
28617
|
-
When processing --file arguments or user file paths, resolve them against the User Working Directory above
|
|
28680
|
+
When processing --file arguments or user file paths, resolve them against the User Working Directory above.`
|
|
28618
28681
|
},
|
|
28619
28682
|
// v0.6.0: Enable Task for subagent spawning, Write/Glob for file operations
|
|
28620
28683
|
// v0.6.3: Added WebSearch/WebFetch for input-less search skill
|
|
@@ -28627,9 +28690,8 @@ When processing --file arguments or user file paths, resolve them against the Us
|
|
|
28627
28690
|
"WebSearch",
|
|
28628
28691
|
"WebFetch"
|
|
28629
28692
|
],
|
|
28630
|
-
outputFormat: { type: "json_schema", schema: jsonSchema }
|
|
28631
|
-
// v0.6.
|
|
28632
|
-
agents
|
|
28693
|
+
outputFormat: { type: "json_schema", schema: jsonSchema }
|
|
28694
|
+
// v0.6.9: No custom agents - using built-in general-purpose for workflow steps
|
|
28633
28695
|
}
|
|
28634
28696
|
});
|
|
28635
28697
|
let finalResult;
|
|
@@ -31400,19 +31462,6 @@ function ensureWorkspace2(mock) {
|
|
|
31400
31462
|
}
|
|
31401
31463
|
return workspace;
|
|
31402
31464
|
}
|
|
31403
|
-
function validateEnvironment(mock) {
|
|
31404
|
-
if (mock) {
|
|
31405
|
-
return;
|
|
31406
|
-
}
|
|
31407
|
-
if (!(process.env.ANTHROPIC_API_KEY || process.env.CLAUDE_CODE_OAUTH_TOKEN)) {
|
|
31408
|
-
console.error(
|
|
31409
|
-
"Error: ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN required"
|
|
31410
|
-
);
|
|
31411
|
-
console.error("Get your API key from: https://console.anthropic.com");
|
|
31412
|
-
console.error("Or use --mock flag to run without API key");
|
|
31413
|
-
process.exit(1);
|
|
31414
|
-
}
|
|
31415
|
-
}
|
|
31416
31465
|
function buildPrompt(args) {
|
|
31417
31466
|
let prompt = BUILD_COMMAND;
|
|
31418
31467
|
if (args.name) {
|
|
@@ -31603,8 +31652,8 @@ async function runBuildCommand(args) {
|
|
|
31603
31652
|
return;
|
|
31604
31653
|
}
|
|
31605
31654
|
try {
|
|
31606
|
-
validateEnvironment(parsed.mock);
|
|
31607
31655
|
const workspace = ensureWorkspace2(parsed.mock);
|
|
31656
|
+
await initializeCommandEnvironment({ mock: parsed.mock });
|
|
31608
31657
|
const prompt = buildPrompt(parsed);
|
|
31609
31658
|
const result = await executeBuild(prompt, workspace, parsed);
|
|
31610
31659
|
renderResult(result);
|
|
@@ -32614,11 +32663,11 @@ async function runConfigCommand(args) {
|
|
|
32614
32663
|
}
|
|
32615
32664
|
|
|
32616
32665
|
// src/commands/init.ts
|
|
32617
|
-
import { dirname as
|
|
32666
|
+
import { dirname as dirname4, join as join7 } from "path";
|
|
32618
32667
|
import { createInterface as createInterface2 } from "readline";
|
|
32619
32668
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
32620
32669
|
function getCliBundledPluginsPath() {
|
|
32621
|
-
const currentFile = typeof __dirname !== "undefined" ? __dirname :
|
|
32670
|
+
const currentFile = typeof __dirname !== "undefined" ? __dirname : dirname4(fileURLToPath3(import.meta.url));
|
|
32622
32671
|
return join7(currentFile, "..", "plugins");
|
|
32623
32672
|
}
|
|
32624
32673
|
function printInitHelp() {
|
|
@@ -33018,19 +33067,6 @@ function ensureWorkspace3(mock) {
|
|
|
33018
33067
|
}
|
|
33019
33068
|
return workspace;
|
|
33020
33069
|
}
|
|
33021
|
-
function validateEnvironment2(mock) {
|
|
33022
|
-
if (mock) {
|
|
33023
|
-
return;
|
|
33024
|
-
}
|
|
33025
|
-
if (!(process.env.ANTHROPIC_API_KEY || process.env.CLAUDE_CODE_OAUTH_TOKEN)) {
|
|
33026
|
-
console.error(
|
|
33027
|
-
"Error: ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN required"
|
|
33028
|
-
);
|
|
33029
|
-
console.error("Get your API key from: https://console.anthropic.com");
|
|
33030
|
-
console.error("Or use --mock flag to run without API key");
|
|
33031
|
-
process.exit(1);
|
|
33032
|
-
}
|
|
33033
|
-
}
|
|
33034
33070
|
function buildRunPrompt(workflowId, sandboxId) {
|
|
33035
33071
|
return `${RUN_COMMAND} ${workflowId} --sandbox-id ${sandboxId}`;
|
|
33036
33072
|
}
|
|
@@ -33178,11 +33214,7 @@ async function runRunCommand(args) {
|
|
|
33178
33214
|
const workspace = ensureWorkspace3(parsed.mock);
|
|
33179
33215
|
const allowInputless = checkWorkflowInputless(workspace, parsed.workflowId);
|
|
33180
33216
|
const sandboxId = resolveSandboxId(workspace, parsed, allowInputless);
|
|
33181
|
-
|
|
33182
|
-
if (settings) {
|
|
33183
|
-
injectLoopliaSettingsEnv(settings);
|
|
33184
|
-
}
|
|
33185
|
-
validateEnvironment2(parsed.mock);
|
|
33217
|
+
await initializeCommandEnvironment({ mock: parsed.mock });
|
|
33186
33218
|
const prompt = buildRunPrompt(parsed.workflowId, sandboxId);
|
|
33187
33219
|
const result = await executeWorkflow(
|
|
33188
33220
|
prompt,
|
|
@@ -33202,7 +33234,7 @@ async function runRunCommand(args) {
|
|
|
33202
33234
|
}
|
|
33203
33235
|
|
|
33204
33236
|
// src/index.ts
|
|
33205
|
-
var VERSION = "0.6.
|
|
33237
|
+
var VERSION = "0.6.10";
|
|
33206
33238
|
function printHelp3() {
|
|
33207
33239
|
console.log(`
|
|
33208
33240
|
looplia - Content intelligence CLI (v${VERSION})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@looplia/looplia-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.10",
|
|
4
4
|
"description": "Looplia CLI - AI-powered workflow automation tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Elastic-2.0",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "tsup",
|
|
32
32
|
"dev": "tsup --watch",
|
|
33
|
-
"start": "node dist/
|
|
33
|
+
"start": "node dist/cli.js",
|
|
34
34
|
"test": "bun run build && bun test",
|
|
35
35
|
"test:watch": "bun test --watch",
|
|
36
36
|
"test:unit": "bun test commands/",
|
|
@@ -76,6 +76,6 @@ LOCK_FILE="${VALIDATION_JSON}.lock"
|
|
|
76
76
|
# Update validation.json to mark step as validated (v0.6.0 uses "steps")
|
|
77
77
|
jq --arg art "$ARTIFACT" '.steps[$art].validated = true' "$VALIDATION_JSON" > "${VALIDATION_JSON}.tmp"
|
|
78
78
|
mv "${VALIDATION_JSON}.tmp" "$VALIDATION_JSON"
|
|
79
|
-
echo "✓ Validated: $ARTIFACT.json"
|
|
79
|
+
echo "✓ Validated: $ARTIFACT.json" >&2
|
|
80
80
|
|
|
81
81
|
) 200>"$LOCK_FILE"
|
|
@@ -6,14 +6,14 @@ description: |
|
|
|
6
6
|
"execute this looplia pipeline", "/run writing-kit", "start the looplia automation", or
|
|
7
7
|
"process these workflow steps".
|
|
8
8
|
|
|
9
|
-
Architecture: One workflow step triggers one
|
|
10
|
-
invokes
|
|
11
|
-
per-step
|
|
9
|
+
Architecture: One workflow step triggers one general-purpose subagent call, which then
|
|
10
|
+
invokes skills to accomplish the step's mission. Each step = separate context window.
|
|
11
|
+
Handles sandbox management, per-step orchestration, and validation state tracking.
|
|
12
12
|
|
|
13
|
-
v0.6.
|
|
13
|
+
v0.6.9: Unified general-purpose subagent strategy for all providers (context offload).
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
# Workflow Executor Skill (v0.6.
|
|
16
|
+
# Workflow Executor Skill (v0.6.9)
|
|
17
17
|
|
|
18
18
|
Execute looplia workflows defined in `workflows/*.md` files using the skills-first architecture.
|
|
19
19
|
|
|
@@ -26,17 +26,17 @@ Use this skill when:
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
-
## CRITICAL:
|
|
29
|
+
## CRITICAL: Task Invocation with general-purpose Subagent
|
|
30
30
|
|
|
31
|
-
**v0.6.
|
|
31
|
+
**v0.6.9:** Using built-in `general-purpose` subagent for ALL workflow steps (all providers).
|
|
32
32
|
|
|
33
33
|
When executing a step with `skill: {name}` and `mission:`:
|
|
34
34
|
|
|
35
35
|
```json
|
|
36
36
|
{
|
|
37
|
-
"subagent_type": "
|
|
37
|
+
"subagent_type": "general-purpose",
|
|
38
38
|
"description": "Execute step: {step.id}",
|
|
39
|
-
"prompt": "Execute skill '{step.skill}' for step '{step.id}'.\n\
|
|
39
|
+
"prompt": "Execute skill '{step.skill}' for step '{step.id}'.\n\n## Mission\n{step.mission}\n\n## Execution Protocol\n1. Read input files (if provided)\n2. Invoke the skill using Skill tool\n3. Execute the mission with skill context\n4. Write JSON output to the specified path using Write tool\n\n## CRITICAL: Output Writing is MANDATORY\nYOU MUST CALL THE WRITE TOOL before completing. If you don't write the file, the workflow fails.\n\n## Rules\n- ALWAYS invoke the specified skill using Skill tool\n- ALWAYS write output to the exact path using Write tool\n- NEVER return results as text - always write JSON to output file\n- NEVER spawn Task subagents - execute skills directly\n- ALWAYS include contentId in JSON outputs\n\nInput: {resolved input path}\nOutput: {step.output}\nValidation: {step.validate JSON}"
|
|
40
40
|
}
|
|
41
41
|
```
|
|
42
42
|
|
|
@@ -54,23 +54,22 @@ When executing a step with `skill: {name}` and `mission:`:
|
|
|
54
54
|
**Task tool call:**
|
|
55
55
|
```json
|
|
56
56
|
{
|
|
57
|
-
"subagent_type": "
|
|
57
|
+
"subagent_type": "general-purpose",
|
|
58
58
|
"description": "Execute step: analyze-content",
|
|
59
|
-
"prompt": "Execute skill 'media-reviewer' for step 'analyze-content'.\n\
|
|
59
|
+
"prompt": "Execute skill 'media-reviewer' for step 'analyze-content'.\n\n## Mission\nDeep analysis of video transcript. Extract key themes, important quotes, and narrative structure.\n\n## Execution Protocol\n1. Read input files (if provided)\n2. Invoke the skill using Skill tool\n3. Execute the mission with skill context\n4. Write JSON output to the specified path using Write tool\n\n## CRITICAL: Output Writing is MANDATORY\nYOU MUST CALL THE WRITE TOOL before completing. If you don't write the file, the workflow fails.\n\n## Rules\n- ALWAYS invoke the specified skill using Skill tool\n- ALWAYS write output to the exact path using Write tool\n- NEVER return results as text - always write JSON to output file\n- NEVER spawn Task subagents - execute skills directly\n- ALWAYS include contentId in JSON outputs\n\nInput: sandbox/video-2025-01-15-abc123/inputs/content.md\nOutput: sandbox/video-2025-01-15-abc123/outputs/analysis.json\nValidation: {\"required_fields\":[\"contentId\",\"headline\",\"keyThemes\"]}"
|
|
60
60
|
}
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
### Rules
|
|
64
64
|
|
|
65
|
-
- **ALWAYS** use `subagent_type: "
|
|
65
|
+
- **ALWAYS** use `subagent_type: "general-purpose"` for ALL workflow steps
|
|
66
66
|
- **NEVER** use custom subagent_type per step (removed in v0.6.1)
|
|
67
|
-
- **NEVER** use `subagent_type: "general-purpose"` for workflow steps
|
|
68
67
|
- **VALIDATE** that step has both `skill:` and `mission:` fields
|
|
69
68
|
- **REJECT** steps using deprecated `run:` syntax
|
|
70
69
|
|
|
71
70
|
### Why Per-Step Task Calls (Context Isolation)
|
|
72
71
|
|
|
73
|
-
Each `Task(
|
|
72
|
+
Each `Task(general-purpose)` creates a **separate context window**:
|
|
74
73
|
- Isolates step processing from main agent context
|
|
75
74
|
- Prevents context pollution across steps
|
|
76
75
|
- Enables focused execution with only relevant inputs
|
|
@@ -249,7 +248,7 @@ Computed order: [analyze-content, generate-ideas, build-writing-kit]
|
|
|
249
248
|
**Execute steps ONE AT A TIME (context isolation):**
|
|
250
249
|
|
|
251
250
|
1. Get first unvalidated step from dependency order
|
|
252
|
-
2. Make ONE `Task(
|
|
251
|
+
2. Make ONE `Task(general-purpose)` call for THIS step only
|
|
253
252
|
3. WAIT for Task completion before proceeding
|
|
254
253
|
4. Validate output, update validation.json
|
|
255
254
|
5. REPEAT for next unvalidated step
|
|
@@ -271,10 +270,10 @@ FOR EACH step in dependency order:
|
|
|
271
270
|
┌─────────┐ ┌─────────────────────────────┐
|
|
272
271
|
│ SKIP │ │ 1. INVOKE Task tool: │
|
|
273
272
|
│ (done) │ │ subagent_type: │
|
|
274
|
-
└─────────┘ │ "
|
|
273
|
+
└─────────┘ │ "general-purpose" │
|
|
275
274
|
│ │
|
|
276
|
-
│ 2.
|
|
277
|
-
│
|
|
275
|
+
│ 2. Subagent invokes the │
|
|
276
|
+
│ specified skill │
|
|
278
277
|
│ │
|
|
279
278
|
│ 3. VALIDATE output │
|
|
280
279
|
│ │
|
|
@@ -302,9 +301,9 @@ For step:
|
|
|
302
301
|
Invoke Task tool:
|
|
303
302
|
```json
|
|
304
303
|
{
|
|
305
|
-
"subagent_type": "
|
|
304
|
+
"subagent_type": "general-purpose",
|
|
306
305
|
"description": "Execute step: analyze-content",
|
|
307
|
-
"prompt": "Execute skill 'media-reviewer' for step 'analyze-content'.\n\
|
|
306
|
+
"prompt": "Execute skill 'media-reviewer' for step 'analyze-content'.\n\n## Mission\nDeep analysis of video transcript. Extract key themes, important quotes with timestamps, and narrative structure.\n\n## Execution Protocol\n1. Read input files (if provided)\n2. Invoke the skill using Skill tool\n3. Execute the mission with skill context\n4. Write JSON output to the specified path using Write tool\n\n## CRITICAL: Output Writing is MANDATORY\nYOU MUST CALL THE WRITE TOOL before completing.\n\n## Rules\n- ALWAYS invoke the specified skill using Skill tool\n- ALWAYS write output to the exact path using Write tool\n- NEVER return results as text - always write JSON to output file\n- ALWAYS include contentId in JSON outputs\n\nInput: sandbox/article-2025-12-18-xk7m/inputs/content.md\nOutput: sandbox/article-2025-12-18-xk7m/outputs/analysis.json\nValidation: {\"required_fields\":[\"contentId\",\"headline\",\"keyThemes\"]}"
|
|
308
307
|
}
|
|
309
308
|
```
|
|
310
309
|
|
|
@@ -350,9 +349,9 @@ When step with `final: true` passes validation:
|
|
|
350
349
|
|
|
351
350
|
---
|
|
352
351
|
|
|
353
|
-
## Variable Substitution (v0.6.
|
|
352
|
+
## Variable Substitution (v0.6.9)
|
|
354
353
|
|
|
355
|
-
Resolve variables before passing to
|
|
354
|
+
Resolve variables before passing to general-purpose subagent:
|
|
356
355
|
|
|
357
356
|
| Variable | Resolution | Example |
|
|
358
357
|
|----------|------------|---------|
|
|
@@ -435,21 +434,21 @@ input: ${{ steps.analyze-content.output }}
|
|
|
435
434
|
4. [ORDER] Computed: [analyze-content, generate-ideas, build-writing-kit]
|
|
436
435
|
|
|
437
436
|
5. [STEP] analyze-content
|
|
438
|
-
- Task tool: subagent_type="
|
|
437
|
+
- Task tool: subagent_type="general-purpose"
|
|
439
438
|
- Skill: media-reviewer
|
|
440
439
|
- Output: outputs/analysis.json
|
|
441
440
|
- Validate: PASSED
|
|
442
441
|
- Update: validation.json (analyze-content.validated = true)
|
|
443
442
|
|
|
444
443
|
6. [STEP] generate-ideas
|
|
445
|
-
- Task tool: subagent_type="
|
|
444
|
+
- Task tool: subagent_type="general-purpose"
|
|
446
445
|
- Skill: idea-synthesis
|
|
447
446
|
- Output: outputs/ideas.json
|
|
448
447
|
- Validate: PASSED
|
|
449
448
|
- Update: validation.json (generate-ideas.validated = true)
|
|
450
449
|
|
|
451
450
|
7. [STEP] build-writing-kit
|
|
452
|
-
- Task tool: subagent_type="
|
|
451
|
+
- Task tool: subagent_type="general-purpose"
|
|
453
452
|
- Skill: writing-kit-assembler
|
|
454
453
|
- Output: outputs/writing-kit.json
|
|
455
454
|
- Validate: PASSED
|
|
@@ -463,7 +462,7 @@ input: ${{ steps.analyze-content.output }}
|
|
|
463
462
|
## File References
|
|
464
463
|
|
|
465
464
|
- Workflow definitions: `workflows/*.md`
|
|
466
|
-
-
|
|
465
|
+
- Subagent: Built-in `general-purpose` agent (v0.6.9)
|
|
467
466
|
- Skill definitions: `plugins/*/skills/*/SKILL.md`
|
|
468
467
|
- Sandbox storage: `sandbox/{sandbox-id}/`
|
|
469
468
|
- Validator script: `.claude/skills/workflow-validator/scripts/validate.ts`
|