@things-factory/ai-assistant 10.1.223 → 10.1.227

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.
Files changed (105) hide show
  1. package/client/components/assistant-chat.ts +50 -2
  2. package/client/components/assistant-dock.ts +1 -1
  3. package/client/components/assistant-mode.ts +1 -1
  4. package/client/components/entry-review.ts +2 -2
  5. package/client/components/workspace-view.ts +1 -1
  6. package/client/index.ts +1 -1
  7. package/client/pages/assistant-workspace-page.ts +1 -1
  8. package/client/route.ts +1 -1
  9. package/client/utils/attachment-policy.ts +15 -8
  10. package/client/utils/document-text.ts +332 -0
  11. package/client/utils/entry-hash.ts +1 -1
  12. package/client/utils/entry-proposal.ts +1 -1
  13. package/client/utils/entry-workspace.ts +1 -1
  14. package/client/utils/pdf-pages.ts +38 -0
  15. package/client/utils/workspace.ts +1 -1
  16. package/dist-client/components/assistant-chat.d.ts +3 -1
  17. package/dist-client/components/assistant-chat.js +48 -2
  18. package/dist-client/components/assistant-chat.js.map +1 -1
  19. package/dist-client/components/assistant-dock.js +1 -1
  20. package/dist-client/components/assistant-dock.js.map +1 -1
  21. package/dist-client/components/assistant-mode.d.ts +1 -1
  22. package/dist-client/components/assistant-mode.js.map +1 -1
  23. package/dist-client/components/entry-review.d.ts +1 -1
  24. package/dist-client/components/entry-review.js +2 -2
  25. package/dist-client/components/entry-review.js.map +1 -1
  26. package/dist-client/components/workspace-view.js +1 -1
  27. package/dist-client/components/workspace-view.js.map +1 -1
  28. package/dist-client/index.js +1 -1
  29. package/dist-client/index.js.map +1 -1
  30. package/dist-client/pages/assistant-workspace-page.js +1 -1
  31. package/dist-client/pages/assistant-workspace-page.js.map +1 -1
  32. package/dist-client/route.js +1 -1
  33. package/dist-client/route.js.map +1 -1
  34. package/dist-client/tsconfig.tsbuildinfo +1 -1
  35. package/dist-client/utils/attachment-policy.d.ts +2 -2
  36. package/dist-client/utils/attachment-policy.js +9 -5
  37. package/dist-client/utils/attachment-policy.js.map +1 -1
  38. package/dist-client/utils/document-text.d.ts +118 -0
  39. package/dist-client/utils/document-text.js +320 -0
  40. package/dist-client/utils/document-text.js.map +1 -0
  41. package/dist-client/utils/entry-hash.js +1 -1
  42. package/dist-client/utils/entry-hash.js.map +1 -1
  43. package/dist-client/utils/entry-proposal.js +1 -1
  44. package/dist-client/utils/entry-proposal.js.map +1 -1
  45. package/dist-client/utils/entry-workspace.js +1 -1
  46. package/dist-client/utils/entry-workspace.js.map +1 -1
  47. package/dist-client/utils/pdf-pages.d.ts +6 -0
  48. package/dist-client/utils/pdf-pages.js +34 -0
  49. package/dist-client/utils/pdf-pages.js.map +1 -0
  50. package/dist-client/utils/workspace.js +1 -1
  51. package/dist-client/utils/workspace.js.map +1 -1
  52. package/dist-server/service/assistant-mode/assistant-mode-resolver.js +1 -1
  53. package/dist-server/service/assistant-mode/assistant-mode-resolver.js.map +1 -1
  54. package/dist-server/service/assistant-mode/mode-categories.d.ts +3 -3
  55. package/dist-server/service/assistant-mode/mode-categories.js +4 -4
  56. package/dist-server/service/assistant-mode/mode-categories.js.map +1 -1
  57. package/dist-server/service/chat-session/attachment-policy.d.ts +1 -1
  58. package/dist-server/service/chat-session/attachment-policy.js +2 -2
  59. package/dist-server/service/chat-session/attachment-policy.js.map +1 -1
  60. package/dist-server/service/data-entry/entry-apply.d.ts +1 -1
  61. package/dist-server/service/data-entry/entry-apply.js +1 -1
  62. package/dist-server/service/data-entry/entry-apply.js.map +1 -1
  63. package/dist-server/service/data-entry/entry-hash.js +1 -1
  64. package/dist-server/service/data-entry/entry-hash.js.map +1 -1
  65. package/dist-server/service/data-read/read-target.d.ts +1 -1
  66. package/dist-server/service/data-read/read-target.js +2 -2
  67. package/dist-server/service/data-read/read-target.js.map +1 -1
  68. package/dist-server/service/data-read/read-tools.js +5 -5
  69. package/dist-server/service/data-read/read-tools.js.map +1 -1
  70. package/dist-server/service/index.js +1 -1
  71. package/dist-server/service/index.js.map +1 -1
  72. package/dist-server/service/people/index.js +1 -1
  73. package/dist-server/service/people/index.js.map +1 -1
  74. package/dist-server/service/workspace/workspace-blocks.js +1 -1
  75. package/dist-server/service/workspace/workspace-blocks.js.map +1 -1
  76. package/dist-server/service/workspace/workspace-tools.js +1 -1
  77. package/dist-server/service/workspace/workspace-tools.js.map +1 -1
  78. package/dist-server/tsconfig.tsbuildinfo +1 -1
  79. package/package.json +11 -9
  80. package/server/service/assistant-mode/assistant-mode-resolver.ts +1 -1
  81. package/server/service/assistant-mode/mode-categories.ts +4 -4
  82. package/server/service/assistant-mode/mode-front.test.ts +1 -1
  83. package/server/service/assistant-mode/resolve.test.ts +1 -1
  84. package/server/service/chat-session/attachment-policy.ts +7 -5
  85. package/server/service/data-entry/entry-apply.ts +2 -2
  86. package/server/service/data-entry/entry-hash.ts +1 -1
  87. package/server/service/data-read/read-target.ts +2 -2
  88. package/server/service/data-read/read-tools.ts +5 -5
  89. package/server/service/data-read/read-words.test.ts +1 -1
  90. package/server/service/index.ts +1 -1
  91. package/server/service/people/index.ts +1 -1
  92. package/server/service/unattended-run/run-unattended.test.ts +1 -1
  93. package/server/service/workspace/workspace-blocks.ts +1 -1
  94. package/server/service/workspace/workspace-tools.ts +1 -1
  95. package/server/service/workspace/workspace.test.ts +1 -1
  96. package/test/attachment-policy-agree.test.ts +4 -1
  97. package/test/document-text.test.ts +175 -0
  98. package/test/entry-workspace.test.ts +1 -1
  99. package/test/workspace.test.ts +1 -1
  100. package/translations/en.json +6 -0
  101. package/translations/es.json +6 -0
  102. package/translations/ja.json +6 -0
  103. package/translations/ko.json +16 -10
  104. package/translations/ms.json +6 -0
  105. package/translations/zh.json +6 -0
