@plune-ai/cli 0.27.0 → 0.29.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.
@@ -36,6 +36,7 @@ __export(reporter_core_exports, {
36
36
  appendBatch: () => appendBatch,
37
37
  ciCommit: () => ciCommit,
38
38
  createClient: () => createClient,
39
+ errorContextFields: () => errorContextFields,
39
40
  errorContextOf: () => errorContextOf,
40
41
  failureOf: () => failureOf,
41
42
  filesOf: () => filesOf,
@@ -449,6 +450,16 @@ function repoRootOf(dir, stopAt) {
449
450
  }
450
451
  }
451
452
  function errorContextOf(attempt, home = (0, import_node_os2.homedir)()) {
453
+ return cutErrorContext(attempt, home).text;
454
+ }
455
+ function errorContextFields(attempt, home = (0, import_node_os2.homedir)()) {
456
+ const { text, omitted: omitted2 } = cutErrorContext(attempt, home);
457
+ return {
458
+ ...text !== "" ? { errorContext: text } : {},
459
+ ...omitted2 > 0 ? { errorContextOmitted: omitted2 } : {}
460
+ };
461
+ }
462
+ function cutErrorContext(attempt, home) {
452
463
  const text = attempt.errors.map((e) => e.text).filter((t) => t !== "").join("\n\n");
453
464
  return cut(machineless(text, attempt.repoRoot, home));
454
465
  }
@@ -484,7 +495,7 @@ function pathIn(path3) {
484
495
  }
485
496
  var fileNameOf = (name) => /^(?:file:\/\/|[\\/]|~[\\/]|[A-Za-z]:[\\/])/.test(name) ? name.split(/[\\/]/).pop() ?? "" : name;
486
497
  function cut(text) {
487
- if (jsonBytes(text) <= TEXT_LIMIT) return text;
498
+ if (jsonBytes(text) <= TEXT_LIMIT) return { text, omitted: 0 };
488
499
  const lines = text.split("\n");
489
500
  const size = lines.map((line) => jsonBytes(line) + 2);
490
501
  const budget = TEXT_LIMIT - jsonBytes(omitted(lines.length));
@@ -493,7 +504,8 @@ function cut(text) {
493
504
  let tail = lines.length;
494
505
  while (head < tail && used + size[head] <= budget / 2) used += size[head++];
495
506
  while (tail > head && used + size[tail - 1] <= budget) used += size[--tail];
496
- return [...lines.slice(0, head), omitted(tail - head), ...lines.slice(tail)].join("\n");
507
+ const kept = [...lines.slice(0, head), ...lines.slice(tail)].join("\n");
508
+ return { text: [...lines.slice(0, head), omitted(tail - head), ...lines.slice(tail)].join("\n"), omitted: text.length - kept.length };
497
509
  }
498
510
  var omitted = (lines) => `\u2026[omitted ${lines} lines]\u2026`;
499
511
  var METADATA_TYPE = "application/plune.metadata+json";
@@ -1585,6 +1597,7 @@ function resultKey(testId, retry) {
1585
1597
  appendBatch,
1586
1598
  ciCommit,
1587
1599
  createClient,
1600
+ errorContextFields,
1588
1601
  errorContextOf,
1589
1602
  failureOf,
1590
1603
  filesOf,
@@ -541,6 +541,16 @@ declare function repoRootOf(dir: string, stopAt?: string): string | undefined;
541
541
  * searched for credentials: the platform does that before its own cut (ADR-0005).
542
542
  */
543
543
  declare function errorContextOf(attempt: FailedAttempt, home?: string): string;
544
+ /**
545
+ * The `errorContext` and `errorContextOmitted` keys of a result (plune-ai/plune#1281 AC-03), ready to spread:
546
+ * none for an empty text, and `errorContextOmitted` only when the cut took something out, a whole number of at
547
+ * least 1 (the platform refuses 0). Counted in characters of the text as it would have been sent (`.length`,
548
+ * the unit the platform counts in), never bytes; the `…[omitted N lines]…` marker is not counted.
549
+ */
550
+ declare function errorContextFields(attempt: FailedAttempt, home?: string): {
551
+ errorContext?: string;
552
+ errorContextOmitted?: number;
553
+ };
544
554
  /**
545
555
  * The files the runner kept for one attempt, whatever its status: a screenshot of a test that passed
546
556
  * is how a person sees what it checked (plune-ai/plune#913). Which of them the platform takes, the
@@ -642,4 +652,4 @@ interface PlatformClient {
642
652
  }
643
653
  declare function createClient(opts: ClientOptions): PlatformClient;
644
654
 
645
- export { type AssertionRecord, type Attachment, type AttemptError, type ClientFailureKind, type ClientOptions, type ClientOutcome, DEFAULT_FALLBACK_PATH, type DeclaredStep, type DeferredBatch, type DeferredResult, type EnvSettings, type Execution, type ExpectedEntry, type ExternalKeyKind, type FailedAttempt, type FailureDetail, type FrozenSummary, type KeyRef, type PendingResult, type PlatformClient, RESULT_KEY_MAX, type ReporterConfig, type ResultFile, type ResultStatus, type ResultSubmission, type RunKind, type RunMeta, type RunRecord, type RunSession, type RunStats, type RunnerLocation, type SubmitCounts, UNSUPPORTED_VARS, type UnofferedWhy, appendBatch, ciCommit, createClient, errorContextOf, failureOf, filesOf, readEnv, repoRootOf, resultKey, startRun, webLink };
655
+ export { type AssertionRecord, type Attachment, type AttemptError, type ClientFailureKind, type ClientOptions, type ClientOutcome, DEFAULT_FALLBACK_PATH, type DeclaredStep, type DeferredBatch, type DeferredResult, type EnvSettings, type Execution, type ExpectedEntry, type ExternalKeyKind, type FailedAttempt, type FailureDetail, type FrozenSummary, type KeyRef, type PendingResult, type PlatformClient, RESULT_KEY_MAX, type ReporterConfig, type ResultFile, type ResultStatus, type ResultSubmission, type RunKind, type RunMeta, type RunRecord, type RunSession, type RunStats, type RunnerLocation, type SubmitCounts, UNSUPPORTED_VARS, type UnofferedWhy, appendBatch, ciCommit, createClient, errorContextFields, errorContextOf, failureOf, filesOf, readEnv, repoRootOf, resultKey, startRun, webLink };
@@ -541,6 +541,16 @@ declare function repoRootOf(dir: string, stopAt?: string): string | undefined;
541
541
  * searched for credentials: the platform does that before its own cut (ADR-0005).
542
542
  */
543
543
  declare function errorContextOf(attempt: FailedAttempt, home?: string): string;
544
+ /**
545
+ * The `errorContext` and `errorContextOmitted` keys of a result (plune-ai/plune#1281 AC-03), ready to spread:
546
+ * none for an empty text, and `errorContextOmitted` only when the cut took something out, a whole number of at
547
+ * least 1 (the platform refuses 0). Counted in characters of the text as it would have been sent (`.length`,
548
+ * the unit the platform counts in), never bytes; the `…[omitted N lines]…` marker is not counted.
549
+ */
550
+ declare function errorContextFields(attempt: FailedAttempt, home?: string): {
551
+ errorContext?: string;
552
+ errorContextOmitted?: number;
553
+ };
544
554
  /**
545
555
  * The files the runner kept for one attempt, whatever its status: a screenshot of a test that passed
546
556
  * is how a person sees what it checked (plune-ai/plune#913). Which of them the platform takes, the
@@ -642,4 +652,4 @@ interface PlatformClient {
642
652
  }
643
653
  declare function createClient(opts: ClientOptions): PlatformClient;
644
654
 
645
- export { type AssertionRecord, type Attachment, type AttemptError, type ClientFailureKind, type ClientOptions, type ClientOutcome, DEFAULT_FALLBACK_PATH, type DeclaredStep, type DeferredBatch, type DeferredResult, type EnvSettings, type Execution, type ExpectedEntry, type ExternalKeyKind, type FailedAttempt, type FailureDetail, type FrozenSummary, type KeyRef, type PendingResult, type PlatformClient, RESULT_KEY_MAX, type ReporterConfig, type ResultFile, type ResultStatus, type ResultSubmission, type RunKind, type RunMeta, type RunRecord, type RunSession, type RunStats, type RunnerLocation, type SubmitCounts, UNSUPPORTED_VARS, type UnofferedWhy, appendBatch, ciCommit, createClient, errorContextOf, failureOf, filesOf, readEnv, repoRootOf, resultKey, startRun, webLink };
655
+ export { type AssertionRecord, type Attachment, type AttemptError, type ClientFailureKind, type ClientOptions, type ClientOutcome, DEFAULT_FALLBACK_PATH, type DeclaredStep, type DeferredBatch, type DeferredResult, type EnvSettings, type Execution, type ExpectedEntry, type ExternalKeyKind, type FailedAttempt, type FailureDetail, type FrozenSummary, type KeyRef, type PendingResult, type PlatformClient, RESULT_KEY_MAX, type ReporterConfig, type ResultFile, type ResultStatus, type ResultSubmission, type RunKind, type RunMeta, type RunRecord, type RunSession, type RunStats, type RunnerLocation, type SubmitCounts, UNSUPPORTED_VARS, type UnofferedWhy, appendBatch, ciCommit, createClient, errorContextFields, errorContextOf, failureOf, filesOf, readEnv, repoRootOf, resultKey, startRun, webLink };
@@ -400,6 +400,16 @@ function repoRootOf(dir, stopAt) {
400
400
  }
401
401
  }
402
402
  function errorContextOf(attempt, home = homedir2()) {
403
+ return cutErrorContext(attempt, home).text;
404
+ }
405
+ function errorContextFields(attempt, home = homedir2()) {
406
+ const { text, omitted: omitted2 } = cutErrorContext(attempt, home);
407
+ return {
408
+ ...text !== "" ? { errorContext: text } : {},
409
+ ...omitted2 > 0 ? { errorContextOmitted: omitted2 } : {}
410
+ };
411
+ }
412
+ function cutErrorContext(attempt, home) {
403
413
  const text = attempt.errors.map((e) => e.text).filter((t) => t !== "").join("\n\n");
404
414
  return cut(machineless(text, attempt.repoRoot, home));
405
415
  }
@@ -435,7 +445,7 @@ function pathIn(path3) {
435
445
  }
436
446
  var fileNameOf = (name) => /^(?:file:\/\/|[\\/]|~[\\/]|[A-Za-z]:[\\/])/.test(name) ? name.split(/[\\/]/).pop() ?? "" : name;
437
447
  function cut(text) {
438
- if (jsonBytes(text) <= TEXT_LIMIT) return text;
448
+ if (jsonBytes(text) <= TEXT_LIMIT) return { text, omitted: 0 };
439
449
  const lines = text.split("\n");
440
450
  const size = lines.map((line) => jsonBytes(line) + 2);
441
451
  const budget = TEXT_LIMIT - jsonBytes(omitted(lines.length));
@@ -444,7 +454,8 @@ function cut(text) {
444
454
  let tail = lines.length;
445
455
  while (head < tail && used + size[head] <= budget / 2) used += size[head++];
446
456
  while (tail > head && used + size[tail - 1] <= budget) used += size[--tail];
447
- return [...lines.slice(0, head), omitted(tail - head), ...lines.slice(tail)].join("\n");
457
+ const kept = [...lines.slice(0, head), ...lines.slice(tail)].join("\n");
458
+ return { text: [...lines.slice(0, head), omitted(tail - head), ...lines.slice(tail)].join("\n"), omitted: text.length - kept.length };
448
459
  }
449
460
  var omitted = (lines) => `\u2026[omitted ${lines} lines]\u2026`;
450
461
  var METADATA_TYPE = "application/plune.metadata+json";
@@ -1535,6 +1546,7 @@ export {
1535
1546
  appendBatch,
1536
1547
  ciCommit,
1537
1548
  createClient,
1549
+ errorContextFields,
1538
1550
  errorContextOf,
1539
1551
  failureOf,
1540
1552
  filesOf,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plune-ai/cli",
3
- "version": "0.27.0",
3
+ "version": "0.29.0",
4
4
  "description": "AI-powered assertion testing for LLM apps — write assertions, run them against any provider, get a pass/fail report (local, CI, or diff).",
5
5
  "keywords": [
6
6
  "ai",
@@ -64,13 +64,15 @@
64
64
  "@anthropic-ai/sdk": "^0.102.0",
65
65
  "@clack/prompts": "^1.5.1",
66
66
  "ajv": "^8.17.1",
67
- "better-sqlite3": "^12.10.0",
68
67
  "commander": "^12.0.0",
69
68
  "dotenv": "^16.4.0",
70
69
  "openai": "^6.42.0",
71
70
  "yaml": "^2.9.0",
72
71
  "zod": "^4.5.4"
73
72
  },
73
+ "optionalDependencies": {
74
+ "better-sqlite3": "^12.10.0"
75
+ },
74
76
  "devDependencies": {
75
77
  "@huggingface/transformers": "4.2.0",
76
78
  "@types/better-sqlite3": "^7.6.13",