@looplia/looplia-cli 0.7.0 → 0.7.2

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.
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env bun
2
+ import {
3
+ init_esm_shims
4
+ } from "./chunk-Y55L47HC.js";
5
+
6
+ // src/utils/sandbox.ts
7
+ init_esm_shims();
8
+ import { randomBytes } from "crypto";
9
+ import { copyFileSync, mkdirSync, readdirSync } from "fs";
10
+ import { join, resolve } from "path";
11
+ var SANDBOX_DIRS = {
12
+ INPUTS: "inputs",
13
+ OUTPUTS: "outputs",
14
+ LOGS: "logs"
15
+ };
16
+ function generateRandomSuffix() {
17
+ return randomBytes(2).toString("hex");
18
+ }
19
+ function generateSlug(input, maxLength = 30) {
20
+ return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, maxLength);
21
+ }
22
+ function generateSandboxId(slug) {
23
+ const normalizedSlug = generateSlug(slug);
24
+ const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
25
+ const suffix = generateRandomSuffix();
26
+ return `${normalizedSlug}-${date}-${suffix}`;
27
+ }
28
+ function createSandboxDirectories(workspace, sandboxId) {
29
+ const sandboxDir = join(workspace, "sandbox", sandboxId);
30
+ mkdirSync(join(sandboxDir, SANDBOX_DIRS.INPUTS), { recursive: true });
31
+ mkdirSync(join(sandboxDir, SANDBOX_DIRS.OUTPUTS), { recursive: true });
32
+ mkdirSync(join(sandboxDir, SANDBOX_DIRS.LOGS), { recursive: true });
33
+ return sandboxDir;
34
+ }
35
+ function copyOutputsToDestination(workspace, sandboxId, destDir) {
36
+ if (!(workspace && sandboxId && destDir)) {
37
+ return 0;
38
+ }
39
+ const outputsPath = join(
40
+ workspace,
41
+ "sandbox",
42
+ sandboxId,
43
+ SANDBOX_DIRS.OUTPUTS
44
+ );
45
+ const resolvedDest = resolve(destDir);
46
+ mkdirSync(resolvedDest, { recursive: true });
47
+ let copiedCount = 0;
48
+ try {
49
+ const entries = readdirSync(outputsPath, { withFileTypes: true });
50
+ for (const entry of entries) {
51
+ if (entry.isFile()) {
52
+ const srcPath = join(outputsPath, entry.name);
53
+ const destPath = join(resolvedDest, entry.name);
54
+ copyFileSync(srcPath, destPath);
55
+ copiedCount += 1;
56
+ }
57
+ }
58
+ } catch (error) {
59
+ const nodeError = error;
60
+ if (nodeError.code !== "ENOENT") {
61
+ console.warn(`Warning: Error copying outputs: ${error}`);
62
+ }
63
+ }
64
+ return copiedCount;
65
+ }
66
+
67
+ export {
68
+ SANDBOX_DIRS,
69
+ generateRandomSuffix,
70
+ generateSlug,
71
+ generateSandboxId,
72
+ createSandboxDirectories,
73
+ copyOutputsToDestination
74
+ };
@@ -1,27 +1,19 @@
1
- #!/usr/bin/env node
2
- var __defProp = Object.defineProperty;
3
- var __export = (target, all) => {
4
- for (var name in all)
5
- __defProp(target, name, { get: all[name], enumerable: true });
6
- };
1
+ #!/usr/bin/env bun
2
+ import {
3
+ init_esm_shims
4
+ } from "./chunk-Y55L47HC.js";
7
5
 
8
- // ../../node_modules/tsup/assets/esm_shims.js
6
+ // ../../packages/provider/dist/chunk-MM63NAER.js
7
+ init_esm_shims();
9
8
  import path from "path";
10
9
  import { fileURLToPath } from "url";
10
+ import { mkdir, stat } from "fs/promises";
11
11
  var getFilename = () => fileURLToPath(import.meta.url);
12
12
  var getDirname = () => path.dirname(getFilename());
13
13
  var __dirname = /* @__PURE__ */ getDirname();
