niceeval 0.2.0 → 0.3.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,6 +1,7 @@
1
1
  import { useEffect, useState } from "react";
2
2
  import type { ArtifactLoadState, T } from "../shared.ts";
3
3
  import type { ViewResult } from "../types.ts";
4
+ import { artifactUrl } from "../lib/artifact-url.ts";
4
5
  import { asEvents, asSources } from "../lib/guards.ts";
5
6
  import { outcomeClass, outcomeLabel } from "../lib/outcome.ts";
6
7
  import { CodeView, NoSourceBody } from "./CodeView.tsx";
@@ -19,7 +20,7 @@ export function AttemptModal({ result, onClose, t }: { result: ViewResult; onClo
19
20
  let alive = true;
20
21
  const grab = (name: string, has?: boolean): Promise<unknown> =>
21
22
  has
22
- ? fetch("/artifact?p=" + encodeURIComponent(`${base}/${name}`))
23
+ ? fetch(artifactUrl(`${base}/${name}`))
23
24
  .then((r) => (r.ok ? r.json() : null))
24
25
  .catch(() => null)
25
26
  : Promise.resolve(null);
@@ -56,7 +57,13 @@ export function AttemptModal({ result, onClose, t }: { result: ViewResult; onClo
56
57
  {hasCode ? (
57
58
  <CodeView sources={data.sources ?? []} events={data.events || []} assertions={allAssertions} t={t} />
58
59
  ) : data.status !== "loading" ? (
59
- <NoSourceBody assertions={allAssertions} events={data.events || []} t={t} />
60
+ // hasSources 为真却取不到 源码捕获过,是工件文件在当前托管里缺失;和「从未捕获」分开提示。
61
+ <NoSourceBody
62
+ assertions={allAssertions}
63
+ events={data.events || []}
64
+ message={t(result.hasSources && base ? "code.sourceUnavailable" : "code.noSource")}
65
+ t={t}
66
+ />
60
67
  ) : null}
61
68
  {result.hasTrace && base ? (
62
69
  <LazyArtifact type="trace" src={`${base}/trace.json`} t={t} />
@@ -245,12 +245,12 @@ export function AssertDetail({ asserts, t }: { asserts: Assertion[]; t: T }) {
245
245
  * 没源码可叠时(此 run 早于 source-loc,或源码不可读:远程沙箱等)。不退回老的分组视图——
246
246
  * 用代码视图同一套视觉语言:一句说明 + checks(绿过/红不过)+ 原始会话流。重跑即可看到代码视图。
247
247
  */
248
- export function NoSourceBody({ assertions, events, t }: { assertions: Assertion[]; events: TranscriptEvent[]; t: T }) {
248
+ export function NoSourceBody({ assertions, events, message, t }: { assertions: Assertion[]; events: TranscriptEvent[]; message?: string; t: T }) {
249
249
  const checks = assertions || [];
250
250
  return (
251
251
  <div className="nosource">
252
252
  <div className="nosource-note">
253
- {t("code.noSource")}
253
+ {message ?? t("code.noSource")}
254
254
  </div>
255
255
  {checks.length ? (
256
256
  <div className="nosource-block">
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useState } from "react";
2
2
  import type { LazyArtifactType, T } from "../shared.ts";
3
+ import { artifactUrl } from "../lib/artifact-url.ts";
3
4
  import { asEvents, asSpans } from "../lib/guards.ts";
4
5
  import { Trace } from "./Trace.tsx";
5
6
  import { Transcript } from "./Transcript.tsx";
@@ -14,7 +15,7 @@ export function LazyArtifact({ type, src, autoLoad = false, t }: { type: LazyArt
14
15
  if (loaded) return;
15
16
  setLoaded(true);
16
17
  try {
17
- const resp = await fetch("/artifact?p=" + encodeURIComponent(src));
18
+ const resp = await fetch(artifactUrl(src));
18
19
  if (!resp.ok) throw new Error("HTTP " + resp.status);
19
20
  const body = await resp.json();
20
21
  setContent(body);
@@ -98,6 +98,7 @@ export type MessageKey =
98
98
  | "code.checks"
99
99
  | "code.conversation"
100
100
  | "code.noSource"
101
+ | "code.sourceUnavailable"
101
102
  | "assert.pass"
102
103
  | "assert.fail"
103
104
  | "assert.soft"
@@ -208,6 +209,7 @@ const dictionaries: Record<Locale, Dictionary> = {
208
209
  "code.checks": "checks",
209
210
  "code.conversation": "conversation",
210
211
  "code.noSource": "Source was not captured. This run may predate source-loc or the source may be unavailable. Re-run this eval to see the code view.",
212
+ "code.sourceUnavailable": "Source was captured for this run, but its artifact files are missing from this deployment. Re-export with `niceeval view --out <dir>` (directory mode bundles artifacts), or open the results locally with `niceeval view`.",
211
213
  "assert.pass": "pass",
212
214
  "assert.fail": "fail",
213
215
  "assert.soft": "soft",
@@ -315,6 +317,7 @@ const dictionaries: Record<Locale, Dictionary> = {
315
317
  "code.checks": "检查",
316
318
  "code.conversation": "会话",
317
319
  "code.noSource": "源码未捕获。此 run 可能早于 source-loc,或源码不可读。重跑此 eval 即可看到代码视图。",
320
+ "code.sourceUnavailable": "此 run 捕获过源码,但当前部署里缺少它的工件文件。用 `niceeval view --out <目录>` 重新导出(目录模式会带上工件),或在本地 `niceeval view` 查看。",
318
321
  "assert.pass": "通过",
319
322
  "assert.fail": "失败",
320
323
  "assert.soft": "soft",
@@ -0,0 +1,6 @@
1
+ // 工件 fetch 的 URL:相对路径 `artifact/<rel>`。
2
+ // 本地 dev server(server.ts 的 /artifact/ 路由)和目录式静态导出(buildView 拷到 <out>/artifact/)
3
+ // 共用同一布局,前端不需要知道自己被谁托管。相对路径也保证子路径部署(如 host/foo/)不断链。
4
+ export function artifactUrl(rel: string): string {
5
+ return "artifact/" + rel.split("/").map(encodeURIComponent).join("/");
6
+ }