perstack 0.0.100 → 0.0.102

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
@@ -959,12 +959,16 @@ function isRemoteUrl(configPath) {
959
959
 
960
960
  //#endregion
961
961
  //#region ../../packages/perstack-toml/src/config.ts
962
- const ALLOWED_CONFIG_HOSTS = ["raw.githubusercontent.com"];
963
962
  async function getPerstackConfig(configPath) {
964
963
  const configString = await findPerstackConfigString(configPath);
965
964
  if (configString === null) throw new PerstackError("perstack.toml not found. Create one or specify --config path.");
966
965
  return parsePerstackConfig(configString);
967
966
  }
967
+ async function getPerstackConfigOrDefault(configPath) {
968
+ const configString = await findPerstackConfigString(configPath);
969
+ if (configString === null) return {};
970
+ return parsePerstackConfig(configString);
971
+ }
968
972
  function parsePerstackConfig(config) {
969
973
  return parseWithFriendlyError(perstackConfigSchema, dist_default.parse(config ?? ""), "perstack.toml");
970
974
  }
@@ -976,9 +980,8 @@ async function fetchRemoteConfig(url) {
976
980
  throw new PerstackError(`Invalid remote config URL: ${url}`);
977
981
  }
978
982
  if (parsed.protocol !== "https:") throw new PerstackError("Remote config requires HTTPS");
979
- if (!ALLOWED_CONFIG_HOSTS.includes(parsed.hostname)) throw new PerstackError(`Remote config only allowed from: ${ALLOWED_CONFIG_HOSTS.join(", ")}`);
980
983
  try {
981
- const response = await fetch(url, { redirect: "error" });
984
+ const response = await fetch(url);
982
985
  if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);
983
986
  return await response.text();
984
987
  } catch (error) {
@@ -21171,15 +21174,15 @@ async function expertCreateHandler(scopeName, options) {
21171
21174
  console.log(` Name: ${draft.name}`);
21172
21175
  console.log(` ID: ${draft.id}`);
21173
21176
  }
21174
- async function expertDeleteHandler(draftId, options) {
21177
+ async function expertDeleteHandler(draftScopeId, options) {
21175
21178
  const result = await createStudioClient({
21176
21179
  apiKey: resolveApiKey(options.apiKey),
21177
21180
  baseUrl: options.baseUrl
21178
- }).expertDrafts.delete(draftId);
21181
+ }).expertDrafts.delete(draftScopeId);
21179
21182
  if (!result.ok) throw new PerstackError(`Failed to delete draft: ${result.error.message}`);
21180
- console.log(`Draft scope deleted: ${draftId}`);
21183
+ console.log(`Draft scope deleted: ${draftScopeId}`);
21181
21184
  }