14
-
15
- // ../../packages/provider/dist/chunk-MM63NAER.js
16
- import path2 from "path";
17
- import { fileURLToPath as fileURLToPath2 } from "url";
18
- import { mkdir, stat } from "fs/promises";
19
- var getFilename2 = () => fileURLToPath2(import.meta.url);
20
- var getDirname2 = () => path2.dirname(getFilename2());
21
- var __dirname2 = /* @__PURE__ */ getDirname2();
22
- async function pathExists(path22) {
14
+ async function pathExists(path2) {
23
15
  try {
24
- await stat(path22);
16
+ await stat(path2);
25
17
  return true;
26
18
  } catch {
27
19
  return false;
@@ -55,9 +47,7 @@ function isValidPathSegment(pathSegment) {
55
47
  }
56
48
 
57
49
  export {
58
- __export,
59
50
  __dirname,
60
- __dirname2,
61
51
  pathExists,
62
52
  isValidGitUrl,
63
53
  isValidPathSegment
@@ -1,9 +1,13 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
2
  import {
3
3
  pathExists
4
- } from "./chunk-FCL2HRTX.js";
4
+ } from "./chunk-VRBGWKZ6.js";
5
+ import {
6
+ init_esm_shims
7
+ } from "./chunk-Y55L47HC.js";
5
8
 
6
- // ../../packages/provider/dist/chunk-NOF2J4UK.js
9
+ // ../../packages/provider/dist/chunk-QHAUYGWN.js
10
+ init_esm_shims();
7
11
  import { exec } from "child_process";
8
12
  import { mkdir, readdir, readFile, writeFile } from "fs/promises";
9
13
  import { homedir } from "os";
@@ -26,6 +30,14 @@ function createProgress() {
26
30
  console.log(`\u2713 ${message ?? currentMessage}`);
27
31
  isActive = false;
28
32
  },
33
+ warn(message) {
34
+ if (!isActive) {
35
+ return;
36
+ }
37
+ process.stdout.write("\r\x1B[K");
38
+ console.log(`\u26A0 ${message ?? currentMessage}`);
39
+ isActive = false;
40
+ },
29
41
  fail(message) {
30
42
  if (!isActive) {
31
43
  return;
@@ -50,14 +62,6 @@ function createProgress() {
50
62
  }
51
63
  };
52
64
  }
53
- var execAsync = promisify(exec);
54
- var OFFICIAL_REGISTRY_URL = "https://github.com/memorysaver/looplia-core/releases/latest/download/registry.json";
55
- var REGISTRY_SCHEMA_URL = "https://looplia.com/schema/registry.json";
56
- var REGISTRY_VERSION = "1.0.0";
57
- var PROTOCOL_REGEX = /^https?:\/\//;
58
- var TRAILING_SLASH_REGEX = /\/$/;
59
- var LEADING_DOT_SLASH_REGEX = /^\.\//;
60
- var FRONTMATTER_REGEX = /^---\n([\s\S]*?)\n---/;
61
65
  var CAPABILITY_PATTERNS = [
62
66
  { pattern: /media|video|audio|image/, capability: "media-processing" },
63
67
  { pattern: /content|text|document/, capability: "content-analysis" },
@@ -67,6 +71,95 @@ var CAPABILITY_PATTERNS = [
67
71
  { pattern: /generat|creat|produc/, capability: "generation" },
68
72
  { pattern: /valid|check|verify/, capability: "validation" }
69
73
  ];
74
+ var FRONTMATTER_REGEX = /^---\n([\s\S]*?)\n---/;
75
+ var PROTOCOL_REGEX = /^https?:\/\//;
76
+ var TRAILING_SLASH_REGEX = /\/$/;
77
+ var LEADING_DOT_SLASH_REGEX = /^\.\//;
78
+ function parseMultilineValue(lines, startIndex) {
79
+ const multilineLines = [];
80
+ for (let j = startIndex; j < lines.length; j++) {
81
+ const nextLine = lines[j];
82
+ if (nextLine === void 0) {
83
+ break;
84
+ }
85
+ if (nextLine.startsWith(" ")) {
86
+ multilineLines.push(nextLine.trim());
87
+ } else if (nextLine.trim() !== "") {
88
+ break;
89
+ }
90
+ }
91
+ return multilineLines.join(" ");
92
+ }
93
+ function parseYamlFrontmatter(frontmatter) {
94
+ const lines = frontmatter.split("\n");
95
+ const metadata = {};
96
+ for (let i = 0; i < lines.length; i++) {
97
+ const line = lines[i];
98
+ if (line === void 0) {
99
+ continue;
100
+ }
101
+ const colonIndex = line.indexOf(":");
102
+ if (colonIndex <= 0) {
103
+ continue;
104
+ }
105
+ const key = line.slice(0, colonIndex).trim();
106
+ let value = line.slice(colonIndex + 1).trim();
107
+ if (value === "|") {
108
+ value = parseMultilineValue(lines, i + 1);
109
+ }
110
+ metadata[key] = value;
111
+ }
112
+ return metadata;
113
+ }
114
+ function inferCategory(name, description) {
115
+ const text = `${name} ${description}`.toLowerCase();
116
+ if (text.includes("review") || text.includes("analyze") || text.includes("scan")) {
117
+ return "analysis";
118
+ }
119
+ if (text.includes("generate") || text.includes("synthesis") || text.includes("create")) {
120
+ return "generation";
121
+ }
122
+ if (text.includes("assemble") || text.includes("document") || text.includes("compile")) {
123
+ return "assembly";
124
+ }
125
+ if (text.includes("validate") || text.includes("check")) {
126
+ return "validation";
127
+ }
128
+ if (text.includes("search") || text.includes("find")) {
129
+ return "search";
130
+ }
131
+ if (text.includes("workflow") || text.includes("execute") || text.includes("orchestrat")) {
132
+ return "orchestration";
133
+ }
134
+ return "utility";
135
+ }
136
+ function inferCapabilities(description) {
137
+ const capabilities = [];
138
+ const text = description.toLowerCase();
139
+ for (const { pattern, capability } of CAPABILITY_PATTERNS) {
140
+ if (pattern.test(text)) {
141
+ capabilities.push(capability);
142
+ }
143
+ }
144
+ return capabilities;
145
+ }
146
+ function formatTitle(name) {
147
+ return name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
148
+ }
149
+ var execAsync = promisify(exec);
150
+ var REGISTRY_VERSION = "1.0.0";
151
+ var DEFAULT_MARKETPLACE_SOURCES = [
152
+ {
153
+ name: "looplia-skills",
154
+ url: "https://github.com/memorysaver/looplia-skills",
155
+ description: "Looplia curated skills collection"
156
+ },
157
+ {
158
+ name: "anthropic-skills",
159
+ url: "https://github.com/anthropics/skills",
160
+ description: "Official Anthropic skills - xlsx, pdf, pptx, docx, frontend-design, and more"
161
+ }
162
+ ];
70
163
  function getLoopliaHome() {
71
164
  return process.env.LOOPLIA_HOME ?? join(homedir(), ".looplia");
72
165
  }
@@ -86,16 +179,17 @@ async function initializeRegistry(force = false) {
86
179
  await mkdir(registryPath, { recursive: true });
87
180
  await mkdir(join(registryPath, "cache"), { recursive: true });
88
181
  if (force || !await pathExists(sourcesPath)) {
89
- const defaultSources = [
90
- {
91
- id: "official",
92
- type: "official",
93
- url: OFFICIAL_REGISTRY_URL,
182
+ const defaultSources = DEFAULT_MARKETPLACE_SOURCES.map(
183
+ (source, index) => ({
184
+ id: `github:${source.url.replace("https://github.com/", "")}`,
185
+ type: "github",
186
+ url: source.url,
94
187
  enabled: true,
95
- priority: 100,
188
+ priority: 90 - index * 10,
189
+ // First source gets highest priority
96
190
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
97
- }
98
- ];
191
+ })
192
+ );
99
193
  await writeFile(sourcesPath, JSON.stringify(defaultSources, null, 2));
100
194
  }
101
195
  }
@@ -168,7 +262,6 @@ async function tryFetchMarketplace(repoPath) {
168
262
  }
169
263
  }
170
264
  return {
171
- $schema: REGISTRY_SCHEMA_URL,
172
265
  name: marketplace.name,
173
266
  homepage: `https://github.com/${repoPath}`,
174
267
  version: marketplace.version ?? "1.0.0",
@@ -192,24 +285,6 @@ async function tryFetchRegistryJson(repoPath) {
192
285
  }
193
286
  }
194
287
  async function fetchRemoteRegistry(source) {
195
- if (source.type === "official") {
196
- try {
197
- const response = await fetch(source.url);
198
- if (!response.ok) {
199
- console.warn(
200
- `Failed to fetch registry from ${source.url}: ${response.status}`
201
- );
202
- return null;
203
- }
204
- return {
205
- manifest: await response.json(),
206
- format: "registry"
207
- };
208
- } catch (error) {
209
- console.warn(`Error fetching registry from ${source.url}:`, error);
210
- return null;
211
- }
212
- }
213
288
  const repoPath = source.url.replace(PROTOCOL_REGEX, "").replace("github.com/", "").replace(TRAILING_SLASH_REGEX, "");
214
289
  const marketplaceManifest = await tryFetchMarketplace(repoPath);
215
290
  if (marketplaceManifest) {
@@ -224,42 +299,6 @@ async function fetchRemoteRegistry(source) {
224
299
  );
225
300
  return null;
226
301
  }
227
- function parseYamlFrontmatter(frontmatter) {
228
- const lines = frontmatter.split("\n");
229
- const metadata = {};
230
- for (let i = 0; i < lines.length; i++) {
231
- const line = lines[i];
232
- if (line === void 0) {
233
- continue;
234
- }
235
- const colonIndex = line.indexOf(":");
236
- if (colonIndex <= 0) {
237
- continue;
238
- }
239
- const key = line.slice(0, colonIndex).trim();
240
- let value = line.slice(colonIndex + 1).trim();
241
- if (value === "|") {
242
- value = parseMultilineValue(lines, i + 1);
243
- }
244
- metadata[key] = value;
245
- }
246
- return metadata;
247
- }
248
- function parseMultilineValue(lines, startIndex) {
249
- const multilineLines = [];
250
- for (let j = startIndex; j < lines.length; j++) {
251
- const nextLine = lines[j];
252
- if (nextLine === void 0) {
253
- break;
254
- }
255
- if (nextLine.startsWith(" ")) {
256
- multilineLines.push(nextLine.trim());
257
- } else if (nextLine.trim() !== "") {
258
- break;
259
- }
260
- }
261
- return multilineLines.join(" ");
262
- }
263
302
  function buildSkillFromMetadata(metadata) {
264
303
  const category = inferCategory(
265
304
  metadata.name ?? "",
@@ -294,41 +333,6 @@ async function parseSkillMetadata(skillPath) {
294
333
  return null;
295
334
  }
296
335
  }
297
- function inferCategory(name, description) {
298
- const text = `${name} ${description}`.toLowerCase();
299
- if (text.includes("review") || text.includes("analyze") || text.includes("scan")) {
300
- return "analysis";
301
- }
302
- if (text.includes("generate") || text.includes("synthesis") || text.includes("create")) {
303
- return "generation";
304
- }
305
- if (text.includes("assemble") || text.includes("document") || text.includes("compile")) {
306
- return "assembly";
307
- }
308
- if (text.includes("validate") || text.includes("check")) {
309
- return "validation";
310
- }
311
- if (text.includes("search") || text.includes("find")) {
312
- return "search";
313
- }
314
- if (text.includes("workflow") || text.includes("execute") || text.includes("orchestrat")) {
315
- return "orchestration";
316
- }
317
- return "utility";
318
- }
319
- function inferCapabilities(description) {
320
- const capabilities = [];
321
- const text = description.toLowerCase();
322
- for (const { pattern, capability } of CAPABILITY_PATTERNS) {
323
- if (pattern.test(text)) {
324
- capabilities.push(capability);
325
- }
326
- }
327
- return capabilities;
328
- }
329
- function formatTitle(name) {
330
- return name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
331
- }
332
336
  async function getGitRemoteUrl(repoPath) {
333
337
  const pluginJsonPath = join(repoPath, ".claude-plugin", "plugin.json");
334
338
  try {
@@ -481,10 +485,10 @@ async function processRemoteSource(options) {
481
485
  model: item.model,
482
486
  inputless: item.inputless,
483
487
  source: source.id,
484
- sourceType: source.type === "official" ? "builtin" : "thirdparty",
488
+ sourceType: "thirdparty",
485
489
  installed: installed !== void 0,
486
490
  installedPath: installed?.installedPath,
487
- gitUrl: format === "marketplace" || source.type === "github" ? item.downloadUrl : void 0,
491
+ gitUrl: item.downloadUrl,
488
492
  skillPath: item.skillPath,
489
493
  // Set by marketplace format, undefined for registry.json
490
494
  checksum: item.checksum,
@@ -516,7 +520,8 @@ function buildRegistrySummary(skills) {
516
520
  }
517
521
  return { byCategory, bySource };
518
522
  }
519
- async function compileRegistry(showProgress = false) {
523
+ async function compileRegistry(options) {
524
+ const { showProgress = false, localOnly = true } = options ?? {};
520
525
  const progress = showProgress ? createProgress() : null;
521
526
  const loopliaPath = getLoopliaHome();
522
527
  const sources = await loadSources();
@@ -530,15 +535,17 @@ async function compileRegistry(showProgress = false) {
530
535
  for (const source of localSources) {
531
536
  await processLocalSource(source, seenSkills, allSkills, progress);
532
537
  }
533
- const remoteSources = sources.filter((s) => s.enabled && s.type !== "local").sort((a, b) => b.priority - a.priority);
534
- for (const source of remoteSources) {
535
- await processRemoteSource({
536
- source,
537
- seenSkills,
538
- allSkills,
539
- installedSkillsMap,
540
- progress
541
- });
538
+ if (!localOnly) {
539
+ const remoteSources = sources.filter((s) => s.enabled && s.type !== "local").sort((a, b) => b.priority - a.priority);
540
+ for (const source of remoteSources) {
541
+ await processRemoteSource({
542
+ source,
543
+ seenSkills,
544
+ allSkills,
545
+ installedSkillsMap,
546
+ progress
547
+ });
548
+ }
542
549
  }
543
550
  const { byCategory, bySource } = buildRegistrySummary(allSkills);
544
551
  const compiled = {
@@ -555,10 +562,9 @@ async function compileRegistry(showProgress = false) {
555
562
  }
556
563
  function createEmptyManifest() {
557
564
  return {
558
- $schema: REGISTRY_SCHEMA_URL,
559
- name: "looplia-official",
565
+ name: "looplia",
560
566
  homepage: "https://github.com/memorysaver/looplia-core",
561
- version: "0.7.0",
567
+ version: "0.7.1",
562
568
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
563
569
  items: []
564
570
  };
@@ -566,6 +572,10 @@ function createEmptyManifest() {
566
572
 
567
573
  export {
568
574
  createProgress,
575
+ FRONTMATTER_REGEX,
576
+ PROTOCOL_REGEX,
577
+ TRAILING_SLASH_REGEX,
578
+ DEFAULT_MARKETPLACE_SOURCES,
569
579
  getRegistryPath,
570
580
  getCompiledRegistryPath,
571
581
  getSkillCatalogPath,
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bun
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
9
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
10
+ }) : x)(function(x) {
11
+ if (typeof require !== "undefined") return require.apply(this, arguments);
12
+ throw Error('Dynamic require of "' + x + '" is not supported');
13
+ });
14
+ var __esm = (fn, res) => function __init() {
15
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
+ };
17
+ var __commonJS = (cb, mod) => function __require2() {
18
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
19
+ };
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, { get: all[name], enumerable: true });
23
+ };
24
+ var __copyProps = (to, from, except, desc) => {
25
+ if (from && typeof from === "object" || typeof from === "function") {
26
+ for (let key of __getOwnPropNames(from))
27
+ if (!__hasOwnProp.call(to, key) && key !== except)
28
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
29
+ }
30
+ return to;
31
+ };
32
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
33
+ // If the importer is in node compatibility mode or this is not an ESM
34
+ // file that has been converted to a CommonJS file using a Babel-
35
+ // compatible transform (i.e. "__esModule" has not been set), then set
36
+ // "default" to the CommonJS "module.exports" for node compatibility.
37
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
38
+ mod
39
+ ));
40
+
41
+ // ../../node_modules/tsup/assets/esm_shims.js
42
+ import path from "path";
43
+ import { fileURLToPath } from "url";
44
+ var getFilename, getDirname, __dirname;
45
+ var init_esm_shims = __esm({
46
+ "../../node_modules/tsup/assets/esm_shims.js"() {
47
+ "use strict";
48
+ getFilename = () => fileURLToPath(import.meta.url);
49
+ getDirname = () => path.dirname(getFilename());
50
+ __dirname = /* @__PURE__ */ getDirname();
51
+ }
52
+ });
53
+
54
+ export {
55
+ __require,
56
+ __commonJS,
57
+ __export,
58
+ __toESM,
59
+ __dirname,
60
+ init_esm_shims
61
+ };
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env bun
2
+ import "./chunk-APZNHRV3.js";
3
+ import {
4
+ DEFAULT_SETTINGS,
5
+ PRESETS,
6
+ SUMMARIZE_SYSTEM_PROMPT,
7
+ WRITING_KIT_OUTPUT_SCHEMA,
8
+ applyPreset,
9
+ buildSummarizePrompt,
10
+ clearClaudeCodePathCache,
11
+ createClaudeAgentExecutor,
12
+ createQueryLogger,
13
+ ensureWorkspace,
14
+ executeAgenticQueryStreaming,
15
+ executeInteractiveQueryStreaming,
16
+ expandPath,
17
+ extractContentIdFromPrompt,
18
+ findClaudeCodePath,
19
+ getConfigPath,
20
+ getLoopliaHome,
21
+ getPluginPath,
22
+ getSettingsDisplayInfo,
23
+ getWorkspacePath,
24
+ initializeCommandEnvironment,
25
+ injectLoopliaSettingsEnv,
26
+ isClaudeCodeInstalled,
27
+ maskAuthToken,
28
+ readLoopliaSettings,
29
+ readUserProfile,
30
+ removeLoopliaSettings,
31
+ validateConfig,
32
+ writeLoopliaSettings,
33
+ writeUserProfile
34
+ } from "./chunk-OIE7CSW6.js";
35
+ import "./chunk-VRBGWKZ6.js";
36
+ import "./chunk-Y55L47HC.js";
37
+ export {
38
+ DEFAULT_SETTINGS,
39
+ PRESETS,
40
+ SUMMARIZE_SYSTEM_PROMPT,
41
+ WRITING_KIT_OUTPUT_SCHEMA,
42
+ applyPreset,
43
+ buildSummarizePrompt,
44
+ clearClaudeCodePathCache,
45
+ createClaudeAgentExecutor,
46
+ createQueryLogger,
47
+ ensureWorkspace,
48
+ executeAgenticQueryStreaming,
49
+ executeInteractiveQueryStreaming,
50
+ expandPath,
51
+ extractContentIdFromPrompt,
52
+ findClaudeCodePath,
53
+ getConfigPath,
54
+ getLoopliaHome,
55
+ getPluginPath,
56
+ getSettingsDisplayInfo,
57
+ getWorkspacePath,
58
+ initializeCommandEnvironment,
59
+ injectLoopliaSettingsEnv,
60
+ isClaudeCodeInstalled,
61
+ maskAuthToken,
62
+ readLoopliaSettings,
63
+ readUserProfile,
64
+ removeLoopliaSettings,
65
+ validateConfig,
66
+ writeLoopliaSettings,
67
+ writeUserProfile
68
+ };