create-expert 0.0.22 → 0.0.24

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/bin/cli.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFileSync, existsSync, mkdirSync, writeFileSync, readdirSync } from 'fs';
3
- import { parseWithFriendlyError, perstackConfigSchema, startCommandInputSchema, defaultMaxRetries, defaultTimeout, checkpointSchema, jobSchema, runSettingSchema, BASE_SKILL_PREFIX, createBaseToolActivity, createGeneralToolActivity } from '@perstack/core';
3
+ import { parseWithFriendlyError, perstackConfigSchema, startCommandInputSchema, defaultMaxRetries, defaultTimeout, checkpointSchema, lockfileSchema, jobSchema, runSettingSchema, BASE_SKILL_PREFIX, createBaseToolActivity, createGeneralToolActivity } from '@perstack/core';
4
4
  import { readFile, mkdir, writeFile } from 'fs/promises';
5
- import path5 from 'path';
6
- import { findLockfile, loadLockfile, runtimeVersion, run } from '@perstack/runtime';
5
+ import path6 from 'path';
6
+ import { runtimeVersion, run } from '@perstack/runtime';
7
7
  import dotenv from 'dotenv';
8
8
  import TOML from 'smol-toml';
9
9
  import { render, useApp, useInput, Box, Text } from 'ink';
@@ -1728,12 +1728,12 @@ function storeJob(job) {
1728
1728
  if (!existsSync(jobDir)) {
1729
1729
  mkdirSync(jobDir, { recursive: true });
1730
1730
  }
1731
- const jobPath = path5.resolve(jobDir, "job.json");
1731
+ const jobPath = path6.resolve(jobDir, "job.json");
1732
1732
  writeFileSync(jobPath, JSON.stringify(job, null, 2));
1733
1733
  }
1734
1734
  function retrieveJob(jobId) {
1735
1735
  const jobDir = getJobDir(jobId);
1736
- const jobPath = path5.resolve(jobDir, "job.json");
1736
+ const jobPath = path6.resolve(jobDir, "job.json");
1737
1737
  if (!existsSync(jobPath)) {
1738
1738
  return void 0;
1739
1739
  }
@@ -1751,7 +1751,7 @@ function getAllJobs() {
1751
1751
  }
1752
1752
  const jobs = [];
1753
1753
  for (const jobDirName of jobDirNames) {
1754
- const jobPath = path5.resolve(jobsDir, jobDirName, "job.json");
1754
+ const jobPath = path6.resolve(jobsDir, jobDirName, "job.json");
1755
1755
  if (!existsSync(jobPath)) {
1756
1756
  continue;
1757
1757
  }
@@ -1812,7 +1812,7 @@ function getCheckpointsByJobId(jobId) {
1812
1812
  const checkpoints = [];
1813
1813
  for (const file of files) {
1814
1814
  try {
1815
- const content = readFileSync(path5.resolve(checkpointDir, file), "utf-8");
1815
+ const content = readFileSync(path6.resolve(checkpointDir, file), "utf-8");
1816
1816
  checkpoints.push(checkpointSchema.parse(JSON.parse(content)));
1817
1817
  } catch {
1818
1818
  }
@@ -1833,13 +1833,13 @@ function getAllRuns() {
1833
1833
  }
1834
1834
  const runs = [];
1835
1835
  for (const jobDirName of jobDirNames) {
1836
- const runsDir = path5.resolve(jobsDir, jobDirName, "runs");
1836
+ const runsDir = path6.resolve(jobsDir, jobDirName, "runs");
1837
1837
  if (!existsSync(runsDir)) {
1838
1838
  continue;
1839
1839
  }
1840
1840
  const runDirNames = readdirSync(runsDir, { withFileTypes: true }).filter((dir) => dir.isDirectory()).map((dir) => dir.name);
1841
1841
  for (const runDirName of runDirNames) {
1842
- const runSettingPath = path5.resolve(runsDir, runDirName, "run-setting.json");
1842
+ const runSettingPath = path6.resolve(runsDir, runDirName, "run-setting.json");
1843
1843
  if (!existsSync(runSettingPath)) {
1844
1844
  continue;
1845
1845
  }
@@ -1873,7 +1873,7 @@ function getEventContents(jobId, runId, maxStepNumber) {
1873
1873
  const events = [];
1874
1874
  for (const { file } of eventFiles) {
1875
1875
  try {
1876
- const content = readFileSync(path5.resolve(runDir, file), "utf-8");
1876
+ const content = readFileSync(path6.resolve(runDir, file), "utf-8");
1877
1877
  events.push(JSON.parse(content));
1878
1878
  } catch {
1879
1879
  }
@@ -1881,7 +1881,7 @@ function getEventContents(jobId, runId, maxStepNumber) {
1881
1881
  return events;
1882
1882
  }
1883
1883
  function getRunIdsByJobId(jobId) {
1884
- const runsDir = path5.resolve(getJobDir(jobId), "runs");
1884
+ const runsDir = path6.resolve(getJobDir(jobId), "runs");
1885
1885
  if (!existsSync(runsDir)) {
1886
1886
  return [];
1887
1887
  }
@@ -1936,23 +1936,23 @@ async function findPerstackConfigString(configPath) {
1936
1936
  return await fetchRemoteConfig(configPath);
1937
1937
  }
1938
1938
  try {
1939
- const tomlString = await readFile(path5.resolve(process.cwd(), configPath), "utf-8");
1939
+ const tomlString = await readFile(path6.resolve(process.cwd(), configPath), "utf-8");
1940
1940
  return tomlString;
1941
1941
  } catch {
1942
1942
  throw new Error(`Given config path "${configPath}" is not found`);
1943
1943
  }
1944
1944
  }
1945
- return await findPerstackConfigStringRecursively(path5.resolve(process.cwd()));
1945
+ return await findPerstackConfigStringRecursively(path6.resolve(process.cwd()));
1946
1946
  }
1947
1947
  async function findPerstackConfigStringRecursively(cwd) {
1948
1948
  try {
1949
- const tomlString = await readFile(path5.resolve(cwd, "perstack.toml"), "utf-8");
1949
+ const tomlString = await readFile(path6.resolve(cwd, "perstack.toml"), "utf-8");
1950
1950
  return tomlString;
1951
1951
  } catch {
1952
- if (cwd === path5.parse(cwd).root) {
1952
+ if (cwd === path6.parse(cwd).root) {
1953
1953
  return null;
1954
1954
  }
1955
- return await findPerstackConfigStringRecursively(path5.dirname(cwd));
1955
+ return await findPerstackConfigStringRecursively(path6.dirname(cwd));
1956
1956
  }
1957
1957
  }
1958
1958
  async function parsePerstackConfig(config2) {
@@ -2168,6 +2168,7 @@ async function resolveRunContext(input) {
2168
2168
  {
2169
2169
  name,
2170
2170
  version: expert.version ?? "1.0.0",
2171
+ minRuntimeVersion: expert.minRuntimeVersion,
2171
2172
  description: expert.description,
2172
2173
  instruction: expert.instruction,
2173
2174
  skills: expert.skills,
@@ -2210,6 +2211,30 @@ function parseInteractiveToolCallResult(query, checkpoint) {
2210
2211
  }
2211
2212
  };
2212
2213
  }
2214
+ function loadLockfile(lockfilePath) {
2215
+ try {
2216
+ const content = readFileSync(lockfilePath, "utf-8");
2217
+ const parsed = TOML.parse(content);
2218
+ return parseWithFriendlyError(lockfileSchema, parsed, "perstack.lock");
2219
+ } catch {
2220
+ return null;
2221
+ }
2222
+ }
2223
+ function findLockfile(configPath) {
2224
+ return findLockfileRecursively(process.cwd());
2225
+ }
2226
+ function findLockfileRecursively(cwd) {
2227
+ const lockfilePath = path6.resolve(cwd, "perstack.lock");
2228
+ try {
2229
+ readFileSync(lockfilePath);
2230
+ return lockfilePath;
2231
+ } catch {
2232
+ if (cwd === path6.parse(cwd).root) {
2233
+ return null;
2234
+ }
2235
+ return findLockfileRecursively(path6.dirname(cwd));
2236
+ }
2237
+ }
2213
2238
 
2214
2239
  // ../../packages/tui-components/src/utils/event-queue.ts
2215
2240
  var defaultErrorLogger = (message, error) => {
@@ -3533,7 +3558,7 @@ function renderTodo(action, color) {
3533
3558
  ] }) });
3534
3559
  }
3535
3560
  function renderReadTextFile(action, color) {
3536
- const { path: path6, content, from, to } = action;
3561
+ const { path: path7, content, from, to } = action;
3537
3562
  const lineRange = from !== void 0 && to !== void 0 ? `#${from}-${to}` : "";
3538
3563
  const lines = content?.split("\n") ?? [];
3539
3564
  return /* @__PURE__ */ jsx(
@@ -3541,24 +3566,24 @@ function renderReadTextFile(action, color) {
3541
3566
  {
3542
3567
  indicatorColor: color,
3543
3568
  label: "Read Text File",
3544
- summary: `${shortenPath(path6)}${lineRange}`,
3569
+ summary: `${shortenPath(path7)}${lineRange}`,
3545
3570
  children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: lines.map((line, idx) => /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 1, children: /* @__PURE__ */ jsx(Text, { color: "white", dimColor: true, children: line }) }, `read-${idx}`)) })
3546
3571
  }
3547
3572
  );
3548
3573
  }
3549
3574
  function renderWriteTextFile(action, color) {
3550
- const { path: path6, text } = action;
3575
+ const { path: path7, text } = action;
3551
3576
  const lines = text.split("\n");
3552
- return /* @__PURE__ */ jsx(ActionRow, { indicatorColor: color, label: "Write Text File", summary: shortenPath(path6), children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: lines.map((line, idx) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
3577
+ return /* @__PURE__ */ jsx(ActionRow, { indicatorColor: color, label: "Write Text File", summary: shortenPath(path7), children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: lines.map((line, idx) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
3553
3578
  /* @__PURE__ */ jsx(Text, { color: "green", dimColor: true, children: "+" }),
3554
3579
  /* @__PURE__ */ jsx(Text, { color: "white", dimColor: true, children: line })
3555
3580
  ] }, `write-${idx}`)) }) });
3556
3581
  }
3557
3582
  function renderEditTextFile(action, color) {
3558
- const { path: path6, oldText, newText } = action;
3583
+ const { path: path7, oldText, newText } = action;
3559
3584
  const oldLines = oldText.split("\n");
3560
3585
  const newLines = newText.split("\n");
3561
- return /* @__PURE__ */ jsx(ActionRow, { indicatorColor: color, label: "Edit Text File", summary: shortenPath(path6), children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3586
+ return /* @__PURE__ */ jsx(ActionRow, { indicatorColor: color, label: "Edit Text File", summary: shortenPath(path7), children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3562
3587
  oldLines.map((line, idx) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
3563
3588
  /* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, children: "-" }),
3564
3589
  /* @__PURE__ */ jsx(Text, { color: "white", dimColor: true, children: line })
@@ -3570,18 +3595,18 @@ function renderEditTextFile(action, color) {
3570
3595
  ] }) });
3571
3596
  }
3572
3597
  function renderAppendTextFile(action, color) {
3573
- const { path: path6, text } = action;
3598
+ const { path: path7, text } = action;
3574
3599
  const lines = text.split("\n");
3575
- return /* @__PURE__ */ jsx(ActionRow, { indicatorColor: color, label: "Append Text File", summary: shortenPath(path6), children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: lines.map((line, idx) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
3600
+ return /* @__PURE__ */ jsx(ActionRow, { indicatorColor: color, label: "Append Text File", summary: shortenPath(path7), children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: lines.map((line, idx) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
3576
3601
  /* @__PURE__ */ jsx(Text, { color: "green", dimColor: true, children: "+" }),
3577
3602
  /* @__PURE__ */ jsx(Text, { color: "white", dimColor: true, children: line })
3578
3603
  ] }, `append-${idx}`)) }) });
3579
3604
  }
3580
3605
  function renderListDirectory(action, color) {
3581
- const { path: path6, items } = action;
3606
+ const { path: path7, items } = action;
3582
3607
  const itemLines = items?.map((item) => `${item.type === "directory" ? "\u{1F4C1}" : "\u{1F4C4}"} ${item.name}`) ?? [];
3583
3608
  const { visible, remaining } = summarizeOutput(itemLines, RENDER_CONSTANTS.LIST_DIR_MAX_ITEMS);
3584
- return /* @__PURE__ */ jsx(ActionRow, { indicatorColor: color, label: "List", summary: shortenPath(path6), children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3609
+ return /* @__PURE__ */ jsx(ActionRow, { indicatorColor: color, label: "List", summary: shortenPath(path7), children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3585
3610
  visible.map((line, idx) => /* @__PURE__ */ jsx(Text, { dimColor: true, children: truncateText(line, UI_CONSTANTS.TRUNCATE_TEXT_DEFAULT) }, `dir-${idx}`)),
3586
3611
  remaining > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
3587
3612
  "... +",
@@ -4353,21 +4378,16 @@ var config = parseWithFriendlyError(
4353
4378
  perstackConfigSchema,
4354
4379
  TOML.parse(readFileSync(tomlPath, "utf-8"))
4355
4380
  );
4356
- new Command().name("create-expert").description("Create and modify Perstack expert definitions").argument("<query>", "Description of the expert to create or modify").action(async (query) => {
4357
- await startHandler(
4358
- "expert",
4359
- query,
4360
- {},
4361
- {
4362
- perstackConfig: config,
4363
- additionalEnv: (env) => {
4364
- const provider = config.provider?.providerName ?? "anthropic";
4365
- const envKey = PROVIDER_ENV_MAP[provider];
4366
- const value = envKey ? env[envKey] : void 0;
4367
- return value ? { PROVIDER_API_KEY: value } : {};
4368
- }
4381
+ new Command().name("create-expert").description("Create and modify Perstack expert definitions").argument("[query]", "Description of the expert to create or modify").option("--continue", "Continue the most recent job with new query").option("--continue-job <jobId>", "Continue the specified job with new query").action(async (query, options) => {
4382
+ await startHandler("expert", query, options, {
4383
+ perstackConfig: config,
4384
+ additionalEnv: (env) => {
4385
+ const provider = config.provider?.providerName ?? "anthropic";
4386
+ const envKey = PROVIDER_ENV_MAP[provider];
4387
+ const value = envKey ? env[envKey] : void 0;
4388
+ return value ? { PROVIDER_API_KEY: value } : {};
4369
4389
  }
4370
- );
4390
+ });
4371
4391
  }).parse();
4372
4392
  /*! Bundled license information:
4373
4393