@jay-framework/aiditor 0.20.0 → 0.21.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.
package/dist/index.d.ts CHANGED
@@ -110,11 +110,13 @@ declare const submitTaskAction: _jay_framework_fullstack_component.JayStreamActi
110
110
  declare const cancelAgentTaskAction: _jay_framework_fullstack_component.JayAction<{
111
111
  pageRoute?: string;
112
112
  renderedUrl?: string;
113
+ cancelKey?: string;
113
114
  }, {
114
115
  cancelled: boolean;
115
116
  }> & _jay_framework_fullstack_component.JayActionDefinition<{
116
117
  pageRoute?: string;
117
118
  renderedUrl?: string;
119
+ cancelKey?: string;
118
120
  }, {
119
121
  cancelled: boolean;
120
122
  }, []>;
@@ -384,9 +386,9 @@ declare const generateAddPageBriefFromImageAction: _jay_framework_fullstack_comp
384
386
  referenceAttachments?: undefined;
385
387
  } | {
386
388
  ok: boolean;
387
- markdown: string;
388
- suggestedRoute: string;
389
- suggestedRouteKind: "static" | "dynamic";
389
+ markdown: any;
390
+ suggestedRoute: any;
391
+ suggestedRouteKind: any;
390
392
  referenceAttachments: {
391
393
  id: string;
392
394
  path: string;
@@ -408,9 +410,9 @@ declare const generateAddPageBriefFromImageAction: _jay_framework_fullstack_comp
408
410
  referenceAttachments?: undefined;
409
411
  } | {
410
412
  ok: boolean;
411
- markdown: string;
412
- suggestedRoute: string;
413
- suggestedRouteKind: "static" | "dynamic";
413
+ markdown: any;
414
+ suggestedRoute: any;
415
+ suggestedRouteKind: any;
414
416
  referenceAttachments: {
415
417
  id: string;
416
418
  path: string;
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1
4
  import { makeJayQuery, makeJayStream, makeJayStackComponent, phaseOutput, RenderPipeline } from "@jay-framework/fullstack-component";
2
5
  import { DEV_SERVER_SERVICE } from "@jay-framework/dev-server";
3
6
  import fs, { readFile, readdir } from "fs/promises";
@@ -1086,11 +1089,12 @@ function appendVisualAttachmentLines(body, attachments, indent = "") {
1086
1089
  return;
1087
1090
  }
1088
1091
  body.push(
1089
- `${indent}Attachments (read from disk; belong to this annotation only):`
1092
+ `${indent}Attachments (read from disk; belong to this annotation only; match "image #N" in the instruction):`
1090
1093
  );
1091
- for (const att of attachments) {
1094
+ for (let i = 0; i < attachments.length; i++) {
1095
+ const att = attachments[i];
1092
1096
  body.push(
1093
- `${indent}- ${att.taskCopyPath} (filename: ${att.originalFileName})`
1097
+ `${indent}- Image #${i + 1}: ${att.taskCopyPath} (filename: ${att.originalFileName})`
1094
1098
  );
1095
1099
  }
1096
1100
  }
@@ -1265,6 +1269,13 @@ function buildVisualPromptVideo(config, pageRoute, renderedUrl, videoPath, frame
1265
1269
  }
1266
1270
  return [...preamble, ...body].join("\n");
1267
1271
  }
1272
+ function distinctTimeSecsAscending(annotations) {
1273
+ const s = /* @__PURE__ */ new Set();
1274
+ for (const a of annotations) {
1275
+ s.add(a.timeSec);
1276
+ }
1277
+ return [...s].sort((a, b) => a - b);
1278
+ }
1268
1279
  function persistFile(file, destDir, fileName) {
1269
1280
  fs$1.mkdirSync(destDir, { recursive: true });
1270
1281
  const dest = path.join(destDir, fileName ?? file.name);
@@ -1309,14 +1320,13 @@ const submitTaskAction = makeJayStream("aiditor.submitTask").withFiles().withHan
1309
1320
  }
1310
1321
  const extra = input.extraFiles ?? {};
1311
1322
  const frames = [];
1323
+ const momentTimes = parsed.structuredVideo ? distinctTimeSecsAscending(parsed.structuredVideo.annotations) : [];
1312
1324
  for (let i = 0; ; i++) {
1313
1325
  const markers = extra[`frame_${i}_markers_only`];
1314
1326
  const clean = extra[`frame_${i}_clean`];
1315
1327
  if (!markers && !clean) break;
1316
1328
  const frameDir = path.join(taskDir, "frames", String(i));
1317
- const timeSec = parsed.structuredVideo?.annotations.find(
1318
- (a, idx) => idx === i || a.timeSec !== void 0
1319
- )?.timeSec ?? i;
1329
+ const timeSec = momentTimes[i] ?? i;
1320
1330
  frames.push({
1321
1331
  timeSec,
1322
1332
  frameIndex: i,
@@ -1456,17 +1466,19 @@ const submitTaskAction = makeJayStream("aiditor.submitTask").withFiles().withHan
1456
1466
  });
1457
1467
  const cancelAgentTaskAction = makeJayQuery(
1458
1468
  "aiditor.cancelAgentTask"
1459
- ).withHandler(async (input) => {
1460
- const routeKey = resolveAgentContextKey({
1461
- pageRoute: input.pageRoute ?? "/",
1462
- renderedUrl: input.renderedUrl
1463
- });
1464
- const cancelled = cancelAgentTask(routeKey);
1465
- if (!cancelled) {
1466
- forceReleaseAgentRoute(routeKey);
1469
+ ).withHandler(
1470
+ async (input) => {
1471
+ const routeKey = input.cancelKey?.trim() || resolveAgentContextKey({
1472
+ pageRoute: input.pageRoute ?? "/",
1473
+ renderedUrl: input.renderedUrl
1474
+ });
1475
+ const cancelled = cancelAgentTask(routeKey);
1476
+ if (!cancelled) {
1477
+ forceReleaseAgentRoute(routeKey);
1478
+ }
1479
+ return { cancelled: true };
1467
1480
  }
1468
- return { cancelled: true };
1469
- });
1481
+ );
1470
1482
  class AddPagePromptLoadError extends Error {
1471
1483
  constructor(message) {
1472
1484
  super(message);
@@ -2292,6 +2304,12 @@ When the image is a formal Figma **design definitions** board, apply these rules
2292
2304
  ${designDefinitionsBody}`;
2293
2305
  });
2294
2306
  }
2307
+ class BriefFillCancelledError extends Error {
2308
+ constructor() {
2309
+ super("Stopped by user.");
2310
+ __publicField(this, "name", "BriefFillCancelledError");
2311
+ }
2312
+ }
2295
2313
  const briefFillModelOverride = process.env.AIDITOR_BRIEF_FILL_MODEL?.trim();
2296
2314
  const ALLOWED_IMAGE_MIMES = /* @__PURE__ */ new Set([
2297
2315
  "image/png",
@@ -2459,6 +2477,9 @@ async function runBriefFillAgentQuery(input) {
2459
2477
  thinking: { type: "disabled" }
2460
2478
  }
2461
2479
  })) {
2480
+ if (input.cancelKey && isAgentTaskCancelled(input.cancelKey)) {
2481
+ throw new BriefFillCancelledError();
2482
+ }
2462
2483
  collected.push(message);
2463
2484
  }
2464
2485
  const rawText = extractBriefFillRawText(collected);
@@ -2487,6 +2508,19 @@ async function generateBriefFromImages(input, options) {
2487
2508
  }
2488
2509
  return { markdown };
2489
2510
  }
2511
+ const BRIEF_FILL_CANCEL_PREFIX = "brief-fill:";
2512
+ function resolveBriefFillCancelKey(input) {
2513
+ const targetSuffix = input.target ? `:${input.target}` : "";
2514
+ const requestId = input.requestId?.trim();
2515
+ if (requestId) {
2516
+ return `${BRIEF_FILL_CANCEL_PREFIX}request:${requestId}${targetSuffix}`;
2517
+ }
2518
+ const route = input.pageRoute?.trim();
2519
+ if (route) {
2520
+ return `${BRIEF_FILL_CANCEL_PREFIX}route:${normalizePageRoute(route)}${targetSuffix}`;
2521
+ }
2522
+ return `${BRIEF_FILL_CANCEL_PREFIX}draft${targetSuffix}`;
2523
+ }
2490
2524
  function persistUpload(file, destPath) {
2491
2525
  fs$1.mkdirSync(path.dirname(destPath), { recursive: true });
2492
2526
  fs$1.copyFileSync(file.path, destPath);
@@ -2826,15 +2860,27 @@ const generateAddPageBriefFromImageAction = makeJayQuery(
2826
2860
  }
2827
2861
  try {
2828
2862
  const images = imageFiles.map(readImageAsBase64);
2829
- const result = await generateBriefFromImages(
2830
- {
2831
- target: input.target,
2832
- images,
2833
- contextNotes: input.contextNotes,
2834
- pageRoute: input.pageRoute
2835
- },
2836
- { projectDir }
2837
- );
2863
+ const cancelKey = resolveBriefFillCancelKey({
2864
+ requestId: input.requestId,
2865
+ pageRoute: input.pageRoute,
2866
+ target: input.target
2867
+ });
2868
+ const cancelToken = beginCancellableAgentTask(cancelKey);
2869
+ let result;
2870
+ try {
2871
+ result = await generateBriefFromImages(
2872
+ {
2873
+ target: input.target,
2874
+ images,
2875
+ contextNotes: input.contextNotes,
2876
+ pageRoute: input.pageRoute,
2877
+ cancelKey
2878
+ },
2879
+ { projectDir }
2880
+ );
2881
+ } finally {
2882
+ endCancellableAgentTask(cancelKey, cancelToken);
2883
+ }
2838
2884
  const referenceAttachments = [];
2839
2885
  if (input.requestId) {
2840
2886
  for (const file of imageFiles) {
@@ -2863,6 +2909,9 @@ const generateAddPageBriefFromImageAction = makeJayQuery(
2863
2909
  referenceAttachments
2864
2910
  };
2865
2911
  } catch (err) {
2912
+ if (err instanceof BriefFillCancelledError) {
2913
+ return { ok: false, error: err.message };
2914
+ }
2866
2915
  return {
2867
2916
  ok: false,
2868
2917
  error: err instanceof Error ? err.message : String(err)
@@ -865,14 +865,54 @@ body {
865
865
  min-width: 200px;
866
866
  }
867
867
  .url-bar {
868
+ display: flex;
869
+ align-items: center;
870
+ gap: 4px;
868
871
  font-size: 12px;
869
872
  font-family: var(--harmony-mono);
870
873
  color: var(--harmony-text-secondary);
871
874
  background: var(--harmony-bg-surface);
872
875
  border: 1px solid var(--harmony-border);
873
876
  border-radius: var(--harmony-radius-sm);
874
- padding: 7px 12px;
875
- word-break: break-all;
877
+ padding: 4px 4px 4px 12px;
878
+ }
879
+ .url-bar-text {
880
+ flex: 1;
881
+ min-width: 0;
882
+ overflow: hidden;
883
+ text-overflow: ellipsis;
884
+ white-space: nowrap;
885
+ }
886
+ .url-bar-open-tab {
887
+ flex-shrink: 0;
888
+ display: inline-flex;
889
+ align-items: center;
890
+ justify-content: center;
891
+ width: 28px;
892
+ height: 28px;
893
+ padding: 0;
894
+ border: none;
895
+ border-radius: var(--harmony-radius-sm);
896
+ background: transparent;
897
+ color: var(--harmony-text-muted);
898
+ cursor: pointer;
899
+ transition: color 0.12s ease, background 0.12s ease;
900
+ }
901
+ .url-bar-open-tab:hover:not(:disabled) {
902
+ color: var(--harmony-text);
903
+ background: var(--harmony-bg-hover);
904
+ }
905
+ .url-bar-open-tab:disabled {
906
+ opacity: 0.4;
907
+ cursor: default;
908
+ }
909
+ .url-bar-open-tab:focus-visible {
910
+ outline: 2px solid var(--harmony-primary);
911
+ outline-offset: 1px;
912
+ }
913
+ .url-bar-open-tab .harmony-routes-panel-open-tab-icon {
914
+ width: 24px;
915
+ height: 24px;
876
916
  }
877
917
 
878
918
  .preview-loading {
@@ -1179,6 +1219,19 @@ body {
1179
1219
  .visual-attachment-remove-file:hover {
1180
1220
  color: var(--harmony-danger);
1181
1221
  }
1222
+ .visual-attachment-chip-actions {
1223
+ display: flex;
1224
+ flex-direction: column;
1225
+ align-items: center;
1226
+ gap: 2px;
1227
+ flex-shrink: 0;
1228
+ }
1229
+ .visual-attachment-number {
1230
+ font-size: 10px;
1231
+ font-weight: 600;
1232
+ color: var(--harmony-primary);
1233
+ line-height: 1;
1234
+ }
1182
1235
  .file-input-hidden {
1183
1236
  display: none;
1184
1237
  }
@@ -2544,12 +2597,28 @@ body {
2544
2597
  padding: 24px;
2545
2598
  box-sizing: border-box;
2546
2599
  }
2600
+ .add-page-brief-fill-popover-stack {
2601
+ display: flex;
2602
+ flex-direction: column;
2603
+ align-items: center;
2604
+ gap: 10px;
2605
+ width: min(420px, 100%);
2606
+ max-height: 90%;
2607
+ }
2608
+ .add-page-brief-fill-stop-confirm {
2609
+ align-self: center;
2610
+ max-width: 100%;
2611
+ white-space: normal;
2612
+ text-align: center;
2613
+ flex-wrap: wrap;
2614
+ justify-content: center;
2615
+ }
2547
2616
  .add-page-brief-fill-panel {
2548
2617
  background: var(--harmony-bg-surface);
2549
2618
  border: 1px solid var(--harmony-border);
2550
2619
  border-radius: var(--harmony-radius-md);
2551
- width: min(420px, 100%);
2552
- max-height: 90%;
2620
+ width: 100%;
2621
+ max-height: 100%;
2553
2622
  overflow: auto;
2554
2623
  padding: 14px 16px;
2555
2624
  display: flex;