@looplia/looplia-cli 0.7.5 → 0.8.0
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-VRBGWKZ6.js → chunk-326UJHZM.js} +1 -1
- package/dist/{chunk-QQGRKUSM.js → chunk-3WLHRD63.js} +3 -3
- package/dist/chunk-JJCGDGRS.js +296 -0
- package/dist/{chunk-XTUQVJYH.js → chunk-MTYPUSCH.js} +21 -22
- package/dist/{chunk-4TKNQ5RW.js → chunk-QKGHHAFR.js} +5 -5
- package/dist/{chunk-GIZRTNY3.js → chunk-RAFHASLI.js} +97 -376
- package/dist/{claude-agent-sdk-W5MXMV4Q.js → claude-agent-sdk-FNYGQYFW.js} +3 -2
- package/dist/cli.js +226 -33
- package/dist/{compiler-4B63UTUP-VE77VSJ2.js → compiler-QKB2ZYNK-CYEN6G5G.js} +3 -3
- package/dist/discovery-22DBV6CT.js +241 -0
- package/dist/{dist-3XSIQAV3.js → dist-HMIWVZMJ.js} +8 -6
- package/dist/{sync-E5PGFGNI-IGGJR7IL.js → sync-XZGFZXZF-6AWT77CE.js} +4 -4
- package/package.json +1 -1
|
@@ -33,8 +33,9 @@ import {
|
|
|
33
33
|
validateConfig,
|
|
34
34
|
writeLoopliaSettings,
|
|
35
35
|
writeUserProfile
|
|
36
|
-
} from "./chunk-
|
|
37
|
-
import "./chunk-
|
|
36
|
+
} from "./chunk-RAFHASLI.js";
|
|
37
|
+
import "./chunk-JJCGDGRS.js";
|
|
38
|
+
import "./chunk-326UJHZM.js";
|
|
38
39
|
import "./chunk-Y55L47HC.js";
|
|
39
40
|
export {
|
|
40
41
|
DEFAULT_SETTINGS,
|
package/dist/cli.js
CHANGED
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
loadCompiledRegistry,
|
|
9
9
|
removeSkill,
|
|
10
10
|
updateSkill
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-QKGHHAFR.js";
|
|
12
|
+
import "./chunk-3WLHRD63.js";
|
|
13
13
|
import {
|
|
14
14
|
addSource,
|
|
15
15
|
compileRegistry,
|
|
@@ -17,27 +17,23 @@ import {
|
|
|
17
17
|
initializeRegistry,
|
|
18
18
|
loadSources,
|
|
19
19
|
removeSource
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-MTYPUSCH.js";
|
|
21
21
|
import "./chunk-APZNHRV3.js";
|
|
22
22
|
import {
|
|
23
23
|
DEFAULT_SETTINGS,
|
|
24
24
|
PRESETS,
|
|
25
25
|
applyPreset,
|
|
26
|
-
copyPlugins,
|
|
27
26
|
createBuildHooks,
|
|
28
27
|
createClaudeAgentExecutor,
|
|
29
28
|
createWorkflowHooks,
|
|
30
|
-
downloadRemotePlugins,
|
|
31
29
|
ensureWorkspace,
|
|
32
30
|
extractWorkflowSkills,
|
|
33
31
|
generateValidationManifest,
|
|
34
32
|
getConfigPath,
|
|
35
33
|
getFinalStep,
|
|
36
|
-
getLoopliaPluginPath,
|
|
37
34
|
getSettingsDisplayInfo,
|
|
38
35
|
initializeCommandEnvironment,
|
|
39
36
|
isInputlessWorkflow,
|
|
40
|
-
isLoopliaInitialized,
|
|
41
37
|
maskAuthToken,
|
|
42
38
|
parseWorkflow,
|
|
43
39
|
readLoopliaSettings,
|
|
@@ -46,14 +42,20 @@ import {
|
|
|
46
42
|
validateUserProfile,
|
|
47
43
|
writeLoopliaSettings,
|
|
48
44
|
writeUserProfile
|
|
49
|
-
} from "./chunk-
|
|
50
|
-
import "./chunk-VRBGWKZ6.js";
|
|
45
|
+
} from "./chunk-RAFHASLI.js";
|
|
51
46
|
import {
|
|
52
47
|
copyOutputsToDestination,
|
|
53
48
|
createSandboxDirectories,
|
|
54
49
|
generateSandboxId,
|
|
55
50
|
writeWorkflowArtifact
|
|
56
51
|
} from "./chunk-VUASEQOQ.js";
|
|
52
|
+
import {
|
|
53
|
+
copyPlugins,
|
|
54
|
+
downloadRemotePlugins,
|
|
55
|
+
getLoopliaPluginPath,
|
|
56
|
+
isLoopliaInitialized
|
|
57
|
+
} from "./chunk-JJCGDGRS.js";
|
|
58
|
+
import "./chunk-326UJHZM.js";
|
|
57
59
|
import {
|
|
58
60
|
__commonJS,
|
|
59
61
|
__dirname,
|
|
@@ -501,7 +503,7 @@ var require_react_production = __commonJS({
|
|
|
501
503
|
exports.useTransition = function() {
|
|
502
504
|
return ReactSharedInternals.H.useTransition();
|
|
503
505
|
};
|
|
504
|
-
exports.version = "19.2.
|
|
506
|
+
exports.version = "19.2.4";
|
|
505
507
|
}
|
|
506
508
|
});
|
|
507
509
|
|
|
@@ -1472,7 +1474,7 @@ var require_react_development = __commonJS({
|
|
|
1472
1474
|
exports.useTransition = function() {
|
|
1473
1475
|
return resolveDispatcher().useTransition();
|
|
1474
1476
|
};
|
|
1475
|
-
exports.version = "19.2.
|
|
1477
|
+
exports.version = "19.2.4";
|
|
1476
1478
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
1477
1479
|
})();
|
|
1478
1480
|
}
|
|
@@ -25127,6 +25129,7 @@ var base_exports = {};
|
|
|
25127
25129
|
__export(base_exports, {
|
|
25128
25130
|
ConEmu: () => ConEmu,
|
|
25129
25131
|
beep: () => beep,
|
|
25132
|
+
beginSynchronizedOutput: () => beginSynchronizedOutput,
|
|
25130
25133
|
clearScreen: () => clearScreen,
|
|
25131
25134
|
clearTerminal: () => clearTerminal,
|
|
25132
25135
|
clearViewport: () => clearViewport,
|
|
@@ -25144,6 +25147,7 @@ __export(base_exports, {
|
|
|
25144
25147
|
cursorShow: () => cursorShow,
|
|
25145
25148
|
cursorTo: () => cursorTo,
|
|
25146
25149
|
cursorUp: () => cursorUp,
|
|
25150
|
+
endSynchronizedOutput: () => endSynchronizedOutput,
|
|
25147
25151
|
enterAlternativeScreen: () => enterAlternativeScreen,
|
|
25148
25152
|
eraseDown: () => eraseDown,
|
|
25149
25153
|
eraseEndLine: () => eraseEndLine,
|
|
@@ -25158,7 +25162,8 @@ __export(base_exports, {
|
|
|
25158
25162
|
link: () => link,
|
|
25159
25163
|
scrollDown: () => scrollDown,
|
|
25160
25164
|
scrollUp: () => scrollUp,
|
|
25161
|
-
setCwd: () => setCwd
|
|
25165
|
+
setCwd: () => setCwd,
|
|
25166
|
+
synchronizedOutput: () => synchronizedOutput
|
|
25162
25167
|
});
|
|
25163
25168
|
init_esm_shims();
|
|
25164
25169
|
import process2 from "process";
|
|
@@ -25276,6 +25281,9 @@ var isOldWindows = () => {
|
|
|
25276
25281
|
var clearTerminal = isOldWindows() ? `${eraseScreen}${ESC}0f` : `${eraseScreen}${ESC}3J${ESC}H`;
|
|
25277
25282
|
var enterAlternativeScreen = ESC + "?1049h";
|
|
25278
25283
|
var exitAlternativeScreen = ESC + "?1049l";
|
|
25284
|
+
var beginSynchronizedOutput = ESC + "?2026h";
|
|
25285
|
+
var endSynchronizedOutput = ESC + "?2026l";
|
|
25286
|
+
var synchronizedOutput = (text) => beginSynchronizedOutput + text + endSynchronizedOutput;
|
|
25279
25287
|
var beep = BEL;
|
|
25280
25288
|
var link = (text, url) => {
|
|
25281
25289
|
const openLink = wrapOsc(`${OSC}8${SEP}${SEP}${url}${BEL}`);
|
|
@@ -27661,7 +27669,7 @@ function sliceAnsi(string, start, end) {
|
|
|
27661
27669
|
// ../../node_modules/string-width/index.js
|
|
27662
27670
|
init_esm_shims();
|
|
27663
27671
|
var segmenter3 = new Intl.Segmenter();
|
|
27664
|
-
var zeroWidthClusterRegex = /^(?:\p{Default_Ignorable_Code_Point}|\p{Control}|\p{Mark}|\p{Surrogate})+$/v;
|
|
27672
|
+
var zeroWidthClusterRegex = /^(?:\p{Default_Ignorable_Code_Point}|\p{Control}|\p{Format}|\p{Mark}|\p{Surrogate})+$/v;
|
|
27665
27673
|
var leadingNonPrintingRegex = /^[\p{Default_Ignorable_Code_Point}\p{Control}\p{Format}\p{Mark}\p{Surrogate}]+/v;
|
|
27666
27674
|
var rgiEmojiRegex = /^\p{RGI_Emoji}$/v;
|
|
27667
27675
|
function baseVisible(segment) {
|
|
@@ -29283,8 +29291,8 @@ for (const [start, end] of ansi_styles_default.codes) {
|
|
|
29283
29291
|
endCodesSet2.add(ansi_styles_default.color.ansi(end));
|
|
29284
29292
|
endCodesMap2.set(ansi_styles_default.color.ansi(start), ansi_styles_default.color.ansi(end));
|
|
29285
29293
|
}
|
|
29286
|
-
var
|
|
29287
|
-
var
|
|
29294
|
+
var linkCodePrefix = "\x1B]8;";
|
|
29295
|
+
var linkCodePrefixCharCodes = linkCodePrefix.split("").map((char) => char.charCodeAt(0));
|
|
29288
29296
|
var linkCodeSuffix = "\x07";
|
|
29289
29297
|
var linkCodeSuffixCharCode = linkCodeSuffix.charCodeAt(0);
|
|
29290
29298
|
var linkEndCode = `\x1B]8;;${linkCodeSuffix}`;
|
|
@@ -29293,7 +29301,7 @@ function getEndCode2(code) {
|
|
|
29293
29301
|
return code;
|
|
29294
29302
|
if (endCodesMap2.has(code))
|
|
29295
29303
|
return endCodesMap2.get(code);
|
|
29296
|
-
if (code.startsWith(
|
|
29304
|
+
if (code.startsWith(linkCodePrefix))
|
|
29297
29305
|
return linkEndCode;
|
|
29298
29306
|
code = code.slice(2);
|
|
29299
29307
|
if (code.startsWith("38")) {
|
|
@@ -29413,12 +29421,15 @@ function styledCharsToString(chars) {
|
|
|
29413
29421
|
init_esm_shims();
|
|
29414
29422
|
function parseLinkCode(string, offset) {
|
|
29415
29423
|
string = string.slice(offset);
|
|
29416
|
-
for (let index = 1; index <
|
|
29417
|
-
if (string.charCodeAt(index) !==
|
|
29424
|
+
for (let index = 1; index < linkCodePrefixCharCodes.length; index++) {
|
|
29425
|
+
if (string.charCodeAt(index) !== linkCodePrefixCharCodes[index]) {
|
|
29418
29426
|
return void 0;
|
|
29419
29427
|
}
|
|
29420
29428
|
}
|
|
29421
|
-
const
|
|
29429
|
+
const paramsEndIndex = string.indexOf(";", linkCodePrefix.length);
|
|
29430
|
+
if (paramsEndIndex === -1)
|
|
29431
|
+
return void 0;
|
|
29432
|
+
const endIndex = string.indexOf("\x07", paramsEndIndex + 1);
|
|
29422
29433
|
if (endIndex === -1)
|
|
29423
29434
|
return void 0;
|
|
29424
29435
|
return string.slice(0, endIndex + 1);
|
|
@@ -32872,7 +32883,7 @@ async function* analyzeDescriptionStreaming(description, workspace, questionCall
|
|
|
32872
32883
|
const { createSandboxDirectories: createSandboxDirectories2, generateSandboxId: generateSandboxId2 } = await import("./sandbox-XVMNWAJO.js");
|
|
32873
32884
|
const sandboxId = generateSandboxId2("build");
|
|
32874
32885
|
createSandboxDirectories2(workspace, sandboxId);
|
|
32875
|
-
const { executeInteractiveQueryStreaming } = await import("./claude-agent-sdk-
|
|
32886
|
+
const { executeInteractiveQueryStreaming } = await import("./claude-agent-sdk-FNYGQYFW.js");
|
|
32876
32887
|
const prompt = `${buildAnalysisPrompt(description)} --sandbox-id ${sandboxId}`;
|
|
32877
32888
|
const generator = executeInteractiveQueryStreaming(
|
|
32878
32889
|
prompt,
|
|
@@ -34019,6 +34030,8 @@ function processArg(result, arg, nextArg, descriptionParts) {
|
|
|
34019
34030
|
result.noInteractive = true;
|
|
34020
34031
|
} else if (arg === "--mock") {
|
|
34021
34032
|
result.mock = true;
|
|
34033
|
+
} else if (arg === "--skip-research" || arg === "--offline") {
|
|
34034
|
+
result.skipResearch = true;
|
|
34022
34035
|
} else if (!arg.startsWith("-")) {
|
|
34023
34036
|
descriptionParts.push(arg);
|
|
34024
34037
|
}
|
|
@@ -34029,7 +34042,8 @@ function parseArgs(args) {
|
|
|
34029
34042
|
description: "",
|
|
34030
34043
|
noInteractive: false,
|
|
34031
34044
|
mock: false,
|
|
34032
|
-
help: false
|
|
34045
|
+
help: false,
|
|
34046
|
+
skipResearch: false
|
|
34033
34047
|
};
|
|
34034
34048
|
let skipNext = false;
|
|
34035
34049
|
for (const [index, arg] of args.entries()) {
|
|
@@ -34059,18 +34073,26 @@ Options:
|
|
|
34059
34073
|
--output, -o <path> Output directory (default: ~/.looplia/workflows/)
|
|
34060
34074
|
--name, -n <name> Workflow filename (derived from description if not set)
|
|
34061
34075
|
--no-interactive Skip TUI, batch mode
|
|
34076
|
+
--skip-research Skip skill auto-discovery (use local skills only)
|
|
34077
|
+
--offline Alias for --skip-research
|
|
34062
34078
|
--mock Use mock mode (no API calls)
|
|
34063
34079
|
--help, -h Show this help
|
|
34064
34080
|
|
|
34081
|
+
Skill Auto-Discovery (v0.8.0):
|
|
34082
|
+
By default, build searches skills.sh for relevant skills based on your
|
|
34083
|
+
description and installs them to ~/.looplia/plugins/auto-discovery-plugin/.
|
|
34084
|
+
Use --skip-research to disable this and use only locally installed skills.
|
|
34085
|
+
|
|
34065
34086
|
Examples:
|
|
34066
34087
|
looplia build
|
|
34067
34088
|
looplia build "analyze videos and create blog outlines"
|
|
34068
34089
|
looplia build "summarize articles" --name article-summary
|
|
34069
34090
|
looplia build "..." --no-interactive --name my-workflow
|
|
34091
|
+
looplia build "..." --skip-research # Skip skill discovery
|
|
34070
34092
|
`);
|
|
34071
34093
|
}
|
|
34072
34094
|
function getWorkspacePath() {
|
|
34073
|
-
return resolve(homedir2(), ".looplia");
|
|
34095
|
+
return process.env.LOOPLIA_HOME ?? resolve(homedir2(), ".looplia");
|
|
34074
34096
|
}
|
|
34075
34097
|
function ensureWorkspace2(mock) {
|
|
34076
34098
|
const workspace = getWorkspacePath();
|
|
@@ -34191,7 +34213,7 @@ async function* executeInteractiveStreamingBatch(prompt, workspace, questionCall
|
|
|
34191
34213
|
process.env.LOOPLIA_SANDBOX_ID = sandboxId;
|
|
34192
34214
|
process.env.LOOPLIA_SANDBOX_ROOT = join2(workspace, "sandbox");
|
|
34193
34215
|
const promptWithSandbox = `${prompt} --sandbox-id ${sandboxId}`;
|
|
34194
|
-
const { executeInteractiveQueryStreaming } = await import("./claude-agent-sdk-
|
|
34216
|
+
const { executeInteractiveQueryStreaming } = await import("./claude-agent-sdk-FNYGQYFW.js");
|
|
34195
34217
|
const schema = {
|
|
34196
34218
|
type: "object",
|
|
34197
34219
|
properties: {
|
|
@@ -34397,6 +34419,66 @@ function renderResult(result, workspace) {
|
|
|
34397
34419
|
const displayPath = writtenPath ?? result.workflowPath ?? null;
|
|
34398
34420
|
renderSuccessMessage(result, displayPath);
|
|
34399
34421
|
}
|
|
34422
|
+
async function researchAndInstallSkills(description, interactive) {
|
|
34423
|
+
const {
|
|
34424
|
+
searchSkills,
|
|
34425
|
+
fetchSkillContent,
|
|
34426
|
+
installSkillToAutoDiscovery,
|
|
34427
|
+
isSkillAutoDiscovered
|
|
34428
|
+
} = await import("./discovery-22DBV6CT.js");
|
|
34429
|
+
console.log("Researching skills for workflow...");
|
|
34430
|
+
const results = await searchSkills(description);
|
|
34431
|
+
if (results.length === 0) {
|
|
34432
|
+
console.log("No additional skills found, using local catalog");
|
|
34433
|
+
return [];
|
|
34434
|
+
}
|
|
34435
|
+
let selectedSkills;
|
|
34436
|
+
if (interactive) {
|
|
34437
|
+
console.log(`Found ${results.length} potential skills:`);
|
|
34438
|
+
for (const [i, skill] of results.slice(0, 5).entries()) {
|
|
34439
|
+
console.log(` ${i + 1}. ${skill.name} - ${skill.description}`);
|
|
34440
|
+
}
|
|
34441
|
+
selectedSkills = results.slice(0, 3);
|
|
34442
|
+
console.log(`Auto-selecting top ${selectedSkills.length} skills...`);
|
|
34443
|
+
} else {
|
|
34444
|
+
selectedSkills = results.slice(0, 3);
|
|
34445
|
+
}
|
|
34446
|
+
const installedNames = [];
|
|
34447
|
+
for (const skill of selectedSkills) {
|
|
34448
|
+
if (await isSkillAutoDiscovered(skill.name)) {
|
|
34449
|
+
console.log(` Skipped: ${skill.name} (already installed)`);
|
|
34450
|
+
installedNames.push(skill.name);
|
|
34451
|
+
continue;
|
|
34452
|
+
}
|
|
34453
|
+
try {
|
|
34454
|
+
const content = await fetchSkillContent(
|
|
34455
|
+
skill.owner,
|
|
34456
|
+
skill.repo,
|
|
34457
|
+
skill.name
|
|
34458
|
+
);
|
|
34459
|
+
const sourceUrl = `https://github.com/${skill.owner}/${skill.repo}`;
|
|
34460
|
+
await installSkillToAutoDiscovery(skill.name, content, sourceUrl);
|
|
34461
|
+
installedNames.push(skill.name);
|
|
34462
|
+
console.log(` Installed: ${skill.name}`);
|
|
34463
|
+
} catch (error) {
|
|
34464
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
34465
|
+
console.warn(` Failed to install ${skill.name}: ${msg}`);
|
|
34466
|
+
}
|
|
34467
|
+
}
|
|
34468
|
+
if (installedNames.length > 0) {
|
|
34469
|
+
console.log(`Installed ${installedNames.length} skills for workflow`);
|
|
34470
|
+
}
|
|
34471
|
+
return installedNames;
|
|
34472
|
+
}
|
|
34473
|
+
async function trySkillResearch(description, interactive) {
|
|
34474
|
+
try {
|
|
34475
|
+
await researchAndInstallSkills(description, interactive);
|
|
34476
|
+
} catch (error) {
|
|
34477
|
+
console.warn(
|
|
34478
|
+
`Skill research failed: ${error instanceof Error ? error.message : error}`
|
|
34479
|
+
);
|
|
34480
|
+
}
|
|
34481
|
+
}
|
|
34400
34482
|
async function runBuildCommand(args) {
|
|
34401
34483
|
const parsed = parseArgs(args);
|
|
34402
34484
|
if (parsed.help) {
|
|
@@ -34405,6 +34487,12 @@ async function runBuildCommand(args) {
|
|
|
34405
34487
|
}
|
|
34406
34488
|
try {
|
|
34407
34489
|
const workspace = ensureWorkspace2(parsed.mock);
|
|
34490
|
+
if (!(parsed.mock || parsed.skipResearch) && parsed.description) {
|
|
34491
|
+
await trySkillResearch(
|
|
34492
|
+
parsed.description,
|
|
34493
|
+
isInteractive() && !parsed.noInteractive
|
|
34494
|
+
);
|
|
34495
|
+
}
|
|
34408
34496
|
if (!parsed.mock) {
|
|
34409
34497
|
try {
|
|
34410
34498
|
await compileRegistry({ localOnly: true });
|
|
@@ -34883,19 +34971,19 @@ Description:
|
|
|
34883
34971
|
Installs the looplia plugin to ~/.looplia for use with Claude Code.
|
|
34884
34972
|
|
|
34885
34973
|
Default mode (npm bundle):
|
|
34886
|
-
- Copies bundled plugins from npm package to ~/.looplia
|
|
34974
|
+
- Copies bundled plugins from npm package to ~/.looplia/plugins/
|
|
34887
34975
|
- Installs looplia-core (workflow engine) + looplia-writer (writing domain)
|
|
34888
34976
|
|
|
34889
34977
|
Remote mode (--remote):
|
|
34890
34978
|
- Downloads plugins from GitHub release
|
|
34891
34979
|
- Use --remote v0.6.5 for specific version
|
|
34892
34980
|
|
|
34893
|
-
Created structure:
|
|
34981
|
+
Created structure (v0.8.0):
|
|
34894
34982
|
~/.looplia/
|
|
34895
|
-
\u251C\u2500\u2500
|
|
34896
|
-
\u2502 \
|
|
34897
|
-
\u251C\u2500\u2500 looplia-writer/
|
|
34898
|
-
\u2502 \u2514\u2500\u2500
|
|
34983
|
+
\u251C\u2500\u2500 plugins/ All plugins (unified location)
|
|
34984
|
+
\u2502 \u251C\u2500\u2500 looplia-core/ Core workflow engine
|
|
34985
|
+
\u2502 \u251C\u2500\u2500 looplia-writer/ Writing domain plugin
|
|
34986
|
+
\u2502 \u2514\u2500\u2500 auto-discovery-plugin/ Auto-discovered skills (created by build)
|
|
34899
34987
|
\u251C\u2500\u2500 workflows/ Workflow templates
|
|
34900
34988
|
\u251C\u2500\u2500 sandbox/ Execution isolation
|
|
34901
34989
|
\u2514\u2500\u2500 user-profile.json User preferences
|
|
@@ -34950,7 +35038,7 @@ function printInitSuccess(targetDir) {
|
|
|
34950
35038
|
console.log("");
|
|
34951
35039
|
console.log(`Looplia initialized at ${targetDir}`);
|
|
34952
35040
|
console.log("");
|
|
34953
|
-
console.log("Installed plugins:");
|
|
35041
|
+
console.log("Installed plugins (in plugins/):");
|
|
34954
35042
|
console.log(" - looplia-core/ (workflow engine)");
|
|
34955
35043
|
console.log(" - looplia-writer/ (writing domain)");
|
|
34956
35044
|
console.log("");
|
|
@@ -35403,7 +35491,7 @@ Examples:
|
|
|
35403
35491
|
`);
|
|
35404
35492
|
}
|
|
35405
35493
|
function getWorkspacePath2() {
|
|
35406
|
-
return resolve2(homedir3(), ".looplia");
|
|
35494
|
+
return process.env.LOOPLIA_HOME ?? resolve2(homedir3(), ".looplia");
|
|
35407
35495
|
}
|
|
35408
35496
|
function ensureWorkspace3(mock) {
|
|
35409
35497
|
const workspace = getWorkspacePath2();
|
|
@@ -35684,6 +35772,7 @@ Usage:
|
|
|
35684
35772
|
|
|
35685
35773
|
Subcommands:
|
|
35686
35774
|
add <name|url> Install skill by name or GitHub URL
|
|
35775
|
+
search <query> Search skills.sh registry
|
|
35687
35776
|
list List installed/available skills
|
|
35688
35777
|
info <name> Show skill details
|
|
35689
35778
|
remove <name> Remove skill from workspace
|
|
@@ -35700,6 +35789,7 @@ Examples:
|
|
|
35700
35789
|
looplia skill add custom-analyzer --from github:user/repo
|
|
35701
35790
|
looplia skill add https://github.com/user/my-skill
|
|
35702
35791
|
looplia skill add https://github.com/anthropics/skills/tree/main/skills/algorithmic-art
|
|
35792
|
+
looplia skill search "pdf processing"
|
|
35703
35793
|
looplia skill list
|
|
35704
35794
|
looplia skill list --available
|
|
35705
35795
|
looplia skill info media-reviewer
|
|
@@ -35744,7 +35834,7 @@ async function skillAdd(nameOrUrl, from) {
|
|
|
35744
35834
|
}
|
|
35745
35835
|
if (GITHUB_URL_PATTERN.test(nameOrUrl)) {
|
|
35746
35836
|
console.log(`Installing skill from URL: ${nameOrUrl}...`);
|
|
35747
|
-
const { installSkillFromUrl } = await import("./dist-
|
|
35837
|
+
const { installSkillFromUrl } = await import("./dist-HMIWVZMJ.js");
|
|
35748
35838
|
const result2 = await installSkillFromUrl(nameOrUrl, true);
|
|
35749
35839
|
switch (result2.status) {
|
|
35750
35840
|
case "installed":
|
|
@@ -35944,6 +36034,106 @@ async function skillUpdate(name) {
|
|
|
35944
36034
|
console.log(`Unexpected status: ${result.status}`);
|
|
35945
36035
|
}
|
|
35946
36036
|
}
|
|
36037
|
+
function displaySearchResults(results) {
|
|
36038
|
+
console.log(`
|
|
36039
|
+
Found ${results.length} skill(s):
|
|
36040
|
+
`);
|
|
36041
|
+
console.log("\u2500".repeat(80));
|
|
36042
|
+
console.log(
|
|
36043
|
+
" # NAME OWNER/REPO DESCRIPTION"
|
|
36044
|
+
);
|
|
36045
|
+
console.log("\u2500".repeat(80));
|
|
36046
|
+
for (const [index, result] of results.entries()) {
|
|
36047
|
+
const num = String(index + 1).padStart(2);
|
|
36048
|
+
const name = result.name.padEnd(20);
|
|
36049
|
+
const repo = `${result.owner}/${result.repo}`.padEnd(28);
|
|
36050
|
+
const desc = result.description.length > 25 ? `${result.description.slice(0, 22)}...` : result.description;
|
|
36051
|
+
console.log(` ${num} ${name} ${repo} ${desc}`);
|
|
36052
|
+
}
|
|
36053
|
+
console.log("\u2500".repeat(80));
|
|
36054
|
+
}
|
|
36055
|
+
async function promptSkillSelection() {
|
|
36056
|
+
const readline = await import("readline");
|
|
36057
|
+
const rl = readline.createInterface({
|
|
36058
|
+
input: process.stdin,
|
|
36059
|
+
output: process.stdout
|
|
36060
|
+
});
|
|
36061
|
+
const answer = await new Promise((resolve3) => {
|
|
36062
|
+
rl.question(
|
|
36063
|
+
"\nEnter number(s) to install (comma-separated), or 'q' to quit: ",
|
|
36064
|
+
resolve3
|
|
36065
|
+
);
|
|
36066
|
+
});
|
|
36067
|
+
rl.close();
|
|
36068
|
+
return answer;
|
|
36069
|
+
}
|
|
36070
|
+
function parseSkillSelection(answer, results) {
|
|
36071
|
+
const indices = answer.split(",").map((s) => Number.parseInt(s.trim(), 10) - 1);
|
|
36072
|
+
return indices.filter((i) => i >= 0 && i < results.length).map((i) => results[i]).filter((s) => s !== void 0);
|
|
36073
|
+
}
|
|
36074
|
+
async function installSelectedSkills(selected) {
|
|
36075
|
+
const { fetchSkillContent, installSkillToAutoDiscovery } = await import("./discovery-22DBV6CT.js");
|
|
36076
|
+
console.log(`
|
|
36077
|
+
Installing ${selected.length} skill(s)...`);
|
|
36078
|
+
let installedCount = 0;
|
|
36079
|
+
for (const skill of selected) {
|
|
36080
|
+
try {
|
|
36081
|
+
const content = await fetchSkillContent(
|
|
36082
|
+
skill.owner,
|
|
36083
|
+
skill.repo,
|
|
36084
|
+
skill.name
|
|
36085
|
+
);
|
|
36086
|
+
const sourceUrl = `https://github.com/${skill.owner}/${skill.repo}`;
|
|
36087
|
+
const installResult = await installSkillToAutoDiscovery(
|
|
36088
|
+
skill.name,
|
|
36089
|
+
content,
|
|
36090
|
+
sourceUrl
|
|
36091
|
+
);
|
|
36092
|
+
console.log(` \u2713 Installed: ${skill.name} \u2192 ${installResult.path}`);
|
|
36093
|
+
installedCount += 1;
|
|
36094
|
+
} catch (error) {
|
|
36095
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
36096
|
+
console.error(` \u2717 Failed to install ${skill.name}: ${msg}`);
|
|
36097
|
+
}
|
|
36098
|
+
}
|
|
36099
|
+
return installedCount;
|
|
36100
|
+
}
|
|
36101
|
+
async function skillSearch(query) {
|
|
36102
|
+
if (!query) {
|
|
36103
|
+
console.error("Error: Search query required");
|
|
36104
|
+
console.error("Usage: looplia skill search <query>");
|
|
36105
|
+
process.exit(1);
|
|
36106
|
+
}
|
|
36107
|
+
console.log(`Searching skills.sh for: ${query}...`);
|
|
36108
|
+
const { searchSkills } = await import("./discovery-22DBV6CT.js");
|
|
36109
|
+
const results = await searchSkills(query);
|
|
36110
|
+
if (results.length === 0) {
|
|
36111
|
+
console.log("No skills found matching your query.");
|
|
36112
|
+
return;
|
|
36113
|
+
}
|
|
36114
|
+
displaySearchResults(results);
|
|
36115
|
+
if (!process.stdin.isTTY) {
|
|
36116
|
+
console.log("\nTo install a skill, run: looplia skill add <name>");
|
|
36117
|
+
return;
|
|
36118
|
+
}
|
|
36119
|
+
const answer = await promptSkillSelection();
|
|
36120
|
+
if (answer.toLowerCase() === "q" || !answer.trim()) {
|
|
36121
|
+
console.log("No skills installed.");
|
|
36122
|
+
return;
|
|
36123
|
+
}
|
|
36124
|
+
const selected = parseSkillSelection(answer, results);
|
|
36125
|
+
if (selected.length === 0) {
|
|
36126
|
+
console.log("No valid selection. No skills installed.");
|
|
36127
|
+
return;
|
|
36128
|
+
}
|
|
36129
|
+
const installedCount = await installSelectedSkills(selected);
|
|
36130
|
+
if (installedCount > 0) {
|
|
36131
|
+
console.log("\nUpdating skill catalog...");
|
|
36132
|
+
const { compileRegistry: compileRegistry2 } = await import("./dist-HMIWVZMJ.js");
|
|
36133
|
+
await compileRegistry2({ localOnly: true });
|
|
36134
|
+
console.log("\u2713 Skill catalog updated");
|
|
36135
|
+
}
|
|
36136
|
+
}
|
|
35947
36137
|
async function runSkillCommand(args) {
|
|
35948
36138
|
const subcommand = args[0];
|
|
35949
36139
|
if (!subcommand || subcommand === "--help" || subcommand === "-h") {
|
|
@@ -35961,6 +36151,9 @@ async function runSkillCommand(args) {
|
|
|
35961
36151
|
case "add":
|
|
35962
36152
|
await skillAdd(positionalArgs[1] ?? "", from);
|
|
35963
36153
|
break;
|
|
36154
|
+
case "search":
|
|
36155
|
+
await skillSearch(positionalArgs[1] ?? "");
|
|
36156
|
+
break;
|
|
35964
36157
|
case "list":
|
|
35965
36158
|
await skillList({ installed: hasInstalled, available: hasAvailable });
|
|
35966
36159
|
break;
|
|
@@ -35981,7 +36174,7 @@ async function runSkillCommand(args) {
|
|
|
35981
36174
|
}
|
|
35982
36175
|
|
|
35983
36176
|
// src/index.ts
|
|
35984
|
-
var VERSION = "0.
|
|
36177
|
+
var VERSION = "0.8.0";
|
|
35985
36178
|
function printHelp5() {
|
|
35986
36179
|
console.log(`
|
|
35987
36180
|
looplia - Content intelligence CLI (v${VERSION})
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
loadSources,
|
|
13
13
|
removeSource,
|
|
14
14
|
saveSources
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-MTYPUSCH.js";
|
|
16
|
+
import "./chunk-326UJHZM.js";
|
|
17
17
|
import {
|
|
18
18
|
init_esm_shims
|
|
19
19
|
} from "./chunk-Y55L47HC.js";
|
|
20
20
|
|
|
21
|
-
// ../../packages/provider/dist/compiler-
|
|
21
|
+
// ../../packages/provider/dist/compiler-QKB2ZYNK.js
|
|
22
22
|
init_esm_shims();
|
|
23
23
|
export {
|
|
24
24
|
DEFAULT_MARKETPLACE_SOURCES,
|