@@ -1,6 +1,6 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  /*
3
- * The blocks of an AI 작업판, drawn (operato-application/design/ai/workspace.md §3).
3
+ * The blocks of an AI 작업 패널, drawn (operato-application/design/ai/workspace.md §3).
4
4
  *
5
5
  * Every kind is drawn here - the model writes no HTML. Charts use the eight validated categorical colours in
6
6
  * a fixed order (dataviz reference palette, light and dark each checked); three of the light ones sit under
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-view.js","sourceRoot":"","sources":["../../client/components/workspace-view.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The blocks of an AI 작업판, drawn (operato-application/design/ai/workspace.md §3).\n *\n * Every kind is drawn here - the model writes no HTML. Charts use the eight validated categorical colours in\n * a fixed order (dataviz reference palette, light and dark each checked); three of the light ones sit under\n * 3:1 against the surface, so every chart carries its legend (two series or more) and a table view.\n */\nimport '@material/web/icon/icon.js'\n\nimport { LitElement, css, html, nothing, svg, type TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js'\n\nimport { i18next } from '@operato/i18n'\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { renderMarkdown } from './markdown.js'\nimport { sortRows, tableCsv, type WorkspaceBlockView, type WorkspaceView } from '../utils/workspace.js'\n\nconst LIGHT = ['#2a78d6', '#eb6834', '#1baf7a', '#eda100', '#e87ba4', '#008300', '#4a3aa7', '#e34948']\nconst DARK = ['#3987e5', '#d95926', '#199e70', '#c98500', '#d55181', '#008300', '#9085e9', '#e66767']\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n String(i18next.t(`ai-assistant.workspace.${key}`, { defaultValue, ...options }))\n\nconst shown = (value: unknown) =>\n value === null || value === undefined ? '' : typeof value === 'number' ? value.toLocaleString(i18next.language || undefined) : String(value)\n\n/*\n * A label cut to the width it has, at the axis size: a wide (Hangul, CJK) character about 11 units, any other about 6.5.\n * The whole label is its title - 「CJ올리브네트웍스」 under a narrow bar ran into the next one (2026-10-24).\n */\nconst charWidth = (char: string) => (/[\\u1100-\\u11ff\\u2e80-\\u9fff\\uac00-\\ud7af\\uff00-\\uffef]/.test(char) ? 11 : 6.5)\nconst fitted = (label: string, width: number) => {\n const room = width * 0.92\n let used = 0\n const chars = [...label]\n for (let i = 0; i < chars.length; i++) {\n used += charWidth(chars[i])\n if (used > room) return `${chars.slice(0, Math.max(1, i - 1)).join('')}…`\n }\n return label\n}\n\n/*\n * An axis step in the reader's short form - 300,000,000 is 「3억」 in Korean and 「300M」 in English - so the axis fits its\n * margin; a mark's own title keeps the whole number. Below ten thousand the number is written whole.\n */\nconst tickShown = (value: number) =>\n Math.abs(value) < 10_000 ? shown(value) : new Intl.NumberFormat(i18next.language || undefined, { notation: 'compact', maximumFractionDigits: 1 }).format(value)\n\n/** Four round steps from zero to above the largest value. */\nfunction ticksFor(max: number): number[] {\n if (!(max > 0)) return [0, 1]\n const raw = max / 4\n const power = 10 ** Math.floor(Math.log10(raw))\n const step = [1, 2, 2.5, 5, 10].map(one => one * power).find(one => one >= raw) ?? raw\n return Array.from({ length: Math.ceil(max / step) + 1 }, (_, i) => Math.round(i * step * 1e6) / 1e6)\n}\n\n@customElement('ox-assistant-workspace-view')\nexport class AssistantWorkspaceView extends LitElement {\n /* The inner scroll areas wear the standard scrollbar, as the dock does. */\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: block;\n color: var(--md-sys-color-on-surface);\n font-size: 14px;\n line-height: 1.5;\n }\n\n section {\n margin: 0 0 20px;\n }\n\n h1,\n h2,\n h3 {\n margin: 24px 0 8px;\n line-height: 1.3;\n }\n\n h1 {\n font-size: 22px;\n }\n\n h2 {\n font-size: 18px;\n }\n\n h3 {\n font-size: 15px;\n }\n\n .metrics {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));\n gap: 10px;\n }\n\n .metric {\n padding: 12px 14px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 10px;\n background: var(--md-sys-color-surface-container-lowest);\n }\n\n .metric .label {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .metric .value {\n font-size: 22px;\n font-weight: 650;\n font-variant-numeric: tabular-nums;\n }\n\n .metric .note {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .bar {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .bar .caption {\n flex: 1;\n }\n\n .bar button {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n\n .bar md-icon {\n --md-icon-size: 16px;\n }\n\n .scroll {\n max-height: 560px;\n overflow: auto;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n }\n\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n\n th,\n td {\n padding: 6px 10px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n text-align: start;\n white-space: nowrap;\n }\n\n th {\n position: sticky;\n top: 0;\n background: var(--md-sys-color-surface-container);\n font-weight: 600;\n }\n\n th button {\n border: 0;\n padding: 0;\n background: none;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n\n td.num,\n th.num {\n text-align: end;\n font-variant-numeric: tabular-nums;\n }\n\n .chart svg {\n width: 100%;\n height: auto;\n display: block;\n }\n\n .chart .grid {\n stroke: var(--md-sys-color-outline-variant);\n stroke-width: 1;\n }\n\n .chart .tick {\n fill: var(--md-sys-color-on-surface-variant);\n font-size: 11px;\n }\n\n .legend {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 14px;\n margin-top: 6px;\n font-size: 12px;\n }\n\n .legend .swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin-inline-end: 5px;\n border-radius: 3px;\n vertical-align: -1px;\n }\n\n .steps {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .steps li {\n display: flex;\n gap: 8px;\n padding: 4px 0;\n }\n\n .steps md-icon {\n --md-icon-size: 18px;\n }\n\n .steps .done md-icon {\n color: var(--md-sys-color-primary);\n }\n\n .steps .failed md-icon {\n color: var(--md-sys-color-error);\n }\n\n .steps .note {\n display: block;\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .unreadable,\n .cut {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n font-style: italic;\n }\n\n .markdown :first-child {\n margin-top: 0;\n }\n\n /*\n * One block in a small frame - a dashboard card (ADR-0160 decision 5). No outer margin, a figure sized to be read\n * across a room, and a table that fills the frame and scrolls inside it.\n */\n :host([compact]) section {\n margin: 0;\n }\n\n :host([compact]) .metrics {\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n }\n\n :host([compact]) .metric {\n border: 0;\n padding: 4px 0;\n background: transparent;\n }\n\n :host([compact]) .metric .value {\n font-size: 30px;\n line-height: 1.2;\n letter-spacing: -0.01em;\n }\n\n :host([compact]) .scroll {\n max-height: var(--assistant-workspace-table-max-height, 320px);\n }\n `\n ]\n\n @property({ attribute: false }) workspace?: WorkspaceView\n /** One block in a small frame - a dashboard card: no outer margin, a large figure, a lower chart. */\n @property({ type: Boolean, reflect: true }) compact = false\n\n @state() private sorts: Record<number, { column: string; direction: 'asc' | 'desc' }> = {}\n @state() private asTable = new Set<number>()\n @state() private dark = false\n\n private themeWatch?: MutationObserver\n\n connectedCallback() {\n super.connectedCallback()\n this.dark = document.body.classList.contains('dark')\n this.themeWatch = new MutationObserver(() => (this.dark = document.body.classList.contains('dark')))\n this.themeWatch.observe(document.body, { attributes: true, attributeFilter: ['class'] })\n }\n\n disconnectedCallback() {\n this.themeWatch?.disconnect()\n super.disconnectedCallback()\n }\n\n render() {\n const blocks = this.workspace?.blocks ?? []\n return html`${blocks.map((block, i) => this.block(block, i))}`\n }\n\n private block(block: WorkspaceBlockView, i: number): TemplateResult {\n switch (block.kind) {\n case 'heading':\n return block.level === 1 ? html`<h1>${block.text}</h1>` : block.level === 3 ? html`<h3>${block.text}</h3>` : html`<h2>${block.text}</h2>`\n case 'text':\n return html`<section class=\"markdown\">${unsafeHTML(renderMarkdown(block.markdown))}</section>`\n case 'metrics':\n return html`<section class=\"metrics\">\n ${(block.items ?? []).map(\n (one: any) => html`<div class=\"metric\">\n <div class=\"label\">${one.label}</div>\n <div class=\"value\">${shown(one.value)}${one.unit ? html` <small>${one.unit}</small>` : nothing}</div>\n ${one.note ? html`<div class=\"note\">${one.note}</div>` : nothing}\n </div>`\n )}\n </section>`\n case 'table':\n return this.table(block, i)\n case 'chart':\n return this.chart(block, i)\n case 'steps':\n return html`<section>\n <ol class=\"steps\">\n ${(block.items ?? []).map(\n (one: any) => html`<li class=${one.state}>\n <md-icon>${{ done: 'check_circle', doing: 'progress_activity', failed: 'error', todo: 'radio_button_unchecked' }[one.state as string] ?? 'radio_button_unchecked'}</md-icon>\n <span>${one.label}${one.note ? html`<span class=\"note\">${one.note}</span>` : nothing}</span>\n </li>`\n )}\n </ol>\n </section>`\n default:\n return html`<section class=\"unreadable\">${t('unreadable', 'a block that cannot be drawn ({reason})', { reason: block.reason ?? block.kind })}</section>`\n }\n }\n\n private table(block: WorkspaceBlockView, i: number): TemplateResult {\n const columns: { name: string; label?: string; type?: string }[] = block.columns ?? []\n const sort = this.sorts[i]\n const rows = sort ? sortRows(block.rows ?? [], sort.column, sort.direction, i18next.language) : block.rows ?? []\n const toggle = (column: string) =>\n (this.sorts = { ...this.sorts, [i]: { column, direction: sort?.column === column && sort.direction === 'asc' ? 'desc' : 'asc' } })\n return html`<section>\n <div class=\"bar\">\n <span class=\"caption\">${block.caption ?? ''} · ${t('rows', '{count} rows', { count: rows.length })}</span>\n <button @click=${() => this.download(block.caption || this.workspace?.title || 'table', columns, rows)}>\n <md-icon>download</md-icon>${t('csv', 'CSV')}\n </button>\n </div>\n ${this.tableOf(columns, rows, sort, toggle)}\n ${block.cut ? html`<div class=\"cut\">${t('cut', '{count} more rows were left out over the limit.', { count: block.cut })}</div>` : nothing}\n </section>`\n }\n\n private tableOf(columns: { name: string; label?: string; type?: string }[], rows: Record<string, any>[], sort?: { column: string; direction: string }, toggle?: (column: string) => void) {\n return html`<div class=\"scroll\">\n <table>\n <thead>\n <tr>\n ${columns.map(\n column => html`<th class=${column.type === 'number' ? 'num' : ''} aria-sort=${sort?.column === column.name ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none'}>\n ${toggle\n ? html`<button @click=${() => toggle(column.name)}>${column.label || column.name}${sort?.column === column.name ? (sort.direction === 'asc' ? ' ▲' : ' ▼') : ''}</button>`\n : column.label || column.name}\n </th>`\n )}\n </tr>\n </thead>\n <tbody>\n ${rows.map(row => html`<tr>${columns.map(column => html`<td class=${column.type === 'number' || typeof row[column.name] === 'number' ? 'num' : ''}>${shown(row[column.name])}</td>`)}</tr>`)}\n </tbody>\n </table>\n </div>`\n }\n\n private chart(block: WorkspaceBlockView, i: number): TemplateResult {\n const colours = this.dark ? DARK : LIGHT\n const x: string[] = block.x ?? []\n const series: { name: string; other?: boolean; values: (number | null)[] }[] = block.series ?? []\n const name = (one: { name: string; other?: boolean }) => (one.other ? t('other', 'other') : one.name)\n const showingTable = this.asTable.has(i)\n const flip = () => {\n const next = new Set(this.asTable)\n next.has(i) ? next.delete(i) : next.add(i)\n this.asTable = next\n }\n\n const bar = html`<div class=\"bar\">\n <span class=\"caption\">${block.caption ?? ''}${block.unit ? ` (${block.unit})` : ''}</span>\n <button @click=${flip}><md-icon>${showingTable ? 'bar_chart' : 'table_rows'}</md-icon>${showingTable ? t('as-chart', 'chart') : t('as-table', 'table')}</button>\n </div>`\n\n if (showingTable) {\n const columns = [{ name: '_x', label: '' }, ...series.map((one, s) => ({ name: `s${s}`, label: name(one), type: 'number' }))]\n const rows = x.map((label, j) => Object.fromEntries([['_x', label], ...series.map((one, s) => [`s${s}`, one.values[j]])]))\n return html`<section class=\"chart\">${bar}${this.tableOf(columns, rows)}</section>`\n }\n\n const W = 640\n const H = this.compact ? 200 : 240\n const left = 56\n const bottom = 28\n const plotW = W - left - 8\n const plotH = H - bottom - 10\n const values = series.flatMap(one => one.values).filter((v): v is number => typeof v === 'number')\n const min = Math.min(0, ...values)\n const ticks = ticksFor(Math.max(...values, 0) - min).map(tick => tick + min)\n const top = ticks[ticks.length - 1] || 1\n const y = (v: number) => 10 + plotH - ((v - min) / (top - min || 1)) * plotH\n const band = plotW / Math.max(1, x.length)\n const everyNth = Math.max(1, Math.ceil(x.length / 12))\n\n const marks =\n block.chart === 'line'\n ? series.map((one, s) => {\n const points = one.values.map((v, j) => (typeof v === 'number' ? [left + band * (j + 0.5), y(v)] : null))\n const path = points.reduce((d, p, j) => (p ? `${d}${d && points[j - 1] ? 'L' : 'M'}${p[0]},${p[1]}` : d), '')\n return svg`<path d=${path} fill=\"none\" stroke=${colours[s % 8]} stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"></path>\n ${points.map((p, j) =>\n p ? svg`<circle cx=${p[0]} cy=${p[1]} r=\"4\" fill=${colours[s % 8]} stroke=\"var(--md-sys-color-surface)\" stroke-width=\"2\"><title>${name(one)} · ${x[j]}: ${shown(one.values[j])}</title></circle>` : nothing\n )}`\n })\n : series.map((one, s) => {\n const inner = band * 0.7\n const width = Math.max(2, inner / series.length - 2)\n return one.values.map((v, j) => {\n if (typeof v !== 'number') return nothing\n const x0 = left + band * j + (band - inner) / 2 + s * (width + 2)\n const y0 = Math.min(y(v), y(0))\n const h = Math.max(1, Math.abs(y(v) - y(0)))\n return svg`<rect x=${x0} y=${y0} width=${width} height=${h} rx=\"3\" fill=${colours[s % 8]}><title>${name(one)} · ${x[j]}: ${shown(v)}</title></rect>`\n })\n })\n\n return html`<section class=\"chart\" role=\"img\" aria-label=${block.caption || series.map(name).join(', ')}>\n ${bar}\n <svg viewBox=\"0 0 ${W} ${H}\">\n ${ticks.map(tick => svg`<line class=\"grid\" x1=${left} x2=${W - 8} y1=${y(tick)} y2=${y(tick)}></line><text class=\"tick\" x=${left - 6} y=${y(tick) + 4} text-anchor=\"end\">${tickShown(tick)}</text>`)}\n ${marks}\n ${x.map((label, j) => (j % everyNth ? nothing : svg`<text class=\"tick\" x=${left + band * (j + 0.5)} y=${H - 8} text-anchor=\"middle\"><title>${label}</title>${fitted(label, band * everyNth)}</text>`))}\n </svg>\n ${series.length > 1\n ? html`<div class=\"legend\">${series.map((one, s) => html`<span><span class=\"swatch\" style=\"background:${colours[s % 8]}\"></span>${name(one)}</span>`)}</div>`\n : nothing}\n </section>`\n }\n\n private download(title: string, columns: { name: string; label?: string }[], rows: Record<string, any>[]) {\n const blob = new Blob([tableCsv(columns, rows)], { type: 'text/csv;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = `${title.replace(/[\\\\/:*?\"<>|]+/g, '-').slice(0, 80)}.csv`\n link.click()\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n }\n}\n"]}
1
+ {"version":3,"file":"workspace-view.js","sourceRoot":"","sources":["../../client/components/workspace-view.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The blocks of an AI 작업 패널, drawn (operato-application/design/ai/workspace.md §3).\n *\n * Every kind is drawn here - the model writes no HTML. Charts use the eight validated categorical colours in\n * a fixed order (dataviz reference palette, light and dark each checked); three of the light ones sit under\n * 3:1 against the surface, so every chart carries its legend (two series or more) and a table view.\n */\nimport '@material/web/icon/icon.js'\n\nimport { LitElement, css, html, nothing, svg, type TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js'\n\nimport { i18next } from '@operato/i18n'\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { renderMarkdown } from './markdown.js'\nimport { sortRows, tableCsv, type WorkspaceBlockView, type WorkspaceView } from '../utils/workspace.js'\n\nconst LIGHT = ['#2a78d6', '#eb6834', '#1baf7a', '#eda100', '#e87ba4', '#008300', '#4a3aa7', '#e34948']\nconst DARK = ['#3987e5', '#d95926', '#199e70', '#c98500', '#d55181', '#008300', '#9085e9', '#e66767']\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n String(i18next.t(`ai-assistant.workspace.${key}`, { defaultValue, ...options }))\n\nconst shown = (value: unknown) =>\n value === null || value === undefined ? '' : typeof value === 'number' ? value.toLocaleString(i18next.language || undefined) : String(value)\n\n/*\n * A label cut to the width it has, at the axis size: a wide (Hangul, CJK) character about 11 units, any other about 6.5.\n * The whole label is its title - 「CJ올리브네트웍스」 under a narrow bar ran into the next one (2026-10-24).\n */\nconst charWidth = (char: string) => (/[\\u1100-\\u11ff\\u2e80-\\u9fff\\uac00-\\ud7af\\uff00-\\uffef]/.test(char) ? 11 : 6.5)\nconst fitted = (label: string, width: number) => {\n const room = width * 0.92\n let used = 0\n const chars = [...label]\n for (let i = 0; i < chars.length; i++) {\n used += charWidth(chars[i])\n if (used > room) return `${chars.slice(0, Math.max(1, i - 1)).join('')}…`\n }\n return label\n}\n\n/*\n * An axis step in the reader's short form - 300,000,000 is 「3억」 in Korean and 「300M」 in English - so the axis fits its\n * margin; a mark's own title keeps the whole number. Below ten thousand the number is written whole.\n */\nconst tickShown = (value: number) =>\n Math.abs(value) < 10_000 ? shown(value) : new Intl.NumberFormat(i18next.language || undefined, { notation: 'compact', maximumFractionDigits: 1 }).format(value)\n\n/** Four round steps from zero to above the largest value. */\nfunction ticksFor(max: number): number[] {\n if (!(max > 0)) return [0, 1]\n const raw = max / 4\n const power = 10 ** Math.floor(Math.log10(raw))\n const step = [1, 2, 2.5, 5, 10].map(one => one * power).find(one => one >= raw) ?? raw\n return Array.from({ length: Math.ceil(max / step) + 1 }, (_, i) => Math.round(i * step * 1e6) / 1e6)\n}\n\n@customElement('ox-assistant-workspace-view')\nexport class AssistantWorkspaceView extends LitElement {\n /* The inner scroll areas wear the standard scrollbar, as the dock does. */\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: block;\n color: var(--md-sys-color-on-surface);\n font-size: 14px;\n line-height: 1.5;\n }\n\n section {\n margin: 0 0 20px;\n }\n\n h1,\n h2,\n h3 {\n margin: 24px 0 8px;\n line-height: 1.3;\n }\n\n h1 {\n font-size: 22px;\n }\n\n h2 {\n font-size: 18px;\n }\n\n h3 {\n font-size: 15px;\n }\n\n .metrics {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));\n gap: 10px;\n }\n\n .metric {\n padding: 12px 14px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 10px;\n background: var(--md-sys-color-surface-container-lowest);\n }\n\n .metric .label {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .metric .value {\n font-size: 22px;\n font-weight: 650;\n font-variant-numeric: tabular-nums;\n }\n\n .metric .note {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .bar {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .bar .caption {\n flex: 1;\n }\n\n .bar button {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n\n .bar md-icon {\n --md-icon-size: 16px;\n }\n\n .scroll {\n max-height: 560px;\n overflow: auto;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n }\n\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n\n th,\n td {\n padding: 6px 10px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n text-align: start;\n white-space: nowrap;\n }\n\n th {\n position: sticky;\n top: 0;\n background: var(--md-sys-color-surface-container);\n font-weight: 600;\n }\n\n th button {\n border: 0;\n padding: 0;\n background: none;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n\n td.num,\n th.num {\n text-align: end;\n font-variant-numeric: tabular-nums;\n }\n\n .chart svg {\n width: 100%;\n height: auto;\n display: block;\n }\n\n .chart .grid {\n stroke: var(--md-sys-color-outline-variant);\n stroke-width: 1;\n }\n\n .chart .tick {\n fill: var(--md-sys-color-on-surface-variant);\n font-size: 11px;\n }\n\n .legend {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 14px;\n margin-top: 6px;\n font-size: 12px;\n }\n\n .legend .swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin-inline-end: 5px;\n border-radius: 3px;\n vertical-align: -1px;\n }\n\n .steps {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .steps li {\n display: flex;\n gap: 8px;\n padding: 4px 0;\n }\n\n .steps md-icon {\n --md-icon-size: 18px;\n }\n\n .steps .done md-icon {\n color: var(--md-sys-color-primary);\n }\n\n .steps .failed md-icon {\n color: var(--md-sys-color-error);\n }\n\n .steps .note {\n display: block;\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .unreadable,\n .cut {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n font-style: italic;\n }\n\n .markdown :first-child {\n margin-top: 0;\n }\n\n /*\n * One block in a small frame - a dashboard card (ADR-0160 decision 5). No outer margin, a figure sized to be read\n * across a room, and a table that fills the frame and scrolls inside it.\n */\n :host([compact]) section {\n margin: 0;\n }\n\n :host([compact]) .metrics {\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n }\n\n :host([compact]) .metric {\n border: 0;\n padding: 4px 0;\n background: transparent;\n }\n\n :host([compact]) .metric .value {\n font-size: 30px;\n line-height: 1.2;\n letter-spacing: -0.01em;\n }\n\n :host([compact]) .scroll {\n max-height: var(--assistant-workspace-table-max-height, 320px);\n }\n `\n ]\n\n @property({ attribute: false }) workspace?: WorkspaceView\n /** One block in a small frame - a dashboard card: no outer margin, a large figure, a lower chart. */\n @property({ type: Boolean, reflect: true }) compact = false\n\n @state() private sorts: Record<number, { column: string; direction: 'asc' | 'desc' }> = {}\n @state() private asTable = new Set<number>()\n @state() private dark = false\n\n private themeWatch?: MutationObserver\n\n connectedCallback() {\n super.connectedCallback()\n this.dark = document.body.classList.contains('dark')\n this.themeWatch = new MutationObserver(() => (this.dark = document.body.classList.contains('dark')))\n this.themeWatch.observe(document.body, { attributes: true, attributeFilter: ['class'] })\n }\n\n disconnectedCallback() {\n this.themeWatch?.disconnect()\n super.disconnectedCallback()\n }\n\n render() {\n const blocks = this.workspace?.blocks ?? []\n return html`${blocks.map((block, i) => this.block(block, i))}`\n }\n\n private block(block: WorkspaceBlockView, i: number): TemplateResult {\n switch (block.kind) {\n case 'heading':\n return block.level === 1 ? html`<h1>${block.text}</h1>` : block.level === 3 ? html`<h3>${block.text}</h3>` : html`<h2>${block.text}</h2>`\n case 'text':\n return html`<section class=\"markdown\">${unsafeHTML(renderMarkdown(block.markdown))}</section>`\n case 'metrics':\n return html`<section class=\"metrics\">\n ${(block.items ?? []).map(\n (one: any) => html`<div class=\"metric\">\n <div class=\"label\">${one.label}</div>\n <div class=\"value\">${shown(one.value)}${one.unit ? html` <small>${one.unit}</small>` : nothing}</div>\n ${one.note ? html`<div class=\"note\">${one.note}</div>` : nothing}\n </div>`\n )}\n </section>`\n case 'table':\n return this.table(block, i)\n case 'chart':\n return this.chart(block, i)\n case 'steps':\n return html`<section>\n <ol class=\"steps\">\n ${(block.items ?? []).map(\n (one: any) => html`<li class=${one.state}>\n <md-icon>${{ done: 'check_circle', doing: 'progress_activity', failed: 'error', todo: 'radio_button_unchecked' }[one.state as string] ?? 'radio_button_unchecked'}</md-icon>\n <span>${one.label}${one.note ? html`<span class=\"note\">${one.note}</span>` : nothing}</span>\n </li>`\n )}\n </ol>\n </section>`\n default:\n return html`<section class=\"unreadable\">${t('unreadable', 'a block that cannot be drawn ({reason})', { reason: block.reason ?? block.kind })}</section>`\n }\n }\n\n private table(block: WorkspaceBlockView, i: number): TemplateResult {\n const columns: { name: string; label?: string; type?: string }[] = block.columns ?? []\n const sort = this.sorts[i]\n const rows = sort ? sortRows(block.rows ?? [], sort.column, sort.direction, i18next.language) : block.rows ?? []\n const toggle = (column: string) =>\n (this.sorts = { ...this.sorts, [i]: { column, direction: sort?.column === column && sort.direction === 'asc' ? 'desc' : 'asc' } })\n return html`<section>\n <div class=\"bar\">\n <span class=\"caption\">${block.caption ?? ''} · ${t('rows', '{count} rows', { count: rows.length })}</span>\n <button @click=${() => this.download(block.caption || this.workspace?.title || 'table', columns, rows)}>\n <md-icon>download</md-icon>${t('csv', 'CSV')}\n </button>\n </div>\n ${this.tableOf(columns, rows, sort, toggle)}\n ${block.cut ? html`<div class=\"cut\">${t('cut', '{count} more rows were left out over the limit.', { count: block.cut })}</div>` : nothing}\n </section>`\n }\n\n private tableOf(columns: { name: string; label?: string; type?: string }[], rows: Record<string, any>[], sort?: { column: string; direction: string }, toggle?: (column: string) => void) {\n return html`<div class=\"scroll\">\n <table>\n <thead>\n <tr>\n ${columns.map(\n column => html`<th class=${column.type === 'number' ? 'num' : ''} aria-sort=${sort?.column === column.name ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none'}>\n ${toggle\n ? html`<button @click=${() => toggle(column.name)}>${column.label || column.name}${sort?.column === column.name ? (sort.direction === 'asc' ? ' ▲' : ' ▼') : ''}</button>`\n : column.label || column.name}\n </th>`\n )}\n </tr>\n </thead>\n <tbody>\n ${rows.map(row => html`<tr>${columns.map(column => html`<td class=${column.type === 'number' || typeof row[column.name] === 'number' ? 'num' : ''}>${shown(row[column.name])}</td>`)}</tr>`)}\n </tbody>\n </table>\n </div>`\n }\n\n private chart(block: WorkspaceBlockView, i: number): TemplateResult {\n const colours = this.dark ? DARK : LIGHT\n const x: string[] = block.x ?? []\n const series: { name: string; other?: boolean; values: (number | null)[] }[] = block.series ?? []\n const name = (one: { name: string; other?: boolean }) => (one.other ? t('other', 'other') : one.name)\n const showingTable = this.asTable.has(i)\n const flip = () => {\n const next = new Set(this.asTable)\n next.has(i) ? next.delete(i) : next.add(i)\n this.asTable = next\n }\n\n const bar = html`<div class=\"bar\">\n <span class=\"caption\">${block.caption ?? ''}${block.unit ? ` (${block.unit})` : ''}</span>\n <button @click=${flip}><md-icon>${showingTable ? 'bar_chart' : 'table_rows'}</md-icon>${showingTable ? t('as-chart', 'chart') : t('as-table', 'table')}</button>\n </div>`\n\n if (showingTable) {\n const columns = [{ name: '_x', label: '' }, ...series.map((one, s) => ({ name: `s${s}`, label: name(one), type: 'number' }))]\n const rows = x.map((label, j) => Object.fromEntries([['_x', label], ...series.map((one, s) => [`s${s}`, one.values[j]])]))\n return html`<section class=\"chart\">${bar}${this.tableOf(columns, rows)}</section>`\n }\n\n const W = 640\n const H = this.compact ? 200 : 240\n const left = 56\n const bottom = 28\n const plotW = W - left - 8\n const plotH = H - bottom - 10\n const values = series.flatMap(one => one.values).filter((v): v is number => typeof v === 'number')\n const min = Math.min(0, ...values)\n const ticks = ticksFor(Math.max(...values, 0) - min).map(tick => tick + min)\n const top = ticks[ticks.length - 1] || 1\n const y = (v: number) => 10 + plotH - ((v - min) / (top - min || 1)) * plotH\n const band = plotW / Math.max(1, x.length)\n const everyNth = Math.max(1, Math.ceil(x.length / 12))\n\n const marks =\n block.chart === 'line'\n ? series.map((one, s) => {\n const points = one.values.map((v, j) => (typeof v === 'number' ? [left + band * (j + 0.5), y(v)] : null))\n const path = points.reduce((d, p, j) => (p ? `${d}${d && points[j - 1] ? 'L' : 'M'}${p[0]},${p[1]}` : d), '')\n return svg`<path d=${path} fill=\"none\" stroke=${colours[s % 8]} stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"></path>\n ${points.map((p, j) =>\n p ? svg`<circle cx=${p[0]} cy=${p[1]} r=\"4\" fill=${colours[s % 8]} stroke=\"var(--md-sys-color-surface)\" stroke-width=\"2\"><title>${name(one)} · ${x[j]}: ${shown(one.values[j])}</title></circle>` : nothing\n )}`\n })\n : series.map((one, s) => {\n const inner = band * 0.7\n const width = Math.max(2, inner / series.length - 2)\n return one.values.map((v, j) => {\n if (typeof v !== 'number') return nothing\n const x0 = left + band * j + (band - inner) / 2 + s * (width + 2)\n const y0 = Math.min(y(v), y(0))\n const h = Math.max(1, Math.abs(y(v) - y(0)))\n return svg`<rect x=${x0} y=${y0} width=${width} height=${h} rx=\"3\" fill=${colours[s % 8]}><title>${name(one)} · ${x[j]}: ${shown(v)}</title></rect>`\n })\n })\n\n return html`<section class=\"chart\" role=\"img\" aria-label=${block.caption || series.map(name).join(', ')}>\n ${bar}\n <svg viewBox=\"0 0 ${W} ${H}\">\n ${ticks.map(tick => svg`<line class=\"grid\" x1=${left} x2=${W - 8} y1=${y(tick)} y2=${y(tick)}></line><text class=\"tick\" x=${left - 6} y=${y(tick) + 4} text-anchor=\"end\">${tickShown(tick)}</text>`)}\n ${marks}\n ${x.map((label, j) => (j % everyNth ? nothing : svg`<text class=\"tick\" x=${left + band * (j + 0.5)} y=${H - 8} text-anchor=\"middle\"><title>${label}</title>${fitted(label, band * everyNth)}</text>`))}\n </svg>\n ${series.length > 1\n ? html`<div class=\"legend\">${series.map((one, s) => html`<span><span class=\"swatch\" style=\"background:${colours[s % 8]}\"></span>${name(one)}</span>`)}</div>`\n : nothing}\n </section>`\n }\n\n private download(title: string, columns: { name: string; label?: string }[], rows: Record<string, any>[]) {\n const blob = new Blob([tableCsv(columns, rows)], { type: 'text/csv;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = `${title.replace(/[\\\\/:*?\"<>|]+/g, '-').slice(0, 80)}.csv`\n link.click()\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n }\n}\n"]}
@@ -20,7 +20,7 @@ export * from './components/assistant-dock.js';
20
20
  export * from './setup-assistant-dock.js';
21
21
  export * from './utils/assistant-surface.js';
22
22
  export * from './utils/assistant-proposals.js';
23
- /* The AI 작업판's blocks, drawn - also a dashboard card's (ADR-0160 decision 5). */
23
+ /* The AI 작업 패널's blocks, drawn - also a dashboard card's (ADR-0160 decision 5). */
24
24
  export * from './components/workspace-view.js';
25
25
  export * from './utils/assistant-ask.js';
26
26
  export * from './utils/assistant-selection.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,gCAAgC,CAAA;AAC9C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,oCAAoC,CAAA;AAClD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,uCAAuC,CAAA;AACrD,cAAc,yCAAyC,CAAA;AACvD,cAAc,wCAAwC,CAAA;AACtD,cAAc,2CAA2C,CAAA;AACzD,cAAc,oCAAoC,CAAA;AAClD,cAAc,2CAA2C,CAAA;AACzD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,iFAAiF;AACjF,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,0GAA0G;AAC1G,cAAc,yCAAyC,CAAA;AACvD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,sCAAsC,CAAA;AACpD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sCAAsC,CAAA","sourcesContent":["/**\n * `@things-factory/ai-assistant` — 대화면.\n *\n * 표준 컴포넌트는 `<ox-assistant-chat>` 이다.\n */\nexport * from './components/assistant-chat.js'\nexport * from './components/chat-defaults.js'\nexport * from './components/assistant-mode.js'\nexport * from './components/markdown.js'\nexport * from './components/chat-echo-dedup.js'\nexport * from './components/chat-input-builder.js'\nexport * from './components/mention-popup.js'\nexport * from './components/mention-popup-helpers.js'\nexport * from './utils/assistant-session-controller.js'\nexport * from './utils/assistant-session-transport.js'\nexport * from './components/assistant-session-toolbar.js'\nexport * from './utils/assistant-session-admin.js'\nexport * from './components/assistant-session-manager.js'\nexport * from './components/assistant-dock.js'\nexport * from './setup-assistant-dock.js'\nexport * from './utils/assistant-surface.js'\nexport * from './utils/assistant-proposals.js'\n/* The AI 작업판's blocks, drawn - also a dashboard card's (ADR-0160 decision 5). */\nexport * from './components/workspace-view.js'\nexport * from './utils/assistant-ask.js'\nexport * from './utils/assistant-selection.js'\n/* 「AI와 작업」 over a list - every application's lists hand their picked rows by it (shared-dock §2-11-1). */\nexport * from './components/assistant-selection-bar.js'\nexport * from './utils/assistant-activity.js'\nexport * from './utils/assistant-request-context.js'\nexport * from './utils/assistant-capability.js'\nexport * from './utils/assistant-capability-read.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,gCAAgC,CAAA;AAC9C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,oCAAoC,CAAA;AAClD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,uCAAuC,CAAA;AACrD,cAAc,yCAAyC,CAAA;AACvD,cAAc,wCAAwC,CAAA;AACtD,cAAc,2CAA2C,CAAA;AACzD,cAAc,oCAAoC,CAAA;AAClD,cAAc,2CAA2C,CAAA;AACzD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,mFAAmF;AACnF,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,0GAA0G;AAC1G,cAAc,yCAAyC,CAAA;AACvD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,sCAAsC,CAAA;AACpD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sCAAsC,CAAA","sourcesContent":["/**\n * `@things-factory/ai-assistant` — 대화면.\n *\n * 표준 컴포넌트는 `<ox-assistant-chat>` 이다.\n */\nexport * from './components/assistant-chat.js'\nexport * from './components/chat-defaults.js'\nexport * from './components/assistant-mode.js'\nexport * from './components/markdown.js'\nexport * from './components/chat-echo-dedup.js'\nexport * from './components/chat-input-builder.js'\nexport * from './components/mention-popup.js'\nexport * from './components/mention-popup-helpers.js'\nexport * from './utils/assistant-session-controller.js'\nexport * from './utils/assistant-session-transport.js'\nexport * from './components/assistant-session-toolbar.js'\nexport * from './utils/assistant-session-admin.js'\nexport * from './components/assistant-session-manager.js'\nexport * from './components/assistant-dock.js'\nexport * from './setup-assistant-dock.js'\nexport * from './utils/assistant-surface.js'\nexport * from './utils/assistant-proposals.js'\n/* The AI 작업 패널's blocks, drawn - also a dashboard card's (ADR-0160 decision 5). */\nexport * from './components/workspace-view.js'\nexport * from './utils/assistant-ask.js'\nexport * from './utils/assistant-selection.js'\n/* 「AI와 작업」 over a list - every application's lists hand their picked rows by it (shared-dock §2-11-1). */\nexport * from './components/assistant-selection-bar.js'\nexport * from './utils/assistant-activity.js'\nexport * from './utils/assistant-request-context.js'\nexport * from './utils/assistant-capability.js'\nexport * from './utils/assistant-capability-read.js'\n"]}
@@ -1,6 +1,6 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  /*
3
- * The AI 작업판 page (operato-application/design/ai/workspace.md).
3
+ * The AI 작업 패널 page (operato-application/design/ai/workspace.md).
4
4
  *
5
5
  * `assistant-workspace?session=<id>&name=<name>[&version=<n>]`, or `?session=<id>&entry=<proposal key>` to review a
6
6
  * 입력안 wide (§6-1) - read only; the card in the dock is where it is entered. It reads the conversation through its own
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-workspace-page.js","sourceRoot":"","sources":["../../client/pages/assistant-workspace-page.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The AI 작업판 page (operato-application/design/ai/workspace.md).\n *\n * `assistant-workspace?session=<id>&name=<name>[&version=<n>]`, or `?session=<id>&entry=<proposal key>` to review a\n * 입력안 wide (§6-1) - read only; the card in the dock is where it is entered. It reads the conversation through its own\n * door (`chatMessages`), so a private conversation shows nothing to someone outside it and a version behind a\n * door the reader cannot pass is not among the versions (ADR-0073). A new version arriving while the page is\n * open is announced, never swapped in under the reader.\n */\nimport '@material/web/icon/icon.js'\nimport '../components/workspace-view.js'\nimport '../components/entry-review.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { navigate, PageView } from '@operato/shell'\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { startSessionActivityFeed, subscribeSessionActivity } from '../utils/assistant-activity.js'\nimport { workspaceAddress, workspaceVersions, type WorkspaceVersion } from '../utils/workspace.js'\nimport { entryForReview, rememberReviewed } from '../utils/entry-workspace.js'\nimport { entryTitle } from '../utils/entry-proposal.js'\n\nconst MESSAGES = gql`\n query ($sessionId: String!, $limit: Int, $offset: Int) {\n chatMessages(sessionId: $sessionId, limit: $limit, offset: $offset) {\n id\n createdAt\n proposalsJson\n }\n }\n`\n\nconst PAGE = 200\nconst MOST = 5000\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n String(i18next.t(`ai-assistant.workspace.${key}`, { defaultValue, ...options }))\n\n@customElement('assistant-workspace-page')\nexport class AssistantWorkspacePage extends localize(i18next)(PageView) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: block;\n overflow: auto;\n padding: 20px 24px 40px;\n box-sizing: border-box;\n background: var(--md-sys-color-surface);\n }\n\n .page {\n max-width: 1100px;\n margin: 0 auto;\n }\n\n /* A 입력안 is as wide as its columns - the reason it left the dock. */\n .page.entry {\n max-width: none;\n }\n\n header {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 16px;\n }\n\n header .what {\n flex: 1;\n min-width: 0;\n }\n\n header h1 {\n margin: 0;\n font-size: 24px;\n line-height: 1.3;\n }\n\n header .summary {\n margin-top: 4px;\n color: var(--md-sys-color-on-surface-variant);\n }\n\n header select {\n padding: 4px 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n background: var(--md-sys-color-surface-container-lowest);\n color: inherit;\n font: inherit;\n }\n\n .notice {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 14px;\n padding: 8px 12px;\n border-radius: 8px;\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n\n .notice button {\n padding: 3px 10px;\n border: 1px solid currentColor;\n border-radius: 6px;\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n\n .empty {\n padding: 40px 0;\n color: var(--md-sys-color-on-surface-variant);\n text-align: center;\n }\n `\n ]\n\n @state() private sessionId = ''\n @state() private name = ''\n @state() private wanted = 0\n @state() private versions: WorkspaceVersion[] = []\n @state() private loading = false\n @state() private failure = ''\n /** A version that arrived after the page was drawn - announced, not shown until asked. */\n @state() private newer = 0\n /** Reviewing a 입력안: its key, what was found, and whether a newer card replaced it. */\n @state() private entryKey = ''\n @state() private entry?: { proposal?: any; createdAt?: string; superseded: boolean }\n\n private unsubscribe?: () => void\n\n get context() {\n if (this.entryKey) return { title: this.entry?.proposal ? entryTitle(this.entry.proposal, (key, options) => String(i18next.t(key, options))) : t('title', 'AI workspace') }\n const shown = this.shown\n return { title: shown?.workspace.title || t('title', 'AI workspace') }\n }\n\n private get shown(): WorkspaceVersion | undefined {\n if (!this.versions.length) return undefined\n return this.versions.find(one => one.version === this.wanted) ?? this.versions[this.versions.length - 1]\n }\n\n connectedCallback() {\n super.connectedCallback()\n startSessionActivityFeed()\n this.unsubscribe = subscribeSessionActivity(activity => {\n if (activity.sessionId === this.sessionId && activity.kind === 'message') void (this.entryKey ? this.loadEntry() : this.load(true))\n })\n }\n\n disconnectedCallback() {\n this.unsubscribe?.()\n super.disconnectedCallback()\n }\n\n async pageUpdated(_changes: any, lifecycle: any) {\n const params = lifecycle?.params ?? {}\n const sessionId = String(params.session || '')\n const name = String(params.name || '')\n const wanted = Number(params.version) || 0\n const entryKey = String(params.entry || '')\n if (entryKey) {\n const changedEntry = sessionId !== this.sessionId || entryKey !== this.entryKey\n this.sessionId = sessionId\n this.entryKey = entryKey\n this.name = ''\n if (changedEntry) await this.loadEntry()\n return\n }\n this.entryKey = ''\n const changed = sessionId !== this.sessionId || name !== this.name\n this.sessionId = sessionId\n this.name = name\n this.wanted = wanted\n if (changed) {\n this.newer = 0\n await this.load(false)\n }\n }\n\n private async load(arriving: boolean) {\n if (!this.sessionId || !this.name) return\n const before = this.versions.length\n if (!arriving) this.loading = true\n this.failure = ''\n try {\n const messages: any[] = []\n for (let offset = 0; offset < MOST; offset += PAGE) {\n const result = await client.query({ query: MESSAGES, variables: { sessionId: this.sessionId, limit: PAGE, offset }, fetchPolicy: 'no-cache' })\n if (result.errors?.length) throw new Error(result.errors[0].message)\n const page = result.data?.chatMessages ?? []\n messages.push(...page)\n if (page.length < PAGE) break\n }\n const versions = workspaceVersions(messages, this.name)\n this.versions = versions\n if (arriving && versions.length > before && before > 0) this.newer = versions[versions.length - 1].version\n } catch (error: any) {\n this.failure = error?.message || String(error)\n } finally {\n this.loading = false\n }\n }\n\n private async readMessages(): Promise<any[]> {\n const messages: any[] = []\n for (let offset = 0; offset < MOST; offset += PAGE) {\n const result = await client.query({ query: MESSAGES, variables: { sessionId: this.sessionId, limit: PAGE, offset }, fetchPolicy: 'no-cache' })\n if (result.errors?.length) throw new Error(result.errors[0].message)\n const page = result.data?.chatMessages ?? []\n messages.push(...page)\n if (page.length < PAGE) break\n }\n return messages\n }\n\n /** The 입력안 under review - remembered as shown, so the card enters only this one (§6-1). */\n private async loadEntry() {\n if (!this.sessionId || !this.entryKey) return\n this.loading = !this.entry\n this.failure = ''\n try {\n const found = entryForReview(await this.readMessages(), this.entryKey)\n this.entry = found\n if (found.proposal && !found.superseded) rememberReviewed(found.proposal)\n } catch (error: any) {\n this.failure = error?.message || String(error)\n } finally {\n this.loading = false\n }\n }\n\n private renderEntry() {\n const found = this.entry\n if (this.loading && !found) return html`<div class=\"empty\">${t('loading', 'loading the workspace…')}</div>`\n if (this.failure) return html`<div class=\"empty\">${t('unreadable-page', 'could not read this workspace: {reason}', { reason: this.failure })}</div>`\n if (!found?.proposal) return html`<div class=\"empty\">${t('entry-not-found', 'there is no proposal here that you can see.')}</div>`\n const p = found.proposal\n return html`<div class=\"page entry\">\n ${found.superseded\n ? html`<div class=\"notice\" role=\"status\">\n <md-icon>update</md-icon>\n <span>${t('entry-superseded', 'a newer card replaced this one in the conversation - review that one.')}</span>\n </div>`\n : html`<div class=\"notice\" role=\"note\">\n <md-icon>touch_app</md-icon>\n <span>${t('entry-press-in-dock', 'this is a review. Enter the rows with the button on the card in the AI dock.')}</span>\n </div>`}\n <header>\n <div class=\"what\">\n <h1>${entryTitle(p, (key, options) => String(i18next.t(key, options)))}</h1>\n ${p.reason || found.createdAt\n ? html`<div class=\"summary\">${[p.reason, found.createdAt ? new Date(found.createdAt).toLocaleString(i18next.language || undefined) : ''].filter(Boolean).join(' · ')}</div>`\n : nothing}\n </div>\n </header>\n <ox-assistant-entry-review wide .proposal=${p}></ox-assistant-entry-review>\n </div>`\n }\n\n private go(version?: number) {\n this.newer = 0\n navigate(workspaceAddress(this.sessionId, this.name, version))\n }\n\n render() {\n if (this.entryKey) return this.renderEntry()\n const shown = this.shown\n if (this.loading && !shown) return html`<div class=\"empty\">${t('loading', 'loading the workspace…')}</div>`\n if (this.failure) return html`<div class=\"empty\">${t('unreadable-page', 'could not read this workspace: {reason}', { reason: this.failure })}</div>`\n /*\n * Nothing to show says only what is true: this reader sees no such workspace. Whether it never existed, is in\n * a private conversation or sits behind a door is not said - saying which would itself tell.\n */\n if (!shown) return html`<div class=\"empty\">${t('not-found', 'there is no workspace here that you can see.')}</div>`\n\n const latest = this.versions[this.versions.length - 1].version\n return html`<div class=\"page\">\n ${this.newer && this.newer !== shown.version\n ? html`<div class=\"notice\" role=\"status\">\n <md-icon>update</md-icon>\n <span>${t('newer', 'a newer version ({version}) is ready.', { version: this.newer })}</span>\n <button @click=${() => this.go(this.newer)}>${t('show-newer', 'show it')}</button>\n </div>`\n : nothing}\n <header>\n <div class=\"what\">\n <h1>${shown.workspace.title}</h1>\n ${shown.workspace.summary ? html`<div class=\"summary\">${shown.workspace.summary}</div>` : nothing}\n </div>\n ${this.versions.length > 1\n ? html`<select aria-label=${t('versions', 'versions')} @change=${(e: Event) => this.go(Number((e.target as HTMLSelectElement).value))}>\n ${this.versions\n .slice()\n .reverse()\n .map(\n one => html`<option value=${one.version} ?selected=${one.version === shown.version}>\n ${t('version', 'version {version} of {of}', { version: one.version, of: latest })}${one.createdAt ? ` · ${new Date(one.createdAt).toLocaleString(i18next.language || undefined)}` : ''}\n </option>`\n )}\n </select>`\n : nothing}\n </header>\n <ox-assistant-workspace-view .workspace=${shown.workspace}></ox-assistant-workspace-view>\n </div>`\n }\n}\n"]}
1
+ {"version":3,"file":"assistant-workspace-page.js","sourceRoot":"","sources":["../../client/pages/assistant-workspace-page.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The AI 작업 패널 page (operato-application/design/ai/workspace.md).\n *\n * `assistant-workspace?session=<id>&name=<name>[&version=<n>]`, or `?session=<id>&entry=<proposal key>` to review a\n * 입력안 wide (§6-1) - read only; the card in the dock is where it is entered. It reads the conversation through its own\n * door (`chatMessages`), so a private conversation shows nothing to someone outside it and a version behind a\n * door the reader cannot pass is not among the versions (ADR-0073). A new version arriving while the page is\n * open is announced, never swapped in under the reader.\n */\nimport '@material/web/icon/icon.js'\nimport '../components/workspace-view.js'\nimport '../components/entry-review.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { navigate, PageView } from '@operato/shell'\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { startSessionActivityFeed, subscribeSessionActivity } from '../utils/assistant-activity.js'\nimport { workspaceAddress, workspaceVersions, type WorkspaceVersion } from '../utils/workspace.js'\nimport { entryForReview, rememberReviewed } from '../utils/entry-workspace.js'\nimport { entryTitle } from '../utils/entry-proposal.js'\n\nconst MESSAGES = gql`\n query ($sessionId: String!, $limit: Int, $offset: Int) {\n chatMessages(sessionId: $sessionId, limit: $limit, offset: $offset) {\n id\n createdAt\n proposalsJson\n }\n }\n`\n\nconst PAGE = 200\nconst MOST = 5000\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n String(i18next.t(`ai-assistant.workspace.${key}`, { defaultValue, ...options }))\n\n@customElement('assistant-workspace-page')\nexport class AssistantWorkspacePage extends localize(i18next)(PageView) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: block;\n overflow: auto;\n padding: 20px 24px 40px;\n box-sizing: border-box;\n background: var(--md-sys-color-surface);\n }\n\n .page {\n max-width: 1100px;\n margin: 0 auto;\n }\n\n /* A 입력안 is as wide as its columns - the reason it left the dock. */\n .page.entry {\n max-width: none;\n }\n\n header {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 16px;\n }\n\n header .what {\n flex: 1;\n min-width: 0;\n }\n\n header h1 {\n margin: 0;\n font-size: 24px;\n line-height: 1.3;\n }\n\n header .summary {\n margin-top: 4px;\n color: var(--md-sys-color-on-surface-variant);\n }\n\n header select {\n padding: 4px 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n background: var(--md-sys-color-surface-container-lowest);\n color: inherit;\n font: inherit;\n }\n\n .notice {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 14px;\n padding: 8px 12px;\n border-radius: 8px;\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n\n .notice button {\n padding: 3px 10px;\n border: 1px solid currentColor;\n border-radius: 6px;\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n\n .empty {\n padding: 40px 0;\n color: var(--md-sys-color-on-surface-variant);\n text-align: center;\n }\n `\n ]\n\n @state() private sessionId = ''\n @state() private name = ''\n @state() private wanted = 0\n @state() private versions: WorkspaceVersion[] = []\n @state() private loading = false\n @state() private failure = ''\n /** A version that arrived after the page was drawn - announced, not shown until asked. */\n @state() private newer = 0\n /** Reviewing a 입력안: its key, what was found, and whether a newer card replaced it. */\n @state() private entryKey = ''\n @state() private entry?: { proposal?: any; createdAt?: string; superseded: boolean }\n\n private unsubscribe?: () => void\n\n get context() {\n if (this.entryKey) return { title: this.entry?.proposal ? entryTitle(this.entry.proposal, (key, options) => String(i18next.t(key, options))) : t('title', 'AI workspace') }\n const shown = this.shown\n return { title: shown?.workspace.title || t('title', 'AI workspace') }\n }\n\n private get shown(): WorkspaceVersion | undefined {\n if (!this.versions.length) return undefined\n return this.versions.find(one => one.version === this.wanted) ?? this.versions[this.versions.length - 1]\n }\n\n connectedCallback() {\n super.connectedCallback()\n startSessionActivityFeed()\n this.unsubscribe = subscribeSessionActivity(activity => {\n if (activity.sessionId === this.sessionId && activity.kind === 'message') void (this.entryKey ? this.loadEntry() : this.load(true))\n })\n }\n\n disconnectedCallback() {\n this.unsubscribe?.()\n super.disconnectedCallback()\n }\n\n async pageUpdated(_changes: any, lifecycle: any) {\n const params = lifecycle?.params ?? {}\n const sessionId = String(params.session || '')\n const name = String(params.name || '')\n const wanted = Number(params.version) || 0\n const entryKey = String(params.entry || '')\n if (entryKey) {\n const changedEntry = sessionId !== this.sessionId || entryKey !== this.entryKey\n this.sessionId = sessionId\n this.entryKey = entryKey\n this.name = ''\n if (changedEntry) await this.loadEntry()\n return\n }\n this.entryKey = ''\n const changed = sessionId !== this.sessionId || name !== this.name\n this.sessionId = sessionId\n this.name = name\n this.wanted = wanted\n if (changed) {\n this.newer = 0\n await this.load(false)\n }\n }\n\n private async load(arriving: boolean) {\n if (!this.sessionId || !this.name) return\n const before = this.versions.length\n if (!arriving) this.loading = true\n this.failure = ''\n try {\n const messages: any[] = []\n for (let offset = 0; offset < MOST; offset += PAGE) {\n const result = await client.query({ query: MESSAGES, variables: { sessionId: this.sessionId, limit: PAGE, offset }, fetchPolicy: 'no-cache' })\n if (result.errors?.length) throw new Error(result.errors[0].message)\n const page = result.data?.chatMessages ?? []\n messages.push(...page)\n if (page.length < PAGE) break\n }\n const versions = workspaceVersions(messages, this.name)\n this.versions = versions\n if (arriving && versions.length > before && before > 0) this.newer = versions[versions.length - 1].version\n } catch (error: any) {\n this.failure = error?.message || String(error)\n } finally {\n this.loading = false\n }\n }\n\n private async readMessages(): Promise<any[]> {\n const messages: any[] = []\n for (let offset = 0; offset < MOST; offset += PAGE) {\n const result = await client.query({ query: MESSAGES, variables: { sessionId: this.sessionId, limit: PAGE, offset }, fetchPolicy: 'no-cache' })\n if (result.errors?.length) throw new Error(result.errors[0].message)\n const page = result.data?.chatMessages ?? []\n messages.push(...page)\n if (page.length < PAGE) break\n }\n return messages\n }\n\n /** The 입력안 under review - remembered as shown, so the card enters only this one (§6-1). */\n private async loadEntry() {\n if (!this.sessionId || !this.entryKey) return\n this.loading = !this.entry\n this.failure = ''\n try {\n const found = entryForReview(await this.readMessages(), this.entryKey)\n this.entry = found\n if (found.proposal && !found.superseded) rememberReviewed(found.proposal)\n } catch (error: any) {\n this.failure = error?.message || String(error)\n } finally {\n this.loading = false\n }\n }\n\n private renderEntry() {\n const found = this.entry\n if (this.loading && !found) return html`<div class=\"empty\">${t('loading', 'loading the workspace…')}</div>`\n if (this.failure) return html`<div class=\"empty\">${t('unreadable-page', 'could not read this workspace: {reason}', { reason: this.failure })}</div>`\n if (!found?.proposal) return html`<div class=\"empty\">${t('entry-not-found', 'there is no proposal here that you can see.')}</div>`\n const p = found.proposal\n return html`<div class=\"page entry\">\n ${found.superseded\n ? html`<div class=\"notice\" role=\"status\">\n <md-icon>update</md-icon>\n <span>${t('entry-superseded', 'a newer card replaced this one in the conversation - review that one.')}</span>\n </div>`\n : html`<div class=\"notice\" role=\"note\">\n <md-icon>touch_app</md-icon>\n <span>${t('entry-press-in-dock', 'this is a review. Enter the rows with the button on the card in the AI dock.')}</span>\n </div>`}\n <header>\n <div class=\"what\">\n <h1>${entryTitle(p, (key, options) => String(i18next.t(key, options)))}</h1>\n ${p.reason || found.createdAt\n ? html`<div class=\"summary\">${[p.reason, found.createdAt ? new Date(found.createdAt).toLocaleString(i18next.language || undefined) : ''].filter(Boolean).join(' · ')}</div>`\n : nothing}\n </div>\n </header>\n <ox-assistant-entry-review wide .proposal=${p}></ox-assistant-entry-review>\n </div>`\n }\n\n private go(version?: number) {\n this.newer = 0\n navigate(workspaceAddress(this.sessionId, this.name, version))\n }\n\n render() {\n if (this.entryKey) return this.renderEntry()\n const shown = this.shown\n if (this.loading && !shown) return html`<div class=\"empty\">${t('loading', 'loading the workspace…')}</div>`\n if (this.failure) return html`<div class=\"empty\">${t('unreadable-page', 'could not read this workspace: {reason}', { reason: this.failure })}</div>`\n /*\n * Nothing to show says only what is true: this reader sees no such workspace. Whether it never existed, is in\n * a private conversation or sits behind a door is not said - saying which would itself tell.\n */\n if (!shown) return html`<div class=\"empty\">${t('not-found', 'there is no workspace here that you can see.')}</div>`\n\n const latest = this.versions[this.versions.length - 1].version\n return html`<div class=\"page\">\n ${this.newer && this.newer !== shown.version\n ? html`<div class=\"notice\" role=\"status\">\n <md-icon>update</md-icon>\n <span>${t('newer', 'a newer version ({version}) is ready.', { version: this.newer })}</span>\n <button @click=${() => this.go(this.newer)}>${t('show-newer', 'show it')}</button>\n </div>`\n : nothing}\n <header>\n <div class=\"what\">\n <h1>${shown.workspace.title}</h1>\n ${shown.workspace.summary ? html`<div class=\"summary\">${shown.workspace.summary}</div>` : nothing}\n </div>\n ${this.versions.length > 1\n ? html`<select aria-label=${t('versions', 'versions')} @change=${(e: Event) => this.go(Number((e.target as HTMLSelectElement).value))}>\n ${this.versions\n .slice()\n .reverse()\n .map(\n one => html`<option value=${one.version} ?selected=${one.version === shown.version}>\n ${t('version', 'version {version} of {of}', { version: one.version, of: latest })}${one.createdAt ? ` · ${new Date(one.createdAt).toLocaleString(i18next.language || undefined)}` : ''}\n </option>`\n )}\n </select>`\n : nothing}\n </header>\n <ox-assistant-workspace-view .workspace=${shown.workspace}></ox-assistant-workspace-view>\n </div>`\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  /* The pages ai-assistant brings to every application that installs it. */
2
2
  export default function route(page) {
3
3
  switch (page) {
4
- /* The AI 작업판 - results too large for the dock (design/ai/workspace.md). */
4
+ /* The AI 작업 패널 - results too large for the dock (design/ai/workspace.md). */
5
5
  case 'assistant-workspace':
6
6
  import('./pages/assistant-workspace-page.js');
7
7
  return page;
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../client/route.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,IAAY;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,2EAA2E;QAC3E,KAAK,qBAAqB;YACxB,MAAM,CAAC,qCAAqC,CAAC,CAAA;YAC7C,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["/* The pages ai-assistant brings to every application that installs it. */\nexport default function route(page: string) {\n switch (page) {\n /* The AI 작업판 - results too large for the dock (design/ai/workspace.md). */\n case 'assistant-workspace':\n import('./pages/assistant-workspace-page.js')\n return page\n }\n}\n"]}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../client/route.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,IAAY;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,6EAA6E;QAC7E,KAAK,qBAAqB;YACxB,MAAM,CAAC,qCAAqC,CAAC,CAAA;YAC7C,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["/* The pages ai-assistant brings to every application that installs it. */\nexport default function route(page: string) {\n switch (page) {\n /* The AI 작업 패널 - results too large for the dock (design/ai/workspace.md). */\n case 'assistant-workspace':\n import('./pages/assistant-workspace-page.js')\n return page\n }\n}\n"]}