poe-code 3.0.307 → 3.0.309

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/index.js CHANGED
@@ -74873,10 +74873,19 @@ var init_path_safety3 = __esm({
74873
74873
  // packages/process-launcher/src/process-id.ts
74874
74874
  import path104 from "node:path";
74875
74875
  function assertValidManagedProcessId(id) {
74876
- if (id.length === 0 || id === "." || id === ".." || path104.basename(id) !== id) {
74876
+ if (id.length === 0 || id !== id.trim() || id === "." || id === ".." || path104.basename(id) !== id || hasControlCharacter(id)) {
74877
74877
  throw new Error(`Invalid managed process id: ${id}`);
74878
74878
  }
74879
74879
  }
74880
+ function hasControlCharacter(value) {
74881
+ for (const char of value) {
74882
+ const code = char.charCodeAt(0);
74883
+ if (code <= 31 || code === 127) {
74884
+ return true;
74885
+ }
74886
+ }
74887
+ return false;
74888
+ }
74880
74889
  var init_process_id = __esm({
74881
74890
  "packages/process-launcher/src/process-id.ts"() {
74882
74891
  "use strict";
@@ -74958,10 +74967,7 @@ function createStateStore(stateDir, fs28 = nodeFs7) {
74958
74967
  await assertPathHasNoSymbolicLinks3(fs28, statePath);
74959
74968
  const content = await fs28.readFile(statePath, "utf8");
74960
74969
  const parsed = JSON.parse(content);
74961
- if (!isProcessState(parsed, id)) {
74962
- throw new Error(`Invalid process state document: ${id}`);
74963
- }
74964
- return parsed;
74970
+ return assertValidProcessStateDocument(parsed, id);
74965
74971
  } catch (error3) {
74966
74972
  if (isNotFoundError7(error3)) {
74967
74973
  return null;
@@ -75045,12 +75051,24 @@ function createStateStore(stateDir, fs28 = nodeFs7) {
75045
75051
  }
75046
75052
  return { read, write: write2, list, remove: remove2 };
75047
75053
  }
75054
+ function assertValidProcessStateDocument(value, id) {
75055
+ if (!isProcessState(value, id)) {
75056
+ throw new Error(`Invalid process state document: ${id}`);
75057
+ }
75058
+ return value;
75059
+ }
75048
75060
  function isProcessState(value, id) {
75049
75061
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
75050
75062
  return false;
75051
75063
  }
75052
75064
  const state = value;
75053
- return state.id === id && (state.pid === null || typeof state.pid === "number") && (state.status === "running" || state.status === "stopped" || state.status === "crashed" || state.status === "restarting") && (state.runtime === "host" || state.runtime === "docker") && typeof state.restartCount === "number" && (state.lastExitCode === null || typeof state.lastExitCode === "number") && (state.lastStartedAt === null || typeof state.lastStartedAt === "string") && (state.lastStoppedAt === null || typeof state.lastStoppedAt === "string") && typeof state.command === "string" && Array.isArray(state.args) && state.args.every((argument) => typeof argument === "string");
75065
+ return state.id === id && (state.pid === null || typeof state.pid === "number") && (state.status === "running" || state.status === "stopped" || state.status === "crashed" || state.status === "restarting") && (state.runtime === "host" || state.runtime === "docker") && isPositiveSafeIntegerOrNull(state.pid) && isNonNegativeSafeInteger(state.restartCount) && (state.lastExitCode === null || isNonNegativeSafeInteger(state.lastExitCode)) && (state.lastStartedAt === null || typeof state.lastStartedAt === "string") && (state.lastStoppedAt === null || typeof state.lastStoppedAt === "string") && typeof state.command === "string" && Array.isArray(state.args) && state.args.every((argument) => typeof argument === "string");
75066
+ }
75067
+ function isPositiveSafeIntegerOrNull(value) {
75068
+ return value === null || typeof value === "number" && Number.isSafeInteger(value) && value > 0;
75069
+ }
75070
+ function isNonNegativeSafeInteger(value) {
75071
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
75054
75072
  }
75055
75073
  var init_state_store = __esm({
75056
75074
  "packages/process-launcher/src/state/state-store.ts"() {
@@ -75277,8 +75295,10 @@ import net from "node:net";
75277
75295
  async function waitForReady(check, options) {
75278
75296
  assertValidTimeout(options.timeoutMs, "readiness timeout");
75279
75297
  if (check.kind === "log-pattern") {
75298
+ assertValidLogPattern(check.pattern);
75280
75299
  return waitForLogPattern(check.pattern, options);
75281
75300
  }
75301
+ assertValidTcpPort(check.port);
75282
75302
  return waitForTcp(check, options);
75283
75303
  }
75284
75304
  function waitForLogPattern(pattern, options) {
@@ -75399,6 +75419,16 @@ function assertValidTimeout(value, description) {
75399
75419
  throw new Error(`Invalid ${description}: ${value}`);
75400
75420
  }
75401
75421
  }
75422
+ function assertValidLogPattern(value) {
75423
+ if (value.trim().length === 0) {
75424
+ throw new Error("Invalid log pattern readiness check: pattern must not be blank.");
75425
+ }
75426
+ }
75427
+ function assertValidTcpPort(value) {
75428
+ if (!Number.isSafeInteger(value) || value <= 0 || value > 65535) {
75429
+ throw new Error(`Invalid TCP readiness port: ${value}`);
75430
+ }
75431
+ }
75402
75432
  var init_health_check = __esm({
75403
75433
  "packages/process-launcher/src/health/health-check.ts"() {
75404
75434
  "use strict";
@@ -76019,6 +76049,7 @@ import path108 from "node:path";
76019
76049
  import { TextDecoder as TextDecoder2 } from "node:util";
76020
76050
  async function startManagedProcess(options) {
76021
76051
  assertOptionalFiniteDuration(options.startupTimeoutMs, "startup timeout");
76052
+ assertOptionalFiniteDuration(options.pollIntervalMs, "poll interval");
76022
76053
  const fs28 = options.fs ?? defaultFs3();
76023
76054
  const spec10 = normalizeSpec(options.spec);
76024
76055
  const existing = await readManagedProcess({
@@ -76060,6 +76091,8 @@ async function startManagedProcess(options) {
76060
76091
  }
76061
76092
  }
76062
76093
  async function stopManagedProcess(options) {
76094
+ assertOptionalFiniteDuration(options.stopTimeoutMs, "stop timeout");
76095
+ assertOptionalFiniteDuration(options.pollIntervalMs, "poll interval");
76063
76096
  const fs28 = options.fs ?? defaultFs3();
76064
76097
  const record = await readManagedProcess({
76065
76098
  baseDir: options.baseDir,
@@ -76184,7 +76217,16 @@ async function* followManagedLogs(options) {
76184
76217
  throw new Error(`Invalid managed log poll interval: ${pollIntervalMs}`);
76185
76218
  }
76186
76219
  const cursor2 = createFollowLogCursor();
76187
- await primeFollowCursor(fs28, options.baseDir, options.id, stream, cursor2);
76220
+ const initialLines = options.lines === void 0 ? [] : await readInitialFollowLogWindow(fs28, options.baseDir, options.id, stream, options.lines, cursor2);
76221
+ if (options.lines === void 0) {
76222
+ await primeFollowCursor(fs28, options.baseDir, options.id, stream, cursor2);
76223
+ }
76224
+ for (const line of initialLines) {
76225
+ if (options.signal?.aborted) {
76226
+ return;
76227
+ }
76228
+ yield line;
76229
+ }
76188
76230
  while (!options.signal?.aborted) {
76189
76231
  await sleep4(pollIntervalMs);
76190
76232
  if (options.signal?.aborted) {
@@ -76204,6 +76246,30 @@ function createFollowLogCursor() {
76204
76246
  remainder: ""
76205
76247
  };
76206
76248
  }
76249
+ async function readInitialFollowLogWindow(fs28, baseDir, id, stream, lines, cursor2) {
76250
+ assertValidLogLineCount(lines);
76251
+ const stat33 = await statFollowedLog(fs28, baseDir, id, stream);
76252
+ resetFollowCursor(cursor2, stat33?.fileId ?? null);
76253
+ if (stat33 === null) {
76254
+ return [];
76255
+ }
76256
+ const bytes = await readFollowedLogBytes(
76257
+ fs28,
76258
+ resolveCurrentLogPath(baseDir, id, stream),
76259
+ 0
76260
+ );
76261
+ cursor2.offset = bytes.byteLength;
76262
+ const allLines = consumeFollowedLogBytes(cursor2, bytes);
76263
+ if (lines === 0) {
76264
+ return [];
76265
+ }
76266
+ return allLines.slice(-lines);
76267
+ }
76268
+ function assertValidLogLineCount(lines) {
76269
+ if (!Number.isFinite(lines) || !Number.isInteger(lines) || lines < 0) {
76270
+ throw new Error("lines must be a finite non-negative integer");
76271
+ }
76272
+ }
76207
76273
  async function primeFollowCursor(fs28, baseDir, id, stream, cursor2) {
76208
76274
  const stat33 = await statFollowedLog(fs28, baseDir, id, stream);
76209
76275
  resetFollowCursor(cursor2, stat33?.fileId ?? null);
@@ -76320,6 +76386,7 @@ async function runManagedProcess(options) {
76320
76386
  if (options.signal?.aborted) {
76321
76387
  return;
76322
76388
  }
76389
+ assertOptionalFiniteDuration(options.pollIntervalMs, "poll interval");
76323
76390
  const fs28 = options.fs ?? defaultFs3();
76324
76391
  await assertProcessDirectorySafe(fs28, options.baseDir, options.id);
76325
76392
  await assertPathNotSymbolicLink(fs28, resolveLogDir2(options.baseDir, options.id));
@@ -76527,13 +76594,71 @@ async function readSpec(fs28, baseDir, id) {
76527
76594
  if (!isRecord31(spec10) || typeof spec10.id !== "string" || spec10.id !== id) {
76528
76595
  throw new Error(`Invalid managed process specification for "${id}".`);
76529
76596
  }
76530
- return spec10;
76597
+ return assertValidProcessSpec(spec10, id);
76598
+ }
76599
+ function assertValidProcessSpec(value, id) {
76600
+ if (value.id !== id || !isNonEmptyString4(value.command) || !isOptionalStringArray(value.args) || !isOptionalString(value.cwd) || !isOptionalStringRecord(value.env) || !isRestartPolicy(value.restart) || !isOptionalNonNegativeSafeInteger(value.maxRestarts) || !isOptionalFiniteDurationValue(value.backoffMs) || !isOptionalFiniteDurationValue(value.maxBackoffMs) || !isOptionalPositiveSafeInteger(value.logRetainCount) || !isOptionalReadyCheck(value.readyCheck) || !isOptionalRecord(value.docker)) {
76601
+ throw new Error(`Invalid managed process specification for "${id}".`);
76602
+ }
76603
+ return value;
76604
+ }
76605
+ function isNonEmptyString4(value) {
76606
+ return typeof value === "string" && value.trim().length > 0;
76607
+ }
76608
+ function isOptionalString(value) {
76609
+ return value === void 0 || typeof value === "string";
76610
+ }
76611
+ function isOptionalStringArray(value) {
76612
+ return value === void 0 || Array.isArray(value) && value.every((entry) => typeof entry === "string");
76613
+ }
76614
+ function isOptionalStringRecord(value) {
76615
+ if (value === void 0) {
76616
+ return true;
76617
+ }
76618
+ if (!isPlainRecord4(value)) {
76619
+ return false;
76620
+ }
76621
+ return Object.values(value).every((entry) => typeof entry === "string");
76622
+ }
76623
+ function isRestartPolicy(value) {
76624
+ return value === "never" || value === "on-failure" || value === "always";
76625
+ }
76626
+ function isOptionalNonNegativeSafeInteger(value) {
76627
+ return value === void 0 || typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
76628
+ }
76629
+ function isOptionalPositiveSafeInteger(value) {
76630
+ return value === void 0 || typeof value === "number" && Number.isSafeInteger(value) && value > 0;
76631
+ }
76632
+ function isOptionalFiniteDurationValue(value) {
76633
+ return value === void 0 || typeof value === "number" && Number.isFinite(value) && value >= 0;
76634
+ }
76635
+ function isOptionalReadyCheck(value) {
76636
+ if (value === void 0) {
76637
+ return true;
76638
+ }
76639
+ if (!isPlainRecord4(value)) {
76640
+ return false;
76641
+ }
76642
+ if (value.kind === "log-pattern") {
76643
+ return isNonEmptyString4(value.pattern);
76644
+ }
76645
+ if (value.kind === "tcp") {
76646
+ return typeof value.port === "number" && Number.isSafeInteger(value.port) && value.port > 0 && value.port <= 65535 && isOptionalString(value.host) && isOptionalFiniteDurationValue(value.timeoutMs);
76647
+ }
76648
+ return false;
76649
+ }
76650
+ function isOptionalRecord(value) {
76651
+ return value === void 0 || isPlainRecord4(value);
76652
+ }
76653
+ function isPlainRecord4(value) {
76654
+ return typeof value === "object" && value !== null && !Array.isArray(value);
76531
76655
  }
76532
76656
  async function writeSpec(fs28, baseDir, spec10) {
76533
76657
  await writeJsonFile(fs28, resolveSpecPath(baseDir, spec10.id), spec10);
76534
76658
  }
76535
76659
  async function readState(fs28, baseDir, id) {
76536
- return await readJsonFile(fs28, resolveStatePath(baseDir, id));
76660
+ const state = await readJsonFile(fs28, resolveStatePath(baseDir, id));
76661
+ return state === null ? null : assertValidProcessStateDocument(state, id);
76537
76662
  }
76538
76663
  async function writeState(fs28, baseDir, state) {
76539
76664
  await writeJsonFile(fs28, resolveStatePath(baseDir, state.id), state);
@@ -90312,7 +90437,7 @@ function isHttpErrorLike(error3) {
90312
90437
  function hasTypedOptionalField(value, field, type) {
90313
90438
  return !hasOwnProperty11(value, field) || typeof value[field] === type;
90314
90439
  }
90315
- function isNonEmptyString4(value) {
90440
+ function isNonEmptyString5(value) {
90316
90441
  return typeof value === "string" && value.trim().length > 0;
90317
90442
  }
90318
90443
  function isProblemDetailsLike(body) {
@@ -90365,7 +90490,7 @@ function hasOwnProperty11(value, name) {
90365
90490
  return Object.prototype.hasOwnProperty.call(value, name);
90366
90491
  }
90367
90492
  function hasOwnNonEmptyString(value, name) {
90368
- return hasOwnProperty11(value, name) && isNonEmptyString4(value[name]);
90493
+ return hasOwnProperty11(value, name) && isNonEmptyString5(value[name]);
90369
90494
  }
90370
90495
  function styleHttpErrorLine(value, style) {
90371
90496
  return process.stdout.isTTY !== true ? value : style(value);
@@ -136215,7 +136340,7 @@ function resolveStringValues2(value) {
136215
136340
  resolved[key2] = entry.map(
136216
136341
  (item) => typeof item === "string" ? resolveStringValue2(item) : item
136217
136342
  );
136218
- } else if (isPlainRecord4(entry)) {
136343
+ } else if (isPlainRecord5(entry)) {
136219
136344
  resolved[key2] = resolveStringValues2(entry);
136220
136345
  } else {
136221
136346
  resolved[key2] = entry;
@@ -136234,7 +136359,7 @@ function resolveWorkflowRelativePath(value, workflowPath) {
136234
136359
  return path173.isAbsolute(value) ? value : path173.resolve(path173.dirname(workflowPath), value);
136235
136360
  }
136236
136361
  function asRecord6(value) {
136237
- return isPlainRecord4(value) ? value : void 0;
136362
+ return isPlainRecord5(value) ? value : void 0;
136238
136363
  }
136239
136364
  function hasOwnEntry4(record, key2) {
136240
136365
  return Object.prototype.hasOwnProperty.call(record, key2);
@@ -136242,7 +136367,7 @@ function hasOwnEntry4(record, key2) {
136242
136367
  function getOwnEntry37(record, key2) {
136243
136368
  return hasOwnEntry4(record, key2) ? record[key2] : void 0;
136244
136369
  }
136245
- function isPlainRecord4(value) {
136370
+ function isPlainRecord5(value) {
136246
136371
  return typeof value === "object" && value !== null && !Array.isArray(value);
136247
136372
  }
136248
136373
  function isFileNotFoundError2(error3) {
@@ -137096,7 +137221,7 @@ var init_package2 = __esm({
137096
137221
  "package.json"() {
137097
137222
  package_default2 = {
137098
137223
  name: "poe-code",
137099
- version: "3.0.307",
137224
+ version: "3.0.309",
137100
137225
  description: "CLI tool to configure Poe API for developer workflows.",
137101
137226
  type: "module",
137102
137227
  main: "./dist/index.js",