akari-video 1.3.0-beta.2 → 1.3.0-beta.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akari-video",
3
- "version": "1.3.0-beta.2",
3
+ "version": "1.3.0-beta.3",
4
4
  "description": "AKARI Video launcher CLI — start an AI-edited video project from any directory: scaffold, connection check, then hand over to Claude Code (or opencode). AKARI Video を opencode や Claude Code で、どのディレクトリからでも始めるための `akari` ランチャー CLI。接続確認(doctor)→ 未セットアップならプロジェクト雛形を作成 → AI エージェントを起動する。外部 npm 依存ゼロ(Node.js 組み込みモジュールのみ)。",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akari-video",
3
- "version": "1.3.0-beta.2",
3
+ "version": "1.3.0-beta.3",
4
4
  "description": "AKARI Video launcher CLI — start an AI-edited video project from any directory: scaffold, connection check, then hand over to Claude Code (or opencode). AKARI Video を opencode や Claude Code で、どのディレクトリからでも始めるための `akari` ランチャー CLI。接続確認(doctor)→ 未セットアップならプロジェクト雛形を作成 → AI エージェントを起動する。外部 npm 依存ゼロ(Node.js 組み込みモジュールのみ)。 [akari-video npm vendor: bin/akari.mjs is reference-only. These CLI entrypoints are not included in the akari-video npm package. Use `akari doctor --json` and run the path reported in `render_cut.path`. Full installations provide it in a monorepo checkout, ~/.akari/app, /Applications/AKARI Video.app/Contents/Resources/packages, or %LOCALAPPDATA%\\Programs\\@akari-videoshell\\resources\\packages.]",
5
5
  "type": "module",
