@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.
@@ -1,298 +1,17 @@
1
1
  #!/usr/bin/env bun
2
2
  import {
3
- __dirname,
3
+ getLoopliaPluginPath,
4
+ getPluginPaths,
5
+ getSelectivePluginPaths
6
+ } from "./chunk-JJCGDGRS.js";
7
+ import {
4
8
  pathExists
5
- } from "./chunk-VRBGWKZ6.js";
9
+ } from "./chunk-326UJHZM.js";
6
10
  import {
7
11
  __export,
8
12
  init_esm_shims
9
13
  } from "./chunk-Y55L47HC.js";
10
14
 
11
- // ../../packages/provider/dist/chunk-5BLYIGE4.js
12
- init_esm_shims();
13
- import { createHash } from "crypto";
14
- import {
15
- cp,
16
- mkdir as mkdir2,
17
- readdir as readdir2,
18
- readFile,
19
- realpath,
20
- rm,
21
- writeFile
22
- } from "fs/promises";
23
- import { homedir as homedir2, tmpdir } from "os";
24
- import { dirname, join as join2 } from "path";
25
- import { fileURLToPath } from "url";
26
- import { exec } from "child_process";
27
- import { mkdir, readdir } from "fs/promises";
28
- import { join } from "path";
29
- import { promisify } from "util";
30
- var execAsync = promisify(exec);
31
- var CORE_SKILLS = [
32
- "workflow-executor",
33
- "workflow-validator",
34
- "registry-loader"
35
- ];
36
- async function buildSkillPluginMap(pluginPaths) {
37
- const map = /* @__PURE__ */ new Map();
38
- for (const { path: pluginPath } of pluginPaths) {
39
- const skillsDir = join(pluginPath, "skills");
40
- if (!await pathExists(skillsDir)) {
41
- continue;
42
- }
43
- try {
44
- const entries = await readdir(skillsDir, { withFileTypes: true });
45
- for (const entry of entries) {
46
- if (entry.isDirectory()) {
47
- map.set(entry.name, pluginPath);
48
- }
49
- }
50
- } catch {
51
- }
52
- }
53
- return map;
54
- }
55
- async function getSelectivePluginPaths(requiredSkills) {
56
- const allPluginPaths = await getPluginPaths();
57
- if (!requiredSkills || requiredSkills.length === 0) {
58
- return allPluginPaths;
59
- }
60
- const neededSkills = /* @__PURE__ */ new Set([...CORE_SKILLS, ...requiredSkills]);
61
- const skillToPlugin = await buildSkillPluginMap(allPluginPaths);
62
- const pluginsToLoad = /* @__PURE__ */ new Set();
63
- for (const skill of neededSkills) {
64
- const pluginPath = skillToPlugin.get(skill);
65
- if (pluginPath) {
66
- pluginsToLoad.add(pluginPath);
67
- }
68
- }
69
- return allPluginPaths.filter((p) => pluginsToLoad.has(p.path));
70
- }
71
- function isCoreSkill(skillName) {
72
- return CORE_SKILLS.includes(skillName);
73
- }
74
- async function computeSha256(filePath) {
75
- const content = await readFile(filePath);
76
- return createHash("sha256").update(content).digest("hex");
77
- }
78
- async function validateExtractedPaths(baseDir) {
79
- const realBase = await realpath(baseDir);
80
- const entries = await readdir2(baseDir, { withFileTypes: true });
81
- for (const entry of entries) {
82
- const fullPath = join2(baseDir, entry.name);
83
- const entryRealPath = await realpath(fullPath);
84
- if (!entryRealPath.startsWith(realBase)) {
85
- throw new Error(
86
- `Security: Path traversal detected in extracted file: ${entry.name}`
87
- );
88
- }
89
- if (entry.isDirectory()) {
90
- await validateExtractedPaths(fullPath);
91
- }
92
- }
93
- }
94
- function getLoopliaPluginPath() {
95
- return process.env.LOOPLIA_HOME ?? join2(homedir2(), ".looplia");
96
- }
97
- function getBundledPluginsPath() {
98
- const currentFile = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
99
- return join2(currentFile, "..", "..", "plugins");
100
- }
101
- async function parseMarketplace(marketplacePath) {
102
- const content = await readFile(marketplacePath, "utf-8");
103
- return JSON.parse(content);
104
- }
105
- async function getPluginNamesFromSource(bundledPath) {
106
- const marketplacePath = join2(
107
- bundledPath,
108
- "..",
109
- ".claude-plugin",
110
- "marketplace.json"
111
- );
112
- if (await pathExists(marketplacePath)) {
113
- const marketplace = await parseMarketplace(marketplacePath);
114
- return marketplace.plugins.map((p) => {
115
- const parts = p.source.split("/");
116
- return parts.at(-1);
117
- }).filter((name) => name !== void 0);
118
- }
119
- const entries = await readdir2(bundledPath, { withFileTypes: true });
120
- return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
121
- }
122
- function createDefaultProfile() {
123
- return {
124
- userId: "default",
125
- topics: [],
126
- style: {
127
- tone: "intermediate",
128
- targetWordCount: 1e3,
129
- voice: "first-person"
130
- }
131
- };
132
- }
133
- async function extractWorkflows(targetDir, pluginNames) {
134
- const workflowsDir = join2(targetDir, "workflows");
135
- await mkdir2(workflowsDir, { recursive: true });
136
- for (const pluginName of pluginNames) {
137
- const pluginWorkflowsPath = join2(targetDir, pluginName, "workflows");
138
- if (!await pathExists(pluginWorkflowsPath)) {
139
- continue;
140
- }
141
- const entries = await readdir2(pluginWorkflowsPath, { withFileTypes: true });
142
- for (const entry of entries) {
143
- if (entry.isFile() && entry.name.endsWith(".md")) {
144
- await cp(
145
- join2(pluginWorkflowsPath, entry.name),
146
- join2(workflowsDir, entry.name)
147
- );
148
- }
149
- }
150
- await rm(pluginWorkflowsPath, { recursive: true, force: true });
151
- }
152
- }
153
- async function copyPlugins(targetDir, sourcePath) {
154
- const bundledPath = sourcePath ?? getBundledPluginsPath();
155
- const pluginNames = await getPluginNamesFromSource(bundledPath);
156
- if (pluginNames.length === 0) {
157
- throw new Error(`No plugins found at ${bundledPath}`);
158
- }
159
- if (await pathExists(targetDir)) {
160
- await rm(targetDir, { recursive: true, force: true });
161
- }
162
- await mkdir2(targetDir, { recursive: true });
163
- for (const pluginName of pluginNames) {
164
- const pluginPath = join2(bundledPath, pluginName);
165
- if (await pathExists(pluginPath)) {
166
- await cp(pluginPath, join2(targetDir, pluginName), { recursive: true });
167
- }
168
- }
169
- await extractWorkflows(targetDir, pluginNames);
170
- await mkdir2(join2(targetDir, "sandbox"), { recursive: true });
171
- await writeFile(
172
- join2(targetDir, "user-profile.json"),
173
- JSON.stringify(createDefaultProfile(), null, 2),
174
- "utf-8"
175
- );
176
- const { initializeRegistry, compileRegistry } = await import("./compiler-4B63UTUP-VE77VSJ2.js");
177
- await initializeRegistry();
178
- const { syncRegistrySources } = await import("./sync-E5PGFGNI-IGGJR7IL.js");
179
- const syncResults = await syncRegistrySources({ showProgress: true });
180
- for (const result of syncResults) {
181
- if (result.status === "failed") {
182
- console.warn(
183
- `Warning: Failed to sync ${result.source.id}: ${result.error}`
184
- );
185
- }
186
- }
187
- await compileRegistry();
188
- }
189
- async function downloadRemotePlugins(version2, targetDir) {
190
- const releaseUrl = version2 === "latest" ? "https://github.com/memorysaver/looplia-core/releases/latest/download/plugins.tar.gz" : `https://github.com/memorysaver/looplia-core/releases/download/${version2}/plugins.tar.gz`;
191
- console.log(`Downloading looplia plugins from ${releaseUrl}...`);
192
- const tempDir = join2(tmpdir(), `looplia-download-${Date.now()}`);
193
- await mkdir2(tempDir, { recursive: true });
194
- try {
195
- const response = await fetch(releaseUrl);
196
- if (!response.ok) {
197
- throw new Error(
198
- `Failed to download plugins: ${response.status} ${response.statusText}`
199
- );
200
- }
201
- const tarPath = join2(tempDir, "plugins.tar.gz");
202
- await writeFile(tarPath, Buffer.from(await response.arrayBuffer()));
203
- const checksumUrl = `${releaseUrl}.sha256`;
204
- const checksumResponse = await fetch(checksumUrl);
205
- if (checksumResponse.ok) {
206
- const checksumText = await checksumResponse.text();
207
- const checksumParts = checksumText.split(" ");
208
- const expectedChecksum = checksumParts[0]?.trim();
209
- if (!expectedChecksum) {
210
- throw new Error("Invalid checksum file format");
211
- }
212
- const actualChecksum = await computeSha256(tarPath);
213
- if (actualChecksum !== expectedChecksum) {
214
- throw new Error(
215
- `Checksum verification failed. Expected: ${expectedChecksum}, Got: ${actualChecksum}`
216
- );
217
- }
218
- console.log("\u2713 Checksum verified");
219
- } else {
220
- console.log(
221
- "\u26A0 Checksum file not available (older release), skipping verification"
222
- );
223
- }
224
- const { exec: exec2 } = await import("child_process");
225
- const { promisify: promisify2 } = await import("util");
226
- const execAsync2 = promisify2(exec2);
227
- try {
228
- await execAsync2("tar -xzf plugins.tar.gz", { cwd: tempDir });
229
- } catch (error2) {
230
- const errorMessage = error2 instanceof Error ? error2.message : String(error2);
231
- throw new Error(
232
- `Failed to extract plugins tarball. Ensure 'tar' is available. Error: ${errorMessage}`
233
- );
234
- }
235
- await rm(tarPath);
236
- await validateExtractedPaths(tempDir);
237
- await copyPlugins(targetDir, tempDir);
238
- console.log(`Plugins downloaded and extracted to ${targetDir}`);
239
- } finally {
240
- await rm(tempDir, { recursive: true, force: true }).catch(() => {
241
- });
242
- }
243
- }
244
- async function isLoopliaInitialized() {
245
- const pluginPath = getLoopliaPluginPath();
246
- try {
247
- const entries = await readdir2(pluginPath, { withFileTypes: true });
248
- return entries.some(
249
- (e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "sandbox" && e.name !== "workflows"
250
- );
251
- } catch {
252
- return false;
253
- }
254
- }
255
- function getDevPluginPaths(projectRoot) {
256
- return [
257
- { type: "local", path: join2(projectRoot, "plugins", "looplia-core") },
258
- { type: "local", path: join2(projectRoot, "plugins", "looplia-writer") }
259
- ];
260
- }
261
- async function getProdPluginPaths() {
262
- const loopliaPath = getLoopliaPluginPath();
263
- const results = [];
264
- try {
265
- const entries = await readdir2(loopliaPath, { withFileTypes: true });
266
- const pluginDirs = entries.filter(
267
- (e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "sandbox" && e.name !== "workflows" && e.name !== "plugins" && e.name !== "registry"
268
- ).map((e) => e.name);
269
- for (const name of pluginDirs) {
270
- results.push({ type: "local", path: join2(loopliaPath, name) });
271
- }
272
- } catch {
273
- }
274
- const pluginsDir = join2(loopliaPath, "plugins");
275
- try {
276
- const entries = await readdir2(pluginsDir, { withFileTypes: true });
277
- const thirdPartyDirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
278
- for (const name of thirdPartyDirs) {
279
- results.push({ type: "local", path: join2(pluginsDir, name) });
280
- }
281
- } catch {
282
- }
283
- return results;
284
- }
285
- async function getPluginPaths() {
286
- if (process.env.LOOPLIA_HOME) {
287
- return await getProdPluginPaths();
288
- }
289
- if (process.env.LOOPLIA_DEV === "true") {
290
- const devRoot = process.env.LOOPLIA_DEV_ROOT ?? process.cwd();
291
- return getDevPluginPaths(devRoot);
292
- }
293
- return await getProdPluginPaths();
294
- }
295
-
296
15
  // ../../packages/core/dist/index.js
297
16
  init_esm_shims();
298
17
 
@@ -5036,23 +4755,23 @@ function validateUserProfile(data) {
5036
4755
  return { success: false, error: { message: result.error.message } };
5037
4756
  }
5038
4757
 
5039
- // ../../packages/provider/dist/chunk-W4MDOBYT.js
4758
+ // ../../packages/provider/dist/chunk-LJ75DZPB.js
5040
4759
  init_esm_shims();
5041
4760
  import { execSync } from "child_process";
5042
4761
  import { existsSync as existsSync3 } from "fs";
5043
4762
  import { createRequire } from "module";
5044
- import { homedir as homedir3 } from "os";
5045
- import { dirname as dirname3, join as join4 } from "path";
4763
+ import { homedir as homedir2 } from "os";
4764
+ import { dirname as dirname2, join as join4 } from "path";
5046
4765
  import {
5047
4766
  chmod,
5048
- mkdir as mkdir3,
5049
- readFile as readFile2,
4767
+ mkdir,
4768
+ readFile,
5050
4769
  rename,
5051
- rm as rm2,
5052
- writeFile as writeFile2
4770
+ rm,
4771
+ writeFile
5053
4772
  } from "fs/promises";
5054
4773
  import { homedir as homedir22 } from "os";
5055
- import { join as join23 } from "path";
4774
+ import { join as join22 } from "path";
5056
4775
 
5057
4776
  // ../../node_modules/zod-to-json-schema/dist/esm/index.js
5058
4777
  init_esm_shims();
@@ -6391,7 +6110,7 @@ var zodToJsonSchema = (schema, options) => {
6391
6110
  return combined;
6392
6111
  };
6393
6112
 
6394
- // ../../packages/provider/dist/chunk-W4MDOBYT.js
6113
+ // ../../packages/provider/dist/chunk-LJ75DZPB.js
6395
6114
  import { join as join6 } from "path";
6396
6115
 
6397
6116
  // ../../node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
@@ -6403,15 +6122,15 @@ import { spawn } from "child_process";
6403
6122
  import { createInterface } from "readline";
6404
6123
  import * as fs from "fs";
6405
6124
  import { stat as statPromise, open } from "fs/promises";
6406
- import { join as join3 } from "path";
6125
+ import { join } from "path";
6407
6126
  import { homedir } from "os";
6408
- import { dirname as dirname2, join as join22 } from "path";
6127
+ import { dirname, join as join2 } from "path";
6409
6128
  import { cwd } from "process";
6410
6129
  import { realpathSync as realpathSync2 } from "fs";
6411
6130
  import { randomUUID } from "crypto";
6412
6131
  import { randomUUID as randomUUID2 } from "crypto";
6413
6132
  import { appendFileSync as appendFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
6414
- import { join as join32 } from "path";
6133
+ import { join as join3 } from "path";
6415
6134
  import { randomUUID as randomUUID3 } from "crypto";
6416
6135
  var __create = Object.create;
6417
6136
  var __getProtoOf = Object.getPrototypeOf;
@@ -13105,7 +12824,7 @@ function shouldShowDebugMessage(message, filter) {
13105
12824
  return shouldShowDebugCategories(categories, filter);
13106
12825
  }
13107
12826
  function getClaudeConfigHomeDir() {
13108
- return process.env.CLAUDE_CONFIG_DIR ?? join3(homedir(), ".claude");
12827
+ return process.env.CLAUDE_CONFIG_DIR ?? join(homedir(), ".claude");
13109
12828
  }
13110
12829
  function isEnvTruthy(envVar) {
13111
12830
  if (!envVar)
@@ -13377,8 +13096,8 @@ function getDebugWriter() {
13377
13096
  debugWriter = createBufferedWriter({
13378
13097
  writeFn: (content) => {
13379
13098
  const path = getDebugLogPath();
13380
- if (!getFsImplementation().existsSync(dirname2(path))) {
13381
- getFsImplementation().mkdirSync(dirname2(path));
13099
+ if (!getFsImplementation().existsSync(dirname(path))) {
13100
+ getFsImplementation().mkdirSync(dirname(path));
13382
13101
  }
13383
13102
  getFsImplementation().appendFileSync(path, content);
13384
13103
  updateLatestDebugLogSymlink();
@@ -13411,7 +13130,7 @@ function logForDebugging(message, { level } = {
13411
13130
  getDebugWriter().write(output);
13412
13131
  }
13413
13132
  function getDebugLogPath() {
13414
- return process.env.CLAUDE_CODE_DEBUG_LOGS_DIR ?? join22(getClaudeConfigHomeDir(), "debug", `${getSessionId()}.txt`);
13133
+ return process.env.CLAUDE_CODE_DEBUG_LOGS_DIR ?? join2(getClaudeConfigHomeDir(), "debug", `${getSessionId()}.txt`);
13415
13134
  }
13416
13135
  var updateLatestDebugLogSymlink = memoize_default(() => {
13417
13136
  if (process.argv[2] === "--ripgrep") {
@@ -13419,8 +13138,8 @@ var updateLatestDebugLogSymlink = memoize_default(() => {
13419
13138
  }
13420
13139
  try {
13421
13140
  const debugLogPath = getDebugLogPath();
13422
- const debugLogsDir = dirname2(debugLogPath);
13423
- const latestSymlinkPath = join22(debugLogsDir, "latest");
13141
+ const debugLogsDir = dirname(debugLogPath);
13142
+ const latestSymlinkPath = join2(debugLogsDir, "latest");
13424
13143
  if (!getFsImplementation().existsSync(debugLogsDir)) {
13425
13144
  getFsImplementation().mkdirSync(debugLogsDir);
13426
13145
  }
@@ -13571,8 +13290,8 @@ function getOrCreateDebugFile() {
13571
13290
  if (!process.env.DEBUG_CLAUDE_AGENT_SDK) {
13572
13291
  return null;
13573
13292
  }
13574
- const debugDir = join32(getClaudeConfigHomeDir(), "debug");
13575
- debugFilePath = join32(debugDir, `sdk-${randomUUID2()}.txt`);
13293
+ const debugDir = join3(getClaudeConfigHomeDir(), "debug");
13294
+ debugFilePath = join3(debugDir, `sdk-${randomUUID2()}.txt`);
13576
13295
  if (!existsSync2(debugDir)) {
13577
13296
  mkdirSync2(debugDir, { recursive: true });
13578
13297
  }
@@ -22929,19 +22648,20 @@ function query({
22929
22648
  return queryInstance;
22930
22649
  }
22931
22650
 
22932
- // ../../packages/provider/dist/chunk-W4MDOBYT.js
22651
+ // ../../packages/provider/dist/chunk-LJ75DZPB.js
22933
22652
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync3, writeFileSync } from "fs";
22934
- import { join as join33 } from "path";
22935
- import { access, readdir as readdir3, readFile as readFile22, stat } from "fs/promises";
22653
+ import { join as join32 } from "path";
22654
+ import { access, readdir, readFile as readFile2, stat } from "fs/promises";
22936
22655
  import { join as join42 } from "path";
22937
- import { cp as cp2, mkdir as mkdir22, readFile as readFile3, rm as rm22, writeFile as writeFile22 } from "fs/promises";
22938
- import { homedir as homedir32 } from "os";
22656
+ import { cp, mkdir as mkdir2, readFile as readFile3, rm as rm2, writeFile as writeFile2 } from "fs/promises";
22657
+ import { homedir as homedir3 } from "os";
22939
22658
  import { isAbsolute, join as join52, normalize, resolve } from "path";
22940
- import { readdir as readdir22, readFile as readFile4, rename as rename2, stat as stat2, writeFile as writeFile3 } from "fs/promises";
22659
+ import { homedir as homedir4 } from "os";
22660
+ import { readdir as readdir2, readFile as readFile4, rename as rename2, stat as stat2, writeFile as writeFile3 } from "fs/promises";
22941
22661
  import { join as join7 } from "path";
22942
22662
  import {
22943
22663
  open as open2,
22944
- readdir as readdir32,
22664
+ readdir as readdir3,
22945
22665
  readFile as readFile5,
22946
22666
  rename as rename3,
22947
22667
  stat as stat3,
@@ -22957,7 +22677,7 @@ function findSdkBundledCliPath() {
22957
22677
  const sdkPackagePath = require2.resolve(
22958
22678
  "@anthropic-ai/claude-agent-sdk/package.json"
22959
22679
  );
22960
- const sdkDir = dirname3(sdkPackagePath);
22680
+ const sdkDir = dirname2(sdkPackagePath);
22961
22681
  const cliPath = join4(sdkDir, "cli.js");
22962
22682
  if (existsSync3(cliPath)) {
22963
22683
  return cliPath;
@@ -22968,13 +22688,13 @@ function findSdkBundledCliPath() {
22968
22688
  }
22969
22689
  var CLAUDE_CODE_PATHS = [
22970
22690
  // User's local bin (npm global install location)
22971
- join4(homedir3(), ".local", "bin", "claude"),
22691
+ join4(homedir2(), ".local", "bin", "claude"),
22972
22692
  // System-wide installations
22973
22693
  "/usr/local/bin/claude",
22974
22694
  // macOS Homebrew
22975
22695
  "/opt/homebrew/bin/claude",
22976
22696
  // Windows (if applicable)
22977
- join4(homedir3(), "AppData", "Local", "Programs", "claude", "claude.exe")
22697
+ join4(homedir2(), "AppData", "Local", "Programs", "claude", "claude.exe")
22978
22698
  ];
22979
22699
  var cachedClaudeCodePath;
22980
22700
  function findClaudeCodePath() {
@@ -23276,15 +22996,15 @@ var PRESETS = {
23276
22996
  };
23277
22997
  var CONFIG_FILE = "looplia.setting.json";
23278
22998
  function getLoopliaHome() {
23279
- return join23(homedir22(), ".looplia");
22999
+ return join22(homedir22(), ".looplia");
23280
23000
  }
23281
23001
  function getConfigPath() {
23282
- return join23(getLoopliaHome(), CONFIG_FILE);
23002
+ return join22(getLoopliaHome(), CONFIG_FILE);
23283
23003
  }
23284
23004
  async function readLoopliaSettings() {
23285
23005
  const configPath = getConfigPath();
23286
23006
  try {
23287
- const content = await readFile2(configPath, "utf-8");
23007
+ const content = await readFile(configPath, "utf-8");
23288
23008
  return JSON.parse(content);
23289
23009
  } catch (error2) {
23290
23010
  if (error2.code === "ENOENT") {
@@ -23292,7 +23012,7 @@ async function readLoopliaSettings() {
23292
23012
  }
23293
23013
  if (error2 instanceof SyntaxError) {
23294
23014
  const backupPath = `${configPath}.corrupted`;
23295
- await rm2(backupPath, { force: true });
23015
+ await rm(backupPath, { force: true });
23296
23016
  await rename(configPath, backupPath);
23297
23017
  console.warn(
23298
23018
  `Config file corrupted, backed up to ${backupPath}. Using defaults.`
@@ -23304,12 +23024,12 @@ async function readLoopliaSettings() {
23304
23024
  }
23305
23025
  async function writeLoopliaSettings(settings) {
23306
23026
  const configPath = getConfigPath();
23307
- await mkdir3(getLoopliaHome(), { recursive: true });
23308
- await writeFile2(configPath, JSON.stringify(settings, null, 2), "utf-8");
23027
+ await mkdir(getLoopliaHome(), { recursive: true });
23028
+ await writeFile(configPath, JSON.stringify(settings, null, 2), "utf-8");
23309
23029
  await chmod(configPath, 384);
23310
23030
  }
23311
23031
  async function removeLoopliaSettings() {
23312
- await rm2(getConfigPath(), { force: true });
23032
+ await rm(getConfigPath(), { force: true });
23313
23033
  }
23314
23034
  function setEnvIfNotSet(key, value) {
23315
23035
  if (!process.env[key]) {
@@ -23486,10 +23206,10 @@ function createQueryLogger(workspace) {
23486
23206
  let logPath = null;
23487
23207
  return {
23488
23208
  init(sandboxId) {
23489
- const logsDir = join33(workspace, "sandbox", sandboxId, "logs");
23209
+ const logsDir = join32(workspace, "sandbox", sandboxId, "logs");
23490
23210
  mkdirSync3(logsDir, { recursive: true });
23491
23211
  const filename = generateLogFilename();
23492
- logPath = join33(logsDir, filename);
23212
+ logPath = join32(logsDir, filename);
23493
23213
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
23494
23214
  writeFileSync(
23495
23215
  logPath,
@@ -23653,7 +23373,7 @@ function validationError(field, message) {
23653
23373
  }
23654
23374
  async function findMostRecentSandbox(sandboxRoot) {
23655
23375
  try {
23656
- const entries = await readdir3(sandboxRoot, { withFileTypes: true });
23376
+ const entries = await readdir(sandboxRoot, { withFileTypes: true });
23657
23377
  const dirs = entries.filter(
23658
23378
  (e) => e.isDirectory() && !e.name.startsWith(".")
23659
23379
  );
@@ -23720,7 +23440,7 @@ async function readValidationManifest(sandboxDir) {
23720
23440
  continue;
23721
23441
  }
23722
23442
  try {
23723
- const content = await readFile22(validationPath, "utf-8");
23443
+ const content = await readFile2(validationPath, "utf-8");
23724
23444
  const parsed = JSON.parse(content);
23725
23445
  if (!isValidationManifest(parsed)) {
23726
23446
  return { error: "Invalid validation manifest structure" };
@@ -23736,7 +23456,7 @@ async function readValidationManifest(sandboxDir) {
23736
23456
  async function readFinalArtifact(sandboxDir, outputPath) {
23737
23457
  const artifactPath = join42(sandboxDir, outputPath);
23738
23458
  try {
23739
- const content = await readFile22(artifactPath, "utf-8");
23459
+ const content = await readFile2(artifactPath, "utf-8");
23740
23460
  return { artifact: JSON.parse(content) };
23741
23461
  } catch (error2) {
23742
23462
  const errorMessage = `Failed to read final artifact from ${outputPath}: ${error2 instanceof Error ? error2.message : String(error2)}`;
@@ -23820,7 +23540,7 @@ async function extractSandboxResult(options) {
23820
23540
  }
23821
23541
  function expandPath(path) {
23822
23542
  if (path.startsWith("~/") || path === "~") {
23823
- const home = homedir32();
23543
+ const home = homedir3();
23824
23544
  if (!home) {
23825
23545
  throw new Error("Unable to determine home directory");
23826
23546
  }
@@ -23861,7 +23581,7 @@ async function checkRequiredFiles(workspaceDir) {
23861
23581
  }
23862
23582
  return true;
23863
23583
  }
23864
- function createDefaultProfile2() {
23584
+ function createDefaultProfile() {
23865
23585
  return {
23866
23586
  userId: "default",
23867
23587
  topics: [],
@@ -23878,104 +23598,104 @@ async function createTestWorkspace(workspaceDir, force) {
23878
23598
  return;
23879
23599
  }
23880
23600
  if (workspaceExists) {
23881
- await rm22(workspaceDir, { recursive: true, force: true });
23601
+ await rm2(workspaceDir, { recursive: true, force: true });
23882
23602
  }
23883
- await mkdir22(workspaceDir, { recursive: true });
23884
- await mkdir22(join52(workspaceDir, ".claude", "agents"), { recursive: true });
23885
- await mkdir22(join52(workspaceDir, ".claude", "skills"), { recursive: true });
23886
- await mkdir22(join52(workspaceDir, "sandbox"), { recursive: true });
23603
+ await mkdir2(workspaceDir, { recursive: true });
23604
+ await mkdir2(join52(workspaceDir, ".claude", "agents"), { recursive: true });
23605
+ await mkdir2(join52(workspaceDir, ".claude", "skills"), { recursive: true });
23606
+ await mkdir2(join52(workspaceDir, "sandbox"), { recursive: true });
23887
23607
  const plugins = getPluginPaths2();
23888
23608
  const writerWorkflowsDir = join52(plugins.writer, "workflows");
23889
23609
  if (await pathExists(writerWorkflowsDir)) {
23890
- await cp2(writerWorkflowsDir, join52(workspaceDir, "workflows"), {
23610
+ await cp(writerWorkflowsDir, join52(workspaceDir, "workflows"), {
23891
23611
  recursive: true
23892
23612
  });
23893
23613
  } else {
23894
- await mkdir22(join52(workspaceDir, "workflows"), { recursive: true });
23614
+ await mkdir2(join52(workspaceDir, "workflows"), { recursive: true });
23895
23615
  }
23896
23616
  const coreValidatorDir = join52(plugins.core, "skills", "workflow-validator");
23897
23617
  if (await pathExists(coreValidatorDir)) {
23898
- await cp2(
23618
+ await cp(
23899
23619
  coreValidatorDir,
23900
23620
  join52(workspaceDir, ".claude", "skills", "workflow-validator"),
23901
23621
  { recursive: true }
23902
23622
  );
23903
23623
  }
23904
- await writeFile22(
23624
+ await writeFile2(
23905
23625
  join52(workspaceDir, "CLAUDE.md"),
23906
23626
  "# Test Workspace\n",
23907
23627
  "utf-8"
23908
23628
  );
23909
- await writeFile22(
23629
+ await writeFile2(
23910
23630
  join52(workspaceDir, "user-profile.json"),
23911
- JSON.stringify(createDefaultProfile2(), null, 2),
23631
+ JSON.stringify(createDefaultProfile(), null, 2),
23912
23632
  "utf-8"
23913
23633
  );
23914
23634
  }
23915
23635
  async function bootstrapFromPlugins(workspaceDir, plugins) {
23916
23636
  const workspaceExists = await pathExists(workspaceDir);
23917
23637
  if (workspaceExists) {
23918
- await rm22(workspaceDir, { recursive: true, force: true });
23638
+ await rm2(workspaceDir, { recursive: true, force: true });
23919
23639
  }
23920
- await mkdir22(workspaceDir, { recursive: true });
23921
- await mkdir22(join52(workspaceDir, ".claude"), { recursive: true });
23922
- await mkdir22(join52(workspaceDir, "sandbox"), { recursive: true });
23640
+ await mkdir2(workspaceDir, { recursive: true });
23641
+ await mkdir2(join52(workspaceDir, ".claude"), { recursive: true });
23642
+ await mkdir2(join52(workspaceDir, "sandbox"), { recursive: true });
23923
23643
  const coreCommandsDir = join52(plugins.core, "commands");
23924
23644
  if (await pathExists(coreCommandsDir)) {
23925
- await cp2(coreCommandsDir, join52(workspaceDir, ".claude", "commands"), {
23645
+ await cp(coreCommandsDir, join52(workspaceDir, ".claude", "commands"), {
23926
23646
  recursive: true
23927
23647
  });
23928
23648
  }
23929
23649
  const coreSkillsDir = join52(plugins.core, "skills");
23930
23650
  if (await pathExists(coreSkillsDir)) {
23931
- await cp2(coreSkillsDir, join52(workspaceDir, ".claude", "skills"), {
23651
+ await cp(coreSkillsDir, join52(workspaceDir, ".claude", "skills"), {
23932
23652
  recursive: true
23933
23653
  });
23934
23654
  }
23935
23655
  const coreHooksDir = join52(plugins.core, "hooks");
23936
23656
  if (await pathExists(coreHooksDir)) {
23937
- await cp2(coreHooksDir, join52(workspaceDir, ".claude", "hooks"), {
23657
+ await cp(coreHooksDir, join52(workspaceDir, ".claude", "hooks"), {
23938
23658
  recursive: true
23939
23659
  });
23940
23660
  }
23941
23661
  const coreAgentsDir = join52(plugins.core, "agents");
23942
23662
  if (await pathExists(coreAgentsDir)) {
23943
- await mkdir22(join52(workspaceDir, ".claude", "agents"), { recursive: true });
23944
- await cp2(coreAgentsDir, join52(workspaceDir, ".claude", "agents"), {
23663
+ await mkdir2(join52(workspaceDir, ".claude", "agents"), { recursive: true });
23664
+ await cp(coreAgentsDir, join52(workspaceDir, ".claude", "agents"), {
23945
23665
  recursive: true
23946
23666
  });
23947
23667
  }
23948
23668
  const coreScriptsDir = join52(plugins.core, "scripts");
23949
23669
  if (await pathExists(coreScriptsDir)) {
23950
- await cp2(coreScriptsDir, join52(workspaceDir, "scripts"), {
23670
+ await cp(coreScriptsDir, join52(workspaceDir, "scripts"), {
23951
23671
  recursive: true
23952
23672
  });
23953
23673
  }
23954
23674
  const coreClaudeMd = join52(plugins.core, "CLAUDE.md");
23955
23675
  if (await pathExists(coreClaudeMd)) {
23956
- await cp2(coreClaudeMd, join52(workspaceDir, "CLAUDE.md"));
23676
+ await cp(coreClaudeMd, join52(workspaceDir, "CLAUDE.md"));
23957
23677
  }
23958
23678
  const writerAgentsDir = join52(plugins.writer, "agents");
23959
23679
  if (await pathExists(writerAgentsDir)) {
23960
- await cp2(writerAgentsDir, join52(workspaceDir, ".claude", "agents"), {
23680
+ await cp(writerAgentsDir, join52(workspaceDir, ".claude", "agents"), {
23961
23681
  recursive: true
23962
23682
  });
23963
23683
  }
23964
23684
  const writerSkillsDir = join52(plugins.writer, "skills");
23965
23685
  if (await pathExists(writerSkillsDir)) {
23966
- await cp2(writerSkillsDir, join52(workspaceDir, ".claude", "skills"), {
23686
+ await cp(writerSkillsDir, join52(workspaceDir, ".claude", "skills"), {
23967
23687
  recursive: true
23968
23688
  });
23969
23689
  }
23970
23690
  const writerWorkflowsDir = join52(plugins.writer, "workflows");
23971
23691
  if (await pathExists(writerWorkflowsDir)) {
23972
- await cp2(writerWorkflowsDir, join52(workspaceDir, "workflows"), {
23692
+ await cp(writerWorkflowsDir, join52(workspaceDir, "workflows"), {
23973
23693
  recursive: true
23974
23694
  });
23975
23695
  }
23976
- await writeFile22(
23696
+ await writeFile2(
23977
23697
  join52(workspaceDir, "user-profile.json"),
23978
- JSON.stringify(createDefaultProfile2(), null, 2),
23698
+ JSON.stringify(createDefaultProfile(), null, 2),
23979
23699
  "utf-8"
23980
23700
  );
23981
23701
  }
@@ -24018,7 +23738,7 @@ async function readUserProfile(workspaceDir) {
24018
23738
  }
24019
23739
  async function writeUserProfile(workspaceDir, profile) {
24020
23740
  const profilePath = join52(workspaceDir, "user-profile.json");
24021
- await writeFile22(profilePath, JSON.stringify(profile, null, 2), "utf-8");
23741
+ await writeFile2(profilePath, JSON.stringify(profile, null, 2), "utf-8");
24022
23742
  }
24023
23743
  var workspaceCache = /* @__PURE__ */ new Map();
24024
23744
  async function getOrInitWorkspace(baseDir, useFilesystemExtensions) {
@@ -24089,8 +23809,13 @@ function* processEvent(event, progressTracker, context) {
24089
23809
  return buildFinalResult(event, context.sessionId);
24090
23810
  }
24091
23811
  }
24092
- var loopliaSystemPrompt = `
24093
- # Looplia Workflow Engine (v0.7.1)
23812
+ function getDefaultWorkspace() {
23813
+ return process.env.LOOPLIA_HOME ?? `${homedir4()}/.looplia`;
23814
+ }
23815
+ function getLoopliaSystemPrompt(workspace) {
23816
+ const ws = workspace ?? getDefaultWorkspace();
23817
+ return `
23818
+ # Looplia Workflow Engine (v0.8.0)
24094
23819
 
24095
23820
  You are a looplia workflow engine. Execute workflows by delegating to skills.
24096
23821
 
@@ -24153,7 +23878,7 @@ Save generated workflow to \`workflows/{name}.md\`.
24153
23878
  ## Workspace Structure
24154
23879
 
24155
23880
  \`\`\`
24156
- ~/.looplia/ # Looplia plugin root
23881
+ ${ws}/ # Looplia plugin root
24157
23882
  \u251C\u2500\u2500 .claude-plugin/
24158
23883
  \u2502 \u2514\u2500\u2500 plugin.json # Plugin manifest
24159
23884
  \u251C\u2500\u2500 commands/ # /looplia:run, /looplia:build, etc.
@@ -24175,13 +23900,13 @@ Save generated workflow to \`workflows/{name}.md\`.
24175
23900
 
24176
23901
  ## Path Resolution
24177
23902
 
24178
- All relative paths resolve from \`~/.looplia\` (the SDK working directory):
23903
+ All relative paths resolve from \`${ws}\` (the SDK working directory):
24179
23904
 
24180
23905
  | Path Type | Example | Resolves To |
24181
23906
  |-----------|---------|-------------|
24182
- | Workflows | \`workflows/writing-kit.md\` | \`~/.looplia/workflows/writing-kit.md\` |
24183
- | Sandbox | \`sandbox/{id}/validation.json\` | \`~/.looplia/sandbox/{id}/validation.json\` |
24184
- | Outputs | \`sandbox/{id}/outputs/\` | \`~/.looplia/sandbox/{id}/outputs/\` |
23907
+ | Workflows | \`workflows/writing-kit.md\` | \`${ws}/workflows/writing-kit.md\` |
23908
+ | Sandbox | \`sandbox/{id}/validation.json\` | \`${ws}/sandbox/{id}/validation.json\` |
23909
+ | Outputs | \`sandbox/{id}/outputs/\` | \`${ws}/sandbox/{id}/outputs/\` |
24185
23910
 
24186
23911
  **User files** (from \`--file\` argument): Resolve against the **User Working Directory** provided in the User Context section below.
24187
23912
 
@@ -24209,6 +23934,8 @@ All relative paths resolve from \`~/.looplia\` (the SDK working directory):
24209
23934
 
24210
23935
  For implementation details, see the SKILL.md files in \`skills/\`.
24211
23936
  `;
23937
+ }
23938
+ var loopliaSystemPrompt = getLoopliaSystemPrompt();
24212
23939
  var SKILL_TO_STEP = {
24213
23940
  "content-analyzer": "analyzing",
24214
23941
  "idea-generator": "generating_ideas",
@@ -24578,7 +24305,7 @@ async function* executeAgenticQueryStreaming(prompt, _jsonSchema, config2) {
24578
24305
  systemPrompt: {
24579
24306
  type: "preset",
24580
24307
  preset: "claude_code",
24581
- append: `${loopliaSystemPrompt}
24308
+ append: `${getLoopliaSystemPrompt(loopliaHome)}
24582
24309
 
24583
24310
  ## User Context
24584
24311
 
@@ -24791,7 +24518,7 @@ function resolveSandboxRoot(context) {
24791
24518
  }
24792
24519
  async function findMostRecentBuildSandbox(sandboxRoot) {
24793
24520
  try {
24794
- const entries = await readdir22(sandboxRoot, { withFileTypes: true });
24521
+ const entries = await readdir2(sandboxRoot, { withFileTypes: true });
24795
24522
  const dirs = entries.filter(
24796
24523
  (e) => e.isDirectory() && e.name.startsWith("build-")
24797
24524
  );
@@ -24966,7 +24693,7 @@ var LOCK_TIMEOUT_MS = 3e4;
24966
24693
  var LOCK_RETRY_DELAY_MS2 = 200;
24967
24694
  async function findMostRecentSandbox2(sandboxRoot) {
24968
24695
  try {
24969
- const entries = await readdir32(sandboxRoot, { withFileTypes: true });
24696
+ const entries = await readdir3(sandboxRoot, { withFileTypes: true });
24970
24697
  const dirs = entries.filter(
24971
24698
  (e) => e.isDirectory() && !e.name.startsWith(".")
24972
24699
  );
@@ -25401,7 +25128,7 @@ async function* executeInteractiveQueryStreaming(prompt, _jsonSchema, config2, q
25401
25128
  systemPrompt: {
25402
25129
  type: "preset",
25403
25130
  preset: "claude_code",
25404
- append: `${loopliaSystemPrompt}
25131
+ append: `${getLoopliaSystemPrompt(loopliaHome)}
25405
25132
 
25406
25133
  ## User Context
25407
25134
 
@@ -25681,12 +25408,6 @@ var WRITING_KIT_OUTPUT_SCHEMA = {
25681
25408
  };
25682
25409
 
25683
25410
  export {
25684
- CORE_SKILLS,
25685
- isCoreSkill,
25686
- getLoopliaPluginPath,
25687
- copyPlugins,
25688
- downloadRemotePlugins,
25689
- isLoopliaInitialized,
25690
25411
  parseWorkflow,
25691
25412
  generateValidationManifest,
25692
25413
  getFinalStep,