@jay-framework/aiditor 0.21.0 → 0.22.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/agent-kit-template/plugin/aiditor-add-menu.md +470 -63
- package/dist/index.client.d.ts +219 -7
- package/dist/index.client.js +1184 -272
- package/dist/index.d.ts +21 -23
- package/dist/index.js +106 -137
- package/dist/pages/aiditor/page.css +55 -19
- package/dist/pages/aiditor/page.jay-html +513 -91
- package/dist/pages/aiditor/page.jay-html.d.ts +219 -7
- package/package.json +11 -10
- package/plugin.yaml +2 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as _jay_framework_dev_server from '@jay-framework/dev-server';
|
|
2
2
|
import * as _jay_framework_fullstack_component from '@jay-framework/fullstack-component';
|
|
3
3
|
import { JayFile } from '@jay-framework/fullstack-component';
|
|
4
|
+
import { AddMenuCatalogLintWarning, AddMenuItem, AddMenuPresentation, AddMenuBrowseSize } from '@jay-framework/plugin-validator';
|
|
5
|
+
export { AddMenuItem, AddMenuPresentation } from '@jay-framework/plugin-validator';
|
|
4
6
|
import { PluginSetupContext, PluginSetupResult } from '@jay-framework/stack-server-runtime';
|
|
5
7
|
export { aiditorPage, aiditorShell } from './index.client.js';
|
|
6
8
|
import '@jay-framework/component';
|
|
@@ -121,26 +123,13 @@ declare const cancelAgentTaskAction: _jay_framework_fullstack_component.JayActio
|
|
|
121
123
|
cancelled: boolean;
|
|
122
124
|
}, []>;
|
|
123
125
|
|
|
124
|
-
/**
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
type
|
|
131
|
-
/** Stable unique id, convention: `<pluginName>:<slug>` */
|
|
132
|
-
id: string;
|
|
133
|
-
title: string;
|
|
134
|
-
/** Menu navigation label — not a type system */
|
|
135
|
-
category: string;
|
|
136
|
-
/** Injected verbatim into agent prompt when attached */
|
|
137
|
-
prompt: string;
|
|
138
|
-
pluginName?: string;
|
|
139
|
-
packageName?: string;
|
|
140
|
-
subCategory?: string;
|
|
141
|
-
thumbnail?: string;
|
|
142
|
-
interaction?: AddMenuInteraction;
|
|
143
|
-
};
|
|
126
|
+
/**
|
|
127
|
+
* AIditor Add Menu runtime types.
|
|
128
|
+
* Catalog item schema types come from @jay-framework/plugin-validator (source of truth).
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
/** Runtime catalog warning — same shape as plugin-validator lint findings. */
|
|
132
|
+
type AddMenuCatalogWarning = AddMenuCatalogLintWarning;
|
|
144
133
|
type AddMenuAttachment = {
|
|
145
134
|
itemId: string;
|
|
146
135
|
/** Change Request: set when chip is on a marker; omit = request-level */
|
|
@@ -163,7 +152,7 @@ type AddMenuSubCategoryGroup = {
|
|
|
163
152
|
type ListAddMenuItemsResult = {
|
|
164
153
|
items: AddMenuItem[];
|
|
165
154
|
categories: AddMenuCategoryGroup[];
|
|
166
|
-
warnings:
|
|
155
|
+
warnings: AddMenuCatalogWarning[];
|
|
167
156
|
};
|
|
168
157
|
|
|
169
158
|
type PageBriefAttachment = {
|
|
@@ -765,7 +754,6 @@ type PageAssetEntry = {
|
|
|
765
754
|
source: PageAssetSource;
|
|
766
755
|
itemId?: string;
|
|
767
756
|
thumbnail?: string;
|
|
768
|
-
persistOnPage: boolean;
|
|
769
757
|
addedAt: string;
|
|
770
758
|
/** Stable key for detected entries — used for sync + suppression */
|
|
771
759
|
detectedKey?: string;
|
|
@@ -863,4 +851,14 @@ declare const runAiditorPublishAction: _jay_framework_fullstack_component.JayStr
|
|
|
863
851
|
|
|
864
852
|
declare function setupAiditor(ctx: PluginSetupContext): Promise<PluginSetupResult>;
|
|
865
853
|
|
|
866
|
-
|
|
854
|
+
declare function listAddMenuItems(projectRoot: string): Promise<ListAddMenuItemsResult>;
|
|
855
|
+
|
|
856
|
+
declare function sanitizeAddMenuHtmlFragment(html: string): string;
|
|
857
|
+
|
|
858
|
+
/** Normalize legacy `thumbnail` and explicit `presentation` to one shape (Design Log #30). */
|
|
859
|
+
declare function normalizeAddMenuPresentation(item: Pick<AddMenuItem, "thumbnail" | "presentation">): AddMenuPresentation | undefined;
|
|
860
|
+
|
|
861
|
+
/** Default browse footprint — Design Log #32. */
|
|
862
|
+
declare function normalizeAddMenuBrowseSize(item: Pick<AddMenuItem, "browse">): AddMenuBrowseSize;
|
|
863
|
+
|
|
864
|
+
export { type AddMenuCatalogWarning, type ListAddMenuItemsResult, cancelAgentTaskAction, checkAddPageRouteAction, checkAiditorPublishAction, checkPageAddPageBriefAction, checkPluginUpdateAction, ensureProjectPluginAction, generateAddPageBriefFromImageAction, getAiditorBootstrap, getContractInspectorTagsAction, getPageAssetsAction, getPageMetaAction, getPageParamsAction, getPluginSetupStatusAction, getProjectInfoAction, listAddMenuItems, listAddMenuItemsAction, listFreezesAction, listJayPluginsAction, listPluginContractsAction, normalizeAddMenuBrowseSize, normalizeAddMenuPresentation, openAddPageFromBriefAction, readFileAction, reclassifyAddPageAssetAction, rerunPluginSetupAction, resolveAddMenuContractParamsAction, runAiditorPublishAction, sanitizeAddMenuHtmlFragment, saveAddPageDraftAction, savePageAssetsAction, savePageMetaAction, setupAiditor, startAddPageRequestAction, submitAddPageAction, submitTaskAction, syncAddMenuAttachmentsAction, syncAddPagePluginManifestAction, syncDetectedPageAssetsAction, uploadAddPageAssetAction, writePluginSourceAction };
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
|
9
9
|
import fs$1 from "fs";
|
|
10
10
|
import crypto from "crypto";
|
|
11
11
|
import yaml, { load } from "js-yaml";
|
|
12
|
+
import { validateAddMenuCatalogFile, lintAddMenuCatalog } from "@jay-framework/plugin-validator";
|
|
12
13
|
import { getLogger } from "@jay-framework/logger";
|
|
13
14
|
import { fileURLToPath } from "url";
|
|
14
15
|
import { spawn } from "child_process";
|
|
@@ -341,131 +342,10 @@ function groupAddMenuItems(items) {
|
|
|
341
342
|
return sa.localeCompare(sb);
|
|
342
343
|
}).map(([subCategory, subItems]) => ({
|
|
343
344
|
subCategory,
|
|
344
|
-
items: subItems
|
|
345
|
+
items: subItems
|
|
345
346
|
}))
|
|
346
347
|
}));
|
|
347
348
|
}
|
|
348
|
-
const REJECTED_ITEM_FIELDS = [
|
|
349
|
-
"kind",
|
|
350
|
-
"parameters",
|
|
351
|
-
"component",
|
|
352
|
-
"allowedScopes"
|
|
353
|
-
];
|
|
354
|
-
function isRecord(value) {
|
|
355
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
356
|
-
}
|
|
357
|
-
function requiredString(obj, field, path2, errors) {
|
|
358
|
-
const value = obj[field];
|
|
359
|
-
if (typeof value !== "string" || value.trim().length === 0) {
|
|
360
|
-
errors.push({
|
|
361
|
-
path: `${path2}.${field}`,
|
|
362
|
-
message: "required non-empty string"
|
|
363
|
-
});
|
|
364
|
-
return null;
|
|
365
|
-
}
|
|
366
|
-
return value.trim();
|
|
367
|
-
}
|
|
368
|
-
function optionalString(obj, field) {
|
|
369
|
-
const value = obj[field];
|
|
370
|
-
if (value === void 0) return void 0;
|
|
371
|
-
if (typeof value !== "string") return void 0;
|
|
372
|
-
const trimmed = value.trim();
|
|
373
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
374
|
-
}
|
|
375
|
-
function optionalBoolean(obj, field) {
|
|
376
|
-
const value = obj[field];
|
|
377
|
-
return typeof value === "boolean" ? value : void 0;
|
|
378
|
-
}
|
|
379
|
-
function validateInteraction(raw, path2, errors) {
|
|
380
|
-
if (raw === void 0) return void 0;
|
|
381
|
-
if (!isRecord(raw)) {
|
|
382
|
-
errors.push({ path: path2, message: "interaction must be an object" });
|
|
383
|
-
return void 0;
|
|
384
|
-
}
|
|
385
|
-
const mode = raw.mode;
|
|
386
|
-
if (mode !== "reference" && mode !== "stage-place") {
|
|
387
|
-
errors.push({
|
|
388
|
-
path: `${path2}.mode`,
|
|
389
|
-
message: 'mode must be "reference" or "stage-place"'
|
|
390
|
-
});
|
|
391
|
-
return void 0;
|
|
392
|
-
}
|
|
393
|
-
return {
|
|
394
|
-
mode,
|
|
395
|
-
persistOnPage: optionalBoolean(raw, "persistOnPage"),
|
|
396
|
-
stagePromptTemplate: optionalString(raw, "stagePromptTemplate")
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
function validateAddMenuItem(raw, path2) {
|
|
400
|
-
const errors = [];
|
|
401
|
-
if (!isRecord(raw)) {
|
|
402
|
-
return {
|
|
403
|
-
item: null,
|
|
404
|
-
errors: [{ path: path2, message: "item must be an object" }]
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
for (const field of REJECTED_ITEM_FIELDS) {
|
|
408
|
-
if (field in raw) {
|
|
409
|
-
errors.push({
|
|
410
|
-
path: `${path2}.${field}`,
|
|
411
|
-
message: `field "${field}" is not allowed in Add Menu catalog items`
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
const id = requiredString(raw, "id", path2, errors);
|
|
416
|
-
const title = requiredString(raw, "title", path2, errors);
|
|
417
|
-
const category = requiredString(raw, "category", path2, errors);
|
|
418
|
-
const prompt = requiredString(raw, "prompt", path2, errors);
|
|
419
|
-
if (errors.length > 0 || !id || !title || !category || !prompt) {
|
|
420
|
-
return { item: null, errors };
|
|
421
|
-
}
|
|
422
|
-
const interaction = validateInteraction(
|
|
423
|
-
raw.interaction,
|
|
424
|
-
`${path2}.interaction`,
|
|
425
|
-
errors
|
|
426
|
-
);
|
|
427
|
-
return {
|
|
428
|
-
item: {
|
|
429
|
-
id,
|
|
430
|
-
title,
|
|
431
|
-
category,
|
|
432
|
-
prompt,
|
|
433
|
-
pluginName: optionalString(raw, "pluginName"),
|
|
434
|
-
packageName: optionalString(raw, "packageName"),
|
|
435
|
-
subCategory: optionalString(raw, "subCategory"),
|
|
436
|
-
thumbnail: optionalString(raw, "thumbnail"),
|
|
437
|
-
...interaction ? { interaction } : {}
|
|
438
|
-
},
|
|
439
|
-
errors
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
function validateAddMenuCatalogFile(raw, sourcePath) {
|
|
443
|
-
const errors = [];
|
|
444
|
-
if (!isRecord(raw)) {
|
|
445
|
-
return {
|
|
446
|
-
file: null,
|
|
447
|
-
errors: [{ path: sourcePath, message: "catalog file must be an object" }]
|
|
448
|
-
};
|
|
449
|
-
}
|
|
450
|
-
if (!Array.isArray(raw.items)) {
|
|
451
|
-
return {
|
|
452
|
-
file: null,
|
|
453
|
-
errors: [
|
|
454
|
-
{ path: `${sourcePath}.items`, message: "items must be an array" }
|
|
455
|
-
]
|
|
456
|
-
};
|
|
457
|
-
}
|
|
458
|
-
const items = [];
|
|
459
|
-
raw.items.forEach((entry, index) => {
|
|
460
|
-
const result = validateAddMenuItem(entry, `${sourcePath}.items[${index}]`);
|
|
461
|
-
errors.push(...result.errors);
|
|
462
|
-
if (result.item) items.push(result.item);
|
|
463
|
-
});
|
|
464
|
-
if (items.length === 0 && errors.length > 0) {
|
|
465
|
-
return { file: null, errors };
|
|
466
|
-
}
|
|
467
|
-
return { file: { items }, errors };
|
|
468
|
-
}
|
|
469
349
|
function parsePluginsIndexYaml(yaml2) {
|
|
470
350
|
const entries = [];
|
|
471
351
|
let currentPlugin = null;
|
|
@@ -591,6 +471,7 @@ async function parsePluginYamlContracts(projectRoot, pluginName) {
|
|
|
591
471
|
}
|
|
592
472
|
}
|
|
593
473
|
const ADD_MENU_DIR = path.join("agent-kit", "aiditor", "add-menu");
|
|
474
|
+
const LOCAL_PLUGINS_DIR = path.join("src", "plugins");
|
|
594
475
|
function packageNameFromItem(item) {
|
|
595
476
|
if (item.packageName) return item.packageName;
|
|
596
477
|
if (item.pluginName) return `@jay-framework/${item.pluginName}`;
|
|
@@ -606,6 +487,39 @@ function pluginNameFromItem(item) {
|
|
|
606
487
|
if (colon > 0) return item.id.slice(0, colon);
|
|
607
488
|
return null;
|
|
608
489
|
}
|
|
490
|
+
async function getLocalPluginNames(projectRoot) {
|
|
491
|
+
const names = /* @__PURE__ */ new Set();
|
|
492
|
+
const pluginsDir = path.join(projectRoot, LOCAL_PLUGINS_DIR);
|
|
493
|
+
let entries;
|
|
494
|
+
try {
|
|
495
|
+
entries = await fs.readdir(pluginsDir);
|
|
496
|
+
} catch (e) {
|
|
497
|
+
const code = e && typeof e === "object" && "code" in e ? e.code : void 0;
|
|
498
|
+
if (code === "ENOENT") return names;
|
|
499
|
+
throw e;
|
|
500
|
+
}
|
|
501
|
+
for (const entry of entries) {
|
|
502
|
+
const pluginYaml = path.join(pluginsDir, entry, "plugin.yaml");
|
|
503
|
+
try {
|
|
504
|
+
const yaml2 = await fs.readFile(pluginYaml, "utf-8");
|
|
505
|
+
const nameMatch = yaml2.match(/^name:\s*(.+)\s*$/m);
|
|
506
|
+
if (nameMatch?.[1]) {
|
|
507
|
+
names.add(nameMatch[1].trim());
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
} catch {
|
|
511
|
+
}
|
|
512
|
+
names.add(entry);
|
|
513
|
+
}
|
|
514
|
+
return names;
|
|
515
|
+
}
|
|
516
|
+
function validationErrorToWarning(err) {
|
|
517
|
+
return {
|
|
518
|
+
code: err.code ?? "catalog-validation-error",
|
|
519
|
+
message: `${err.path}: ${err.message}`,
|
|
520
|
+
sourcePath: err.path
|
|
521
|
+
};
|
|
522
|
+
}
|
|
609
523
|
async function listAddMenuItems(projectRoot) {
|
|
610
524
|
const addMenuDir = path.join(projectRoot, ADD_MENU_DIR);
|
|
611
525
|
const warnings = [];
|
|
@@ -623,43 +537,67 @@ async function listAddMenuItems(projectRoot) {
|
|
|
623
537
|
const installed = await getInstalledPlugins(projectRoot);
|
|
624
538
|
const installedPackages = new Set(installed.map((p) => p.packageName));
|
|
625
539
|
const installedPlugins = new Set(installed.map((p) => p.pluginName));
|
|
540
|
+
for (const localName of await getLocalPluginNames(projectRoot)) {
|
|
541
|
+
installedPlugins.add(localName);
|
|
542
|
+
}
|
|
626
543
|
const byId = /* @__PURE__ */ new Map();
|
|
544
|
+
const orderedIds = [];
|
|
545
|
+
const lintBlockedIds = /* @__PURE__ */ new Set();
|
|
627
546
|
for (const filePath of yamlFiles) {
|
|
628
547
|
const relPath = path.relative(projectRoot, filePath);
|
|
629
548
|
let rawContent;
|
|
630
549
|
try {
|
|
631
550
|
rawContent = await fs.readFile(filePath, "utf-8");
|
|
632
551
|
} catch {
|
|
633
|
-
warnings.push(
|
|
552
|
+
warnings.push({
|
|
553
|
+
code: "catalog-read-error",
|
|
554
|
+
message: `Could not read Add Menu catalog file: ${relPath}`,
|
|
555
|
+
sourcePath: relPath
|
|
556
|
+
});
|
|
634
557
|
continue;
|
|
635
558
|
}
|
|
636
559
|
let parsed;
|
|
637
560
|
try {
|
|
638
561
|
parsed = load(rawContent);
|
|
639
562
|
} catch (err) {
|
|
640
|
-
warnings.push(
|
|
641
|
-
|
|
642
|
-
|
|
563
|
+
warnings.push({
|
|
564
|
+
code: "catalog-parse-error",
|
|
565
|
+
message: `Invalid YAML in ${relPath}: ${err instanceof Error ? err.message : String(err)}`,
|
|
566
|
+
sourcePath: relPath
|
|
567
|
+
});
|
|
643
568
|
continue;
|
|
644
569
|
}
|
|
645
570
|
const validated = validateAddMenuCatalogFile(parsed, relPath);
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
571
|
+
for (const err of validated.errors) {
|
|
572
|
+
warnings.push(validationErrorToWarning(err));
|
|
573
|
+
}
|
|
574
|
+
if (!validated.file) {
|
|
650
575
|
continue;
|
|
651
576
|
}
|
|
577
|
+
const linted = lintAddMenuCatalog(validated.file.items, relPath);
|
|
578
|
+
for (const err of linted.errors) {
|
|
579
|
+
warnings.push(err);
|
|
580
|
+
if (err.itemId) lintBlockedIds.add(err.itemId);
|
|
581
|
+
}
|
|
582
|
+
warnings.push(...linted.warnings);
|
|
652
583
|
for (const item of validated.file.items) {
|
|
584
|
+
if (lintBlockedIds.has(item.id)) continue;
|
|
653
585
|
const prev = byId.get(item.id);
|
|
654
586
|
if (prev) {
|
|
655
|
-
warnings.push(
|
|
656
|
-
|
|
657
|
-
|
|
587
|
+
warnings.push({
|
|
588
|
+
code: "catalog-duplicate-id",
|
|
589
|
+
message: `Duplicate Add Menu item id "${item.id}": "${prev.sourcePath}" overwritten by "${relPath}"`,
|
|
590
|
+
itemId: item.id,
|
|
591
|
+
sourcePath: relPath
|
|
592
|
+
});
|
|
593
|
+
byId.set(item.id, { item, sourcePath: relPath });
|
|
594
|
+
continue;
|
|
658
595
|
}
|
|
659
596
|
byId.set(item.id, { item, sourcePath: relPath });
|
|
597
|
+
orderedIds.push(item.id);
|
|
660
598
|
}
|
|
661
599
|
}
|
|
662
|
-
const merged =
|
|
600
|
+
const merged = orderedIds.map((id) => byId.get(id)?.item).filter((item) => item !== void 0);
|
|
663
601
|
const filtered = merged.filter((item) => {
|
|
664
602
|
const pkg = packageNameFromItem(item);
|
|
665
603
|
const plugin = pluginNameFromItem(item);
|
|
@@ -668,7 +606,7 @@ async function listAddMenuItems(projectRoot) {
|
|
|
668
606
|
return false;
|
|
669
607
|
});
|
|
670
608
|
return {
|
|
671
|
-
items: filtered
|
|
609
|
+
items: filtered,
|
|
672
610
|
categories: groupAddMenuItems(filtered),
|
|
673
611
|
warnings
|
|
674
612
|
};
|
|
@@ -941,7 +879,7 @@ function buildRouteMigrationPromptSection(routeMigration) {
|
|
|
941
879
|
].join("\n");
|
|
942
880
|
}
|
|
943
881
|
function buildPageAssetsPromptSection(assets) {
|
|
944
|
-
const active = assets.filter((a) =>
|
|
882
|
+
const active = assets.filter((a) => !a.userRemoved);
|
|
945
883
|
if (active.length === 0) return "";
|
|
946
884
|
const lines = [
|
|
947
885
|
"Page assets (in scope for this page — use when referenced in marker instructions or @mentions):"
|
|
@@ -4423,7 +4361,6 @@ function detectedToPageAssetEntry(detected) {
|
|
|
4423
4361
|
prompt: detected.prompt,
|
|
4424
4362
|
source: "detected",
|
|
4425
4363
|
itemId: detected.pluginName ? `${detected.pluginName}:${detected.contractName ?? ""}` : void 0,
|
|
4426
|
-
persistOnPage: true,
|
|
4427
4364
|
addedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4428
4365
|
detectedKey: detected.detectedKey,
|
|
4429
4366
|
detectedMeta: {
|
|
@@ -4645,6 +4582,34 @@ async function setupAiditor(ctx) {
|
|
|
4645
4582
|
...filesUpdated.length > 0 ? { filesUpdated } : {}
|
|
4646
4583
|
};
|
|
4647
4584
|
}
|
|
4585
|
+
const BLOCKED_TAGS = /<\s*(script|iframe|object|embed)\b[^>]*>[\s\S]*?<\/\s*\1\s*>|<\s*(script|iframe|object|embed)\b[^>]*\/?>/gi;
|
|
4586
|
+
const EVENT_HANDLER_ATTR = /\s+on[a-z]+\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi;
|
|
4587
|
+
const JAVASCRIPT_URL = /\b(href|src|xlink:href)\s*=\s*("|')\s*javascript:/gi;
|
|
4588
|
+
function sanitizeAddMenuHtmlFragment(html) {
|
|
4589
|
+
let result = html;
|
|
4590
|
+
result = result.replace(BLOCKED_TAGS, "");
|
|
4591
|
+
BLOCKED_TAGS.lastIndex = 0;
|
|
4592
|
+
result = result.replace(EVENT_HANDLER_ATTR, "");
|
|
4593
|
+
EVENT_HANDLER_ATTR.lastIndex = 0;
|
|
4594
|
+
result = result.replace(JAVASCRIPT_URL, "");
|
|
4595
|
+
JAVASCRIPT_URL.lastIndex = 0;
|
|
4596
|
+
return result.trim();
|
|
4597
|
+
}
|
|
4598
|
+
function isGifPath(src) {
|
|
4599
|
+
return /\.gif($|\?)/i.test(src.trim());
|
|
4600
|
+
}
|
|
4601
|
+
function normalizeAddMenuPresentation(item) {
|
|
4602
|
+
if (item.presentation) return item.presentation;
|
|
4603
|
+
const thumbnail = item.thumbnail?.trim();
|
|
4604
|
+
if (!thumbnail) return void 0;
|
|
4605
|
+
if (isGifPath(thumbnail)) {
|
|
4606
|
+
return { type: "gif", src: thumbnail };
|
|
4607
|
+
}
|
|
4608
|
+
return { type: "image", src: thumbnail };
|
|
4609
|
+
}
|
|
4610
|
+
function normalizeAddMenuBrowseSize(item) {
|
|
4611
|
+
return item.browse?.size ?? "medium";
|
|
4612
|
+
}
|
|
4648
4613
|
const aiditorShell = makeJayStackComponent().withProps().withSlowlyRender(async () => {
|
|
4649
4614
|
return phaseOutput({}, { headline: "AIditor" });
|
|
4650
4615
|
}).withFastRender(async (_props, carryForward) => {
|
|
@@ -4675,16 +4640,20 @@ export {
|
|
|
4675
4640
|
getPageParamsAction,
|
|
4676
4641
|
getPluginSetupStatusAction,
|
|
4677
4642
|
getProjectInfoAction,
|
|
4643
|
+
listAddMenuItems,
|
|
4678
4644
|
listAddMenuItemsAction,
|
|
4679
4645
|
listFreezesAction,
|
|
4680
4646
|
listJayPluginsAction,
|
|
4681
4647
|
listPluginContractsAction,
|
|
4648
|
+
normalizeAddMenuBrowseSize,
|
|
4649
|
+
normalizeAddMenuPresentation,
|
|
4682
4650
|
openAddPageFromBriefAction,
|
|
4683
4651
|
readFileAction,
|
|
4684
4652
|
reclassifyAddPageAssetAction,
|
|
4685
4653
|
rerunPluginSetupAction,
|
|
4686
4654
|
resolveAddMenuContractParamsAction,
|
|
4687
4655
|
runAiditorPublishAction,
|
|
4656
|
+
sanitizeAddMenuHtmlFragment,
|
|
4688
4657
|
saveAddPageDraftAction,
|
|
4689
4658
|
savePageAssetsAction,
|
|
4690
4659
|
savePageMetaAction,
|
|
@@ -290,7 +290,7 @@ body {
|
|
|
290
290
|
padding: 5px 8px;
|
|
291
291
|
background: var(--harmony-bg-surface);
|
|
292
292
|
border: 1px solid var(--harmony-border);
|
|
293
|
-
border-radius:
|
|
293
|
+
border-radius: 8px;
|
|
294
294
|
box-shadow:
|
|
295
295
|
0 6px 28px rgba(22, 45, 61, 0.14),
|
|
296
296
|
0 2px 6px rgba(22, 45, 61, 0.06);
|
|
@@ -896,7 +896,9 @@ body {
|
|
|
896
896
|
background: transparent;
|
|
897
897
|
color: var(--harmony-text-muted);
|
|
898
898
|
cursor: pointer;
|
|
899
|
-
transition:
|
|
899
|
+
transition:
|
|
900
|
+
color 0.12s ease,
|
|
901
|
+
background 0.12s ease;
|
|
900
902
|
}
|
|
901
903
|
.url-bar-open-tab:hover:not(:disabled) {
|
|
902
904
|
color: var(--harmony-text);
|
|
@@ -1602,11 +1604,24 @@ body {
|
|
|
1602
1604
|
max-height: 94vh;
|
|
1603
1605
|
display: flex;
|
|
1604
1606
|
flex-direction: column;
|
|
1605
|
-
gap:
|
|
1606
|
-
padding:
|
|
1607
|
+
gap: 24px;
|
|
1608
|
+
padding: 32px 32px;
|
|
1607
1609
|
overflow: hidden;
|
|
1608
1610
|
box-shadow: var(--harmony-shadow-lg);
|
|
1609
1611
|
}
|
|
1612
|
+
.video-review-panel {
|
|
1613
|
+
position: relative;
|
|
1614
|
+
}
|
|
1615
|
+
.video-review-header {
|
|
1616
|
+
align-items: flex-start;
|
|
1617
|
+
padding-right: 28px;
|
|
1618
|
+
}
|
|
1619
|
+
.video-review-panel .harmony-modal-close {
|
|
1620
|
+
position: absolute;
|
|
1621
|
+
top: 12px;
|
|
1622
|
+
right: 12px;
|
|
1623
|
+
z-index: 1;
|
|
1624
|
+
}
|
|
1610
1625
|
.video-review-body {
|
|
1611
1626
|
display: flex;
|
|
1612
1627
|
flex-direction: column;
|
|
@@ -1614,23 +1629,27 @@ body {
|
|
|
1614
1629
|
min-height: 0;
|
|
1615
1630
|
flex: 1 1 auto;
|
|
1616
1631
|
}
|
|
1617
|
-
.video-review-tools {
|
|
1618
|
-
display: inline-flex;
|
|
1619
|
-
flex-wrap: nowrap;
|
|
1620
|
-
gap: 2px;
|
|
1621
|
-
align-items: center;
|
|
1622
|
-
width: fit-content;
|
|
1623
|
-
}
|
|
1624
|
-
.video-review-tools .visual-tool-btn {
|
|
1625
|
-
padding: 7px 8px;
|
|
1626
|
-
min-width: 28px;
|
|
1627
|
-
}
|
|
1628
1632
|
.video-review-capture-root {
|
|
1633
|
+
position: relative;
|
|
1629
1634
|
flex: 0 1 auto;
|
|
1630
1635
|
min-height: 0;
|
|
1631
1636
|
max-height: min(56vh, 480px);
|
|
1632
1637
|
overflow: hidden;
|
|
1633
1638
|
}
|
|
1639
|
+
.video-review-toolbar-wrap {
|
|
1640
|
+
position: absolute;
|
|
1641
|
+
bottom: 12px;
|
|
1642
|
+
left: 50%;
|
|
1643
|
+
transform: translateX(-50%);
|
|
1644
|
+
z-index: 12;
|
|
1645
|
+
pointer-events: none;
|
|
1646
|
+
}
|
|
1647
|
+
.video-review-toolbar-wrap > * {
|
|
1648
|
+
pointer-events: auto;
|
|
1649
|
+
}
|
|
1650
|
+
.video-review-toolbar-wrap .annotate-dock {
|
|
1651
|
+
border-radius: 8px;
|
|
1652
|
+
}
|
|
1634
1653
|
.video-review-capture-root .preview-frame {
|
|
1635
1654
|
width: 100%;
|
|
1636
1655
|
height: auto;
|
|
@@ -1638,6 +1657,9 @@ body {
|
|
|
1638
1657
|
max-height: min(56vh, 480px);
|
|
1639
1658
|
object-fit: contain;
|
|
1640
1659
|
display: block;
|
|
1660
|
+
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
1661
|
+
border-radius: 8px;
|
|
1662
|
+
box-sizing: border-box;
|
|
1641
1663
|
}
|
|
1642
1664
|
.snapshot-panel {
|
|
1643
1665
|
width: min(1200px, 96vw);
|
|
@@ -1647,10 +1669,12 @@ body {
|
|
|
1647
1669
|
.snapshot-header {
|
|
1648
1670
|
display: flex;
|
|
1649
1671
|
justify-content: space-between;
|
|
1650
|
-
align-items: center;
|
|
1651
1672
|
gap: 12px;
|
|
1652
1673
|
flex-wrap: wrap;
|
|
1653
1674
|
}
|
|
1675
|
+
.snapshot-header {
|
|
1676
|
+
align-items: center;
|
|
1677
|
+
}
|
|
1654
1678
|
.video-review-title,
|
|
1655
1679
|
.snapshot-title {
|
|
1656
1680
|
font-size: 15px;
|
|
@@ -1658,9 +1682,21 @@ body {
|
|
|
1658
1682
|
color: var(--harmony-text);
|
|
1659
1683
|
margin: 0;
|
|
1660
1684
|
}
|
|
1661
|
-
.video-review-
|
|
1685
|
+
.video-review-title {
|
|
1686
|
+
font-size: 20px;
|
|
1687
|
+
}
|
|
1688
|
+
.video-review-subtitle {
|
|
1689
|
+
font-size: 16px;
|
|
1690
|
+
color: var(--harmony-text-secondary);
|
|
1691
|
+
margin: 4px 0 0;
|
|
1692
|
+
line-height: 1.35;
|
|
1693
|
+
}
|
|
1694
|
+
.video-review-time {
|
|
1695
|
+
flex-shrink: 0;
|
|
1662
1696
|
font-size: 12px;
|
|
1663
1697
|
color: var(--harmony-text-muted);
|
|
1698
|
+
font-variant-numeric: tabular-nums;
|
|
1699
|
+
white-space: nowrap;
|
|
1664
1700
|
}
|
|
1665
1701
|
.snapshot-tools {
|
|
1666
1702
|
display: flex;
|
|
@@ -2304,7 +2340,7 @@ body {
|
|
|
2304
2340
|
.add-menu-picker-search-icon {
|
|
2305
2341
|
color: var(--harmony-text-muted);
|
|
2306
2342
|
font-size: 30px;
|
|
2307
|
-
line-height:
|
|
2343
|
+
line-height: 0;
|
|
2308
2344
|
flex-shrink: 0;
|
|
2309
2345
|
}
|
|
2310
2346
|
.add-menu-picker-search-input {
|
|
@@ -3874,7 +3910,7 @@ body {
|
|
|
3874
3910
|
}
|
|
3875
3911
|
.add-menu-dock-subhint {
|
|
3876
3912
|
margin: 0;
|
|
3877
|
-
padding:
|
|
3913
|
+
padding: 2px 18px 6px;
|
|
3878
3914
|
font-size: 12px;
|
|
3879
3915
|
line-height: 1.35;
|
|
3880
3916
|
color: var(--harmony-text-secondary);
|