6
6
  "files": [
@@ -422,6 +422,8 @@ function elementBoxCompanions(style, parentStyle, width, height) {
422
422
  let selectedId = null;
423
423
  let selectedIds = [];
424
424
  let elementFocus = null;
425
+ // Inner selection belongs only to the currently selected telop, never to edit.json.
426
+ let telopInnerId = null;
425
427
  let elementGeometryCache = null;
426
428
  let elementNudge = null;
427
429
  let elementNudgeTimer = null;
@@ -1819,8 +1821,11 @@ function elementBoxCompanions(style, parentStyle, width, height) {
1819
1821
 
1820
1822
  function clearSelection() {
1821
1823
  const hadElementFocus = window.akari.capabilities?.elementSelection === true && Boolean(selectedElementFocus());
1824
+ const hadTelopSelection = window.akari.capabilities?.elementSelection === true
1825
+ && selectedOverlay && isTelopOverlay(selectedOverlay);
1822
1826
  flushElementNudge();
1823
1827
  elementFocus = null;
1828
+ telopInnerId = null;
1824
1829
  if (activeRotate) cancelRotate();
1825
1830
  if (activeLine) finishLineEndpoint(true);
1826
1831
  flushNudge();
@@ -1839,7 +1844,7 @@ function elementBoxCompanions(style, parentStyle, width, height) {
1839
1844
  selectionFrame?.remove();
1840
1845
  selectionFrame = null;
1841
1846
  hideSnapGuides();
1842
- if (hadElementFocus) renderScopeBreadcrumb();
1847
+ if (hadElementFocus || hadTelopSelection) renderScopeBreadcrumb();
1843
1848
  }
1844
1849
 
1845
1850
  function handleSelectedOverlayUnavailable(container) {
@@ -1879,24 +1884,41 @@ function elementBoxCompanions(style, parentStyle, width, height) {
1879
1884
  selectedOverlay.setAttribute('data-akari-interaction-selected', 'true');
1880
1885
  reconcileElementFocus();
1881
1886
  } else {
1887
+ const keepTelopInner = selectedId === nextId && telopInnerId === nextId
1888
+ && selectedIds.length === 1 && !groupSelection;
1882
1889
  clearSelection();
1883
1890
  selectedOverlay = container;
1884
1891
  selectedId = nextId;
1885
1892
  selectedIds = selectedId === null ? [] : [selectedId];
1893
+ if (keepTelopInner) telopInnerId = nextId;
1886
1894
  selectedOverlay.setAttribute("data-akari-interaction-selected", "true");
1887
1895
  }
1888
1896
  }
1889
1897
 
1890
1898
  refreshSelectionFrame();
1899
+ if (window.akari.capabilities?.elementSelection === true && isTelopOverlay(selectedOverlay)) renderScopeBreadcrumb();
1891
1900
  startSelectionTracking();
1892
1901
  return true;
1893
1902
  }
1894
1903
 
1895
- function canFocusElement(container) {
1904
+ function elementSelectionEnabled(container) {
1896
1905
  if (window.akari.capabilities?.elementSelection !== true || !container || selectedIds.length > 1) return false;
1897
1906
  return window.akari.state?.summary?.overlays?.some(overlay => overlay.id === container.dataset.overlayId
1898
1907
  && overlay.elementSelection === true) === true;
1899
1908
  }
1909
+ function canFocusElement(container) {
1910
+ return elementSelectionEnabled(container)
1911
+ && (!isTelopOverlay(container) || telopInnerId === selectedId && selectedId === container.dataset.overlayId);
1912
+ }
1913
+ function setTelopInnerSelection(overlayId, inner) {
1914
+ if (typeof overlayId !== 'string' || selectedId !== overlayId || selectedIds.length !== 1
1915
+ || groupSelection || !selectedOverlay || !isTelopOverlay(selectedOverlay)
1916
+ || !elementSelectionEnabled(selectedOverlay)) return false;
1917
+ telopInnerId = inner === true ? overlayId : null;
1918
+ if (!telopInnerId && selectedElementFocus()) focusElement(null);
1919
+ hideHover();
1920
+ return true;
1921
+ }
1900
1922
  function focusedElement() {
1901
1923
  if (!selectedElementFocus() || !selectedOverlay) return null;
1902
1924
  const root = fragmentRoot(selectedOverlay);
@@ -1929,6 +1951,7 @@ function elementBoxCompanions(style, parentStyle, width, height) {
1929
1951
  const ref = element && elementAddress(root, element);
1930
1952
  const next = ref ? { overlayId: selectedId, ref, tag: element.tagName.toLowerCase(),
1931
1953
  label: elementLabel(root, element) } : null;
1954
+ if (!next && telopInnerId === selectedId) telopInnerId = null;
1932
1955
  if (elementFocus?.ref === next?.ref && elementFocus?.overlayId === next?.overlayId) return;
1933
1956
  flushElementNudge();
1934
1957
  elementFocus = next;
@@ -2063,7 +2086,8 @@ function elementBoxCompanions(style, parentStyle, width, height) {
2063
2086
  clearBreadcrumbHover();
2064
2087
  const entries = [];
2065
2088
  const append = (label, action, target) => entries.push({ label, action, target });
2066
- if (selectedElementFocus() && selectedOverlay) {
2089
+ if (selectedOverlay && (selectedElementFocus() || window.akari.capabilities?.elementSelection === true
2090
+ && selectedIds.length === 1 && isTelopOverlay(selectedOverlay))) {
2067
2091
  append('全体', () => { clearSelection(); publishScopedSelection(); }, { kind: 'stage' });
2068
2092
  for (const id of lineage(selectionTree(), scopeId)) {
2069
2093
  append(treeNode(id)?.label ?? id, () => applyScopedSelection({ selectId: id, scopeId: treeNode(id)?.parentId ?? null }),
@@ -4383,7 +4407,8 @@ function elementBoxCompanions(style, parentStyle, width, height) {
4383
4407
  if (activeEdit?.container === hit && eventHitsElement(event, activeEdit.element)) return;
4384
4408
  clickOrigin.scopedHit = true;
4385
4409
  if (activeEdit) void commitEdit();
4386
- if (window.akari.capabilities?.elementSelection === true && event.isTrusted && !event.shiftKey) {
4410
+ if (window.akari.capabilities?.elementSelection === true && event.isTrusted && !event.shiftKey
4411
+ && (!isTelopOverlay(hit) || canFocusElement(hit))) {
4387
4412
  const root = fragmentRoot(hit);
4388
4413
  const target = event.target instanceof Element && root?.contains(event.target)
4389
4414
  ? nearestSelectableElement(root, event.target, stage?.getBoundingClientRect(), selectionOptions(root)) : null;
@@ -4404,7 +4429,8 @@ function elementBoxCompanions(style, parentStyle, width, height) {
4404
4429
  const focused = focusedElement();
4405
4430
  if (focused && isSelectionContainer(focused) && focused.contains(event.target)) {
4406
4431
  clickOrigin.preservedContainer = true;
4407
- } else if (clickOrigin?.hitId === selectedId) {
4432
+ } else if ((!isTelopOverlay(selectedOverlay) || canFocusElement(selectedOverlay))
4433
+ && clickOrigin?.hitId === selectedId) {
4408
4434
  focusElement(elementByAddress(fragmentRoot(selectedOverlay), clickOrigin.elementRef));
4409
4435
  } else focusElementAt(selectedOverlay, event);
4410
4436
  } else if (selectedElementFocus()) focusElement(null);
@@ -5209,7 +5235,9 @@ function elementBoxCompanions(style, parentStyle, width, height) {
5209
5235
  if (window.akari.capabilities?.elementSelection === true
5210
5236
  && event.isTrusted && !event.shiftKey && selectedOverlay) {
5211
5237
  if (clickOrigin?.preservedContainer) focusElementAt(selectedOverlay, event);
5212
- else if (!nextId && clickOrigin?.hitId === selectedId) {
5238
+ else if ((!isTelopOverlay(selectedOverlay) || canFocusElement(selectedOverlay))
5239
+ && (!nextId || isTelopOverlay(selectedOverlay) && telopInnerId === selectedId
5240
+ && nextId === selectedId) && clickOrigin?.hitId === selectedId) {
5213
5241
  focusElement(elementByAddress(fragmentRoot(selectedOverlay), clickOrigin.elementRef));
5214
5242
  } else focusElementAt(selectedOverlay, event);
5215
5243
  }
@@ -5288,10 +5316,12 @@ function elementBoxCompanions(style, parentStyle, width, height) {
5288
5316
  }
5289
5317
  }
5290
5318
  if (event.key === 'Enter' && !event.shiftKey && !activeEdit && !selectedElementFocus()
5291
- && selectedOverlay && canFocusElement(selectedOverlay)) {
5319
+ && selectedOverlay && elementSelectionEnabled(selectedOverlay)
5320
+ && (!isTelopOverlay(selectedOverlay) || selectedIds.length === 1)) {
5292
5321
  const root = fragmentRoot(selectedOverlay);
5293
5322
  const first = firstSelectableElement(root, stage?.getBoundingClientRect(), selectionOptions(root));
5294
5323
  if (first) {
5324
+ if (isTelopOverlay(selectedOverlay)) telopInnerId = selectedId;
5295
5325
  focusElement(first);
5296
5326
  event.preventDefault(); event.stopPropagation(); event.stopImmediatePropagation();
5297
5327
  return;
@@ -5339,7 +5369,8 @@ function elementBoxCompanions(style, parentStyle, width, height) {
5339
5369
  if (groupSelection) {
5340
5370
  applyScopedSelection(enterScope(selectionTree(), selectedId)); handled(); return;
5341
5371
  }
5342
- if (selectedOverlay) {
5372
+ if (selectedOverlay && (!isTelopOverlay(selectedOverlay)
5373
+ || telopInnerId === selectedId && Boolean(selectedElementFocus()))) {
5343
5374
  const root = fragmentRoot(selectedOverlay);
5344
5375
  const text = root && [root, ...root.querySelectorAll('*')].find(canEditText);
5345
5376
  if (text) { beginEdit(selectedOverlay, text); handled(); }
@@ -5827,6 +5858,9 @@ function elementBoxCompanions(style, parentStyle, width, height) {
5827
5858
  releasePointerOwner,
5828
5859
  get selectedId() { return selectedId; },
5829
5860
  get elementFocus() { return selectedElementFocus(); },
5861
+ get selectedTelop() { return Boolean(selectedOverlay && selectedIds.length === 1 && isTelopOverlay(selectedOverlay)); },
5862
+ get telopInner() { return telopInnerId !== null && telopInnerId === selectedId; },
5863
+ setTelopInnerSelection,
5830
5864
  clearElementFocus() { if (selectedElementFocus()) focusElement(null, { notify: false }); },
5831
5865
  focusElementAtPoint,
5832
5866
  get selectedIds() { return [...selectedIds]; },