21182
- async function expertPushHandler(draftId, options) {
21185
+ async function expertPushHandler(draftScopeId, options) {
21183
21186
  const client = createStudioClient({
21184
21187
  apiKey: resolveApiKey(options.apiKey),
21185
21188
  baseUrl: options.baseUrl
@@ -21187,7 +21190,7 @@ async function expertPushHandler(draftId, options) {
21187
21190
  const perstackConfig = await getPerstackConfig(options.config);
21188
21191
  if (!perstackConfig.experts || Object.keys(perstackConfig.experts).length === 0) throw new PerstackError("No experts defined in perstack.toml");
21189
21192
  const experts = Object.entries(perstackConfig.experts).map(([key, configExpert]) => configExpertToExpert(key, configExpert));
21190
- const result = await client.expertDrafts.refs.create(draftId, { experts });
21193
+ const result = await client.expertDrafts.refs.create(draftScopeId, { experts });
21191
21194
  if (!result.ok) throw new PerstackError(`Failed to push experts: ${result.error.message}`);
21192
21195
  const { draftRef, definition } = result.data.data;
21193
21196
  const expertKeys = Object.keys(definition.experts);
@@ -21195,11 +21198,11 @@ async function expertPushHandler(draftId, options) {
21195
21198
  console.log(` Ref ID: ${draftRef.id}`);
21196
21199
  console.log(` Experts: ${expertKeys.join(", ")}`);
21197
21200
  }
21198
- async function expertRefsHandler(draftId, options) {
21201
+ async function expertRefsHandler(draftScopeId, options) {
21199
21202
  const result = await createStudioClient({
21200
21203
  apiKey: resolveApiKey(options.apiKey),
21201
21204
  baseUrl: options.baseUrl
21202
- }).expertDrafts.refs.list(draftId, {
21205
+ }).expertDrafts.refs.list(draftScopeId, {
21203
21206
  take: options.take,
21204
21207
  skip: options.skip
21205
21208
  });
@@ -21246,14 +21249,14 @@ async function expertYankHandler(key, options) {
21246
21249
 
21247
21250
  //#endregion
21248
21251
  //#region ../../packages/studio/src/version-handlers.ts
21249
- async function expertVersionHandler(draftId, refId, version, options) {
21252
+ async function expertVersionHandler(draftScopeId, refId, version, options) {
21250
21253
  const client = createStudioClient({
21251
21254
  apiKey: resolveApiKey(options.apiKey),
21252
21255
  baseUrl: options.baseUrl
21253
21256
  });
21254
21257
  let readme;
21255
21258
  if (options.readme) readme = await readFile(options.readme, "utf-8");
21256
- const result = await client.expertDrafts.refs.assignVersion(draftId, refId, {
21259
+ const result = await client.expertDrafts.refs.assignVersion(draftScopeId, refId, {
21257
21260
  version,
21258
21261
  tag: options.tag,
21259
21262
  readme
@@ -119753,7 +119756,7 @@ async function startHandler(expertKey, query, options, handlerOptions) {
119753
119756
  //#endregion
119754
119757
  //#region package.json
119755
119758
  var name = "perstack";
119756
- var version = "0.0.100";
119759
+ var version = "0.0.102";
119757
119760
  var description = "PerStack CLI";
119758
119761
 
119759
119762
  //#endregion
@@ -119766,16 +119769,24 @@ async function resolveConfigAndLockfile(configOption) {
119766
119769
  lockfile: lockfilePath ? loadLockfile(lockfilePath) ?? void 0 : void 0
119767
119770
  };
119768
119771
  }
119772
+ async function resolveConfigAndLockfileOrDefault(configOption) {
119773
+ const perstackConfig = await getPerstackConfigOrDefault(configOption);
119774
+ const lockfilePath = findLockfile(configOption);
119775
+ return {
119776
+ perstackConfig,
119777
+ lockfile: lockfilePath ? loadLockfile(lockfilePath) ?? void 0 : void 0
119778
+ };
119779
+ }
119769
119780
  const program = new Command().name(name).description(description).version(version);
119770
119781
  program.command("start").description("Start Perstack with interactive TUI").argument("[expertKey]", "Expert key to run (optional, will prompt if not provided)").argument("[query]", "Query to run (optional, will prompt if not provided)").option("--config <configPath>", "Path to perstack.toml config file").option("--provider <provider>", "Provider to use").option("--model <model>", "Model to use").option("--reasoning-budget <budget>", "Reasoning budget for native LLM reasoning (minimal, low, medium, high, or token count)").option("--max-retries <maxRetries>", "Maximum number of generation retries, default is 5").option("--timeout <timeout>", "Timeout for each generation in milliseconds, default is 300000 (5 minutes)").option("--job-id <jobId>", "Job ID for identifying the job").option("--env-path <path>", "Path to the environment file (can be specified multiple times), default is .env and .env.local", (value, previous) => previous.concat(value), []).option("--verbose", "Enable verbose logging").option("--continue", "Continue the most recent job with new query").option("--continue-job <jobId>", "Continue the specified job with new query").option("--resume-from <checkpointId>", "Resume from a specific checkpoint (requires --continue or --continue-job)").option("-i, --interactive-tool-call-result", "Query is interactive tool call result").action(async (expertKey, query, options) => {
119771
- const { perstackConfig, lockfile } = await resolveConfigAndLockfile(options.config);
119782
+ const { perstackConfig, lockfile } = await (expertKey ? resolveConfigAndLockfileOrDefault : resolveConfigAndLockfile)(options.config);
119772
119783
  await startHandler(expertKey, query, options, {
119773
119784
  perstackConfig,
119774
119785
  lockfile
119775
119786
  });
119776
119787
  });
119777
119788
  program.command("run").description("Run Perstack with JSON output").argument("<expertKey>", "Expert key to run").argument("<query>", "Query to run").option("--config <configPath>", "Path to perstack.toml config file").option("--provider <provider>", "Provider to use").option("--model <model>", "Model to use").option("--reasoning-budget <budget>", "Reasoning budget for native LLM reasoning (minimal, low, medium, high, or token count)").option("--max-retries <maxRetries>", "Maximum number of generation retries, default is 5").option("--timeout <timeout>", "Timeout for each generation in milliseconds, default is 300000 (5 minutes)").option("--job-id <jobId>", "Job ID for identifying the job").option("--env-path <path>", "Path to the environment file (can be specified multiple times), default is .env and .env.local", (value, previous) => previous.concat(value), []).option("--verbose", "Enable verbose logging").option("--continue", "Continue the most recent job with new query").option("--continue-job <jobId>", "Continue the specified job with new query").option("--resume-from <checkpointId>", "Resume from a specific checkpoint (requires --continue or --continue-job)").option("-i, --interactive-tool-call-result", "Query is interactive tool call result").option("--filter <types>", "Filter events by type (comma-separated, e.g., completeRun,stopRunByError)").action(async (expertKey, query, options) => {
119778
- const { perstackConfig, lockfile } = await resolveConfigAndLockfile(options.config);
119789
+ const { perstackConfig, lockfile } = await resolveConfigAndLockfileOrDefault(options.config);
119779
119790
  await runHandler(expertKey, query, options, {
119780
119791
  perstackConfig,
119781
119792
  lockfile
@@ -119809,23 +119820,23 @@ expertCmd.command("create").description("Create a new draft scope").argument("<s
119809
119820
  ...options
119810
119821
  });
119811
119822
  });
119812
- expertCmd.command("delete").description("Delete a draft scope").argument("<draftId>", "Draft scope ID").action(async function(draftId) {
119813
- await expertDeleteHandler(draftId, getParentOptions(this));
119823
+ expertCmd.command("delete").description("Delete a draft scope").argument("<draftScopeId>", "Draft scope ID").action(async function(draftScopeId) {
119824
+ await expertDeleteHandler(draftScopeId, getParentOptions(this));
119814
119825
  });
119815
- expertCmd.command("push").description("Push local expert definitions to a draft ref").argument("<draftId>", "Draft scope ID").option("--config <path>", "Path to perstack.toml config file").action(async function(draftId, options) {
119816
- await expertPushHandler(draftId, {
119826
+ expertCmd.command("push").description("Push local expert definitions to a draft ref").argument("<draftScopeId>", "Draft scope ID").option("--config <path>", "Path to perstack.toml config file").action(async function(draftScopeId, options) {
119827
+ await expertPushHandler(draftScopeId, {
119817
119828
  ...getParentOptions(this),
119818
119829
  ...options
119819
119830
  });
119820
119831
  });
119821
- expertCmd.command("refs").description("List draft refs for a draft scope").argument("<draftId>", "Draft scope ID").option("--take <n>", "Limit results", Number.parseInt).option("--skip <n>", "Offset", Number.parseInt).action(async function(draftId, options) {
119822
- await expertRefsHandler(draftId, {
119832
+ expertCmd.command("refs").description("List draft refs for a draft scope").argument("<draftScopeId>", "Draft scope ID").option("--take <n>", "Limit results", Number.parseInt).option("--skip <n>", "Offset", Number.parseInt).action(async function(draftScopeId, options) {
119833
+ await expertRefsHandler(draftScopeId, {
119823
119834
  ...getParentOptions(this),
119824
119835
  ...options
119825
119836
  });
119826
119837
  });
119827
- expertCmd.command("version").description("Assign a version to a draft ref").argument("<draftId>", "Draft scope ID").argument("<refId>", "Draft ref ID").argument("<version>", "Semantic version (e.g., 1.0.0)").option("--tag <tag>", "Version tag (e.g., latest)").option("--readme <path>", "Path to README file").action(async function(draftId, refId, version, options) {
119828
- await expertVersionHandler(draftId, refId, version, {
119838
+ expertCmd.command("version").description("Assign a version to a draft ref").argument("<draftScopeId>", "Draft scope ID").argument("<refId>", "Draft ref ID").argument("<version>", "Semantic version (e.g., 1.0.0)").option("--tag <tag>", "Version tag (e.g., latest)").option("--readme <path>", "Path to README file").action(async function(draftScopeId, refId, version, options) {
119839
+ await expertVersionHandler(draftScopeId, refId, version, {
119829
119840
  ...getParentOptions(this),
119830
119841
  ...options
119831
119842
  });