From 2d7a76f1be8151426938ae9ae3da061ca5480a3a Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 8 Nov 2026 15:28:27 -0600 Subject: [PATCH 01/30] test(navigation) Ignore pending badge images why: External README badges can hold the load event after the Ruby legacy URL has reached its destination article. The shared assertion affects multiple port integrations. what: - Check the destination URL, parsed article heading and title - Hold badge responses in a regression without raising timeouts - Add the focused --guide-redirect browser mode Isolated samples with staged Ruby guides compared main 9a01505fc with the Perl integration ca13fe555: cold GET 7.13s versus 7.34s, final server RSS 2675 versus 2716 MiB, and warm redirects 0.30s versus 0.34s. This sample showed little integration growth; it did not establish the cause of the separate hosted ECONNRESET. On this main-based branch, held badge responses reproduce the old load timeout. Document readiness completes within the existing deadline. Appearance checks retain their image-completion contract. --- site/scripts/check-dev.mjs | 7 ++++++- site/scripts/check-navigation.mjs | 30 ++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/site/scripts/check-dev.mjs b/site/scripts/check-dev.mjs index e07ac0cf3..cd50eca6c 100644 --- a/site/scripts/check-dev.mjs +++ b/site/scripts/check-dev.mjs @@ -24,6 +24,7 @@ import { checkBlockLinksUndecorated, checkKindBadgeLinks, checkKindBadgeLinksFai import { checkTypeParameters } from './check-type-parameters.mjs' import { checkTmuxKeys, TMUX_KEY_PAGES } from './check-tmux-keys.mjs' import { checkSidebarDemo } from './check-sidebar-demo.mjs' +import { checkGuideRedirect } from './check-navigation.mjs' const apiNavigationOnly = process.argv.includes('--api-navigation') const apiAnchorsOnly = process.argv.includes('--api-anchors') @@ -53,6 +54,7 @@ assert(requestedBrowserPort === undefined || /^\d+$/.test(requestedBrowserPort) && Number(requestedBrowserPort) >= 1 && Number(requestedBrowserPort) <= 65535, 'LIBTMUX_DOCS_BROWSER_PORT must be an integer from 1 to 65535') const documentationNavigationOnly = process.argv.includes('--documentation-navigation') +const guideRedirectOnly = process.argv.includes('--guide-redirect') const workspacePortCount = PORTS.filter((port) => productAvailable(port, 'workspace')).length Object.assign(process.env, { @@ -785,6 +787,7 @@ try { // Compile the initial pages during setup; navigation assertions measure // the running app. The outer loop still budgets this initial compilation. const firstPage = homeLauncherOnly || homeControlsOnly ? '/' + : guideRedirectOnly ? '/ruby/latest/guides/overview/' : keywordHelpOnly ? '/kotlin/latest/reference/io-github-libtmux-kotlin-withserver/' : apiStickyOnly || permalinkRevealOnly ? '/swift/latest/reference/server/' : badgeCentringOnly ? '/py/v0.46.2/guides/attaching-to-tmux/' @@ -793,7 +796,7 @@ try { : apiNavigationOnly ? '/lua/latest/reference/libtmux-server/' : typeParametersOnly ? '/ts/latest/reference/selection-selection-where/' : '/tmux/concepts/server-session-window-pane/' const fullRun = ![homeLauncherOnly, homeControlsOnly, keywordHelpOnly, apiSignaturesOnly, referenceLayoutOnly, globalHeaderOnly, headerMenuSectionsOnly, statusBadgesOnly, badgeCentringOnly, referencePreviewsOnly, - referencePreferencesOnly, documentationNavigationOnly, apiNavigationOnly, apiAnchorsOnly, typeParametersOnly, permalinkRevealOnly, requiredAppearanceOnly].some(Boolean) + referencePreferencesOnly, documentationNavigationOnly, guideRedirectOnly, apiNavigationOnly, apiAnchorsOnly, typeParametersOnly, permalinkRevealOnly, requiredAppearanceOnly].some(Boolean) const setupPages = sampleOnly ? [firstPage, '/demo/widgets/pickers/', ...TMUX_KEY_PAGES] : [firstPage, ...(fullRun ? TMUX_KEY_PAGES : [])] const ready = Promise.all(setupPages.map(async (path) => { @@ -863,6 +866,8 @@ try { } else if (referencePreferencesOnly) { await retryReload(() => checkReferencePreferences(browser, base)) await retryReload(() => checkGlobalHeader(browser, base)) + } else if (guideRedirectOnly) { + await checkGuideRedirect(browser, base) } else if (documentationNavigationOnly) { await retryReload(() => checkDocumentationNavigation(browser, base, true)) } else if (apiNavigationOnly) { diff --git a/site/scripts/check-navigation.mjs b/site/scripts/check-navigation.mjs index be7df6b38..caccb9b52 100644 --- a/site/scripts/check-navigation.mjs +++ b/site/scripts/check-navigation.mjs @@ -7,6 +7,33 @@ import { checkPickerFilters } from './check-picker-filters.mjs' /** The version the dev build mounts a port's prose pages at: its default, as check-dev sets it. */ const defaultVersion = (port) => JSON.parse(process.env.LIBTMUX_DOCS_PORT_DEFAULTS || '{}')[port] ?? 'latest' +/** A legacy guide reaches its article while external README badges remain pending. */ +export async function checkGuideRedirect(browser, base) { + const page = await browser.newPage({ reducedMotion: 'reduce' }) + page.setDefaultTimeout(process.env.CI ? 20000 : 10000) + let release + let requested = 0 + const pending = new Promise((resolve) => { release = resolve }) + await page.route('https://img.shields.io/**', async (route) => { + requested += 1 + await pending + await route.fulfill({ contentType: 'image/svg+xml', body: '' }) + }) + try { + await page.goto(`${base}/ruby/latest/guides/overview/`, { waitUntil: 'domcontentloaded' }) + await page.waitForURL(`${base}/ruby/latest/guides/getting-started/`, { waitUntil: 'domcontentloaded' }) + assert.equal((await page.locator('main h1').textContent()).trim(), 'Getting started') + assert.equal(await page.title(), 'Getting started | libtmux-ruby') + assert(requested > 0, 'The real guide requested external badges') + assert.equal(await page.evaluate(() => document.readyState), 'interactive', 'The destination document is parsed before external badges complete') + console.log('Guide redirect: the legacy Ruby URL reaches its article with external badges still pending') + } finally { + release() + await page.unrouteAll({ behavior: 'wait' }) + await page.close() + } +} + /** Optional scripts injected at the end of the body cannot gate navigation. */ export async function checkNavigationBeforeAnalytics(browser, base) { const page = await browser.newPage({ viewport: { width: 390, height: 900 }, reducedMotion: 'reduce' }) @@ -297,8 +324,7 @@ export async function checkDocumentationNavigation(browser, base, complete = fal await page.waitForURL(`${base}/fsharp/latest/reference/?from=bookmark`) assert.equal((await page.locator('main h1').textContent()).trim(), 'API reference') assert.equal(await page.title(), 'F# API reference | libtmux-fsharp') - await page.goto(`${base}/ruby/latest/guides/overview/`, { waitUntil: 'load' }) - await page.waitForURL(`${base}/ruby/latest/guides/getting-started/`) + await checkGuideRedirect(browser, base) console.log(`Documentation surfaces: ${ports.length} ports retain real section links; Ruby/F# setup, cards and legacy links pass`) } finally { await page.close() From 547ee120c281f53364da63012f9f89f91a1d0286 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 8 Nov 2026 16:43:36 -0600 Subject: [PATCH 02/30] test(browser) Isolate checks from external requests why: Remote README badges can keep document load pending across browser checks. Context routing alone misses redirects and can be bypassed by later request decorators. what: - Create shared check contexts with an owned origin-restricted proxy - Fulfil foreign images locally and constrain existing decorators - Preserve load and visible-readiness assertions for legacy guides - Exercise redirects, popups, WebSockets and failed stream cleanup - Close owned contexts when policy registration fails --- site/scripts/.probe-core-tabs.mjs | 3 +- site/scripts/browser-context.mjs | 113 +++++++++++ site/scripts/check-badge-centring.mjs | 9 +- site/scripts/check-browser-network.mjs | 193 +++++++++++++++++++ site/scripts/check-clipboard.mjs | 5 +- site/scripts/check-color-scheme.mjs | 9 +- site/scripts/check-dev-sample.mjs | 5 +- site/scripts/check-dev.mjs | 19 +- site/scripts/check-fonts.mjs | 3 +- site/scripts/check-header-menu-sections.mjs | 3 +- site/scripts/check-home-example-options.mjs | 5 +- site/scripts/check-home-hover.mjs | 3 +- site/scripts/check-home-launcher.mjs | 9 +- site/scripts/check-home-task-reset.mjs | 17 +- site/scripts/check-language-icon-scheme.mjs | 5 +- site/scripts/check-mobile-nav.mjs | 3 +- site/scripts/check-native-layout.mjs | 8 +- site/scripts/check-native-navigation.mjs | 7 +- site/scripts/check-native-shell.mjs | 5 +- site/scripts/check-navigation.mjs | 54 +++--- site/scripts/check-page-readiness.mjs | 26 +-- site/scripts/check-picker-filters.mjs | 8 +- site/scripts/check-reference-preferences.mjs | 13 +- site/scripts/check-ruby-lua.mjs | 3 +- site/scripts/check-sidebar-demo.mjs | 3 +- site/scripts/check-status-badges.mjs | 5 +- site/scripts/check-style-parity.mjs | 3 +- site/scripts/check-tables.mjs | 3 +- site/scripts/check-tmux-keys.mjs | 3 +- site/scripts/check-type-parameters.mjs | 3 +- site/scripts/check-visual.mjs | 3 +- site/scripts/check-workspace-hover.mjs | 3 +- site/scripts/check-workspace-shift.mjs | 3 +- 33 files changed, 448 insertions(+), 109 deletions(-) create mode 100644 site/scripts/browser-context.mjs create mode 100644 site/scripts/check-browser-network.mjs diff --git a/site/scripts/.probe-core-tabs.mjs b/site/scripts/.probe-core-tabs.mjs index 2b2757999..f90783402 100644 --- a/site/scripts/.probe-core-tabs.mjs +++ b/site/scripts/.probe-core-tabs.mjs @@ -1,8 +1,9 @@ +import { newCheckPage } from './browser-context.mjs' import { chromium } from 'playwright' const url = process.argv[2] ?? 'http://127.0.0.1:53972/' const browser = await chromium.launch() -const page = await browser.newPage({ viewport: { width: 1280, height: 900 }, colorScheme: 'dark' }) +const page = await newCheckPage(browser, url, { viewport: { width: 1280, height: 900 }, colorScheme: 'dark' }) await page.addInitScript(() => { window.__shifts = [] window.__phase = 'load' diff --git a/site/scripts/browser-context.mjs b/site/scripts/browser-context.mjs new file mode 100644 index 000000000..bf555a8a8 --- /dev/null +++ b/site/scripts/browser-context.mjs @@ -0,0 +1,113 @@ +/** Own a forwarding proxy per check context; redirects and route.fetch share its origin boundary. */ +import { once } from 'node:events' +import { Agent, createServer, request as httpRequest } from 'node:http' +import { connect } from 'node:net' +import { pipeline } from 'node:stream' + +async function proxyFor(base) { + const own = new URL(base) + const allowed = own.origin + const agent = new Agent({ keepAlive: true, maxSockets: 32 }) + const sockets = new Set() + const track = (socket) => { + if (sockets.has(socket)) return socket + sockets.add(socket) + socket.once('close', () => sockets.delete(socket)) + return socket + } + const targetFor = (raw, tunnel = false) => { + const target = new URL(tunnel ? `${own.protocol}//${raw}` : raw) + const origin = target.origin.replace(/^ws:/, 'http:').replace(/^wss:/, 'https:') + return origin === allowed ? target : undefined + } + const server = createServer((incoming, outgoing) => { + let target + try { target = targetFor(incoming.url) } catch {} + if (!target || target.protocol !== 'http:') { incoming.socket.destroy(); return } + const headers = { ...incoming.headers, host: target.host } + delete headers['proxy-connection'] + delete headers['proxy-authorization'] + const upstream = httpRequest(target, { method: incoming.method, headers, agent }, (response) => { + outgoing.writeHead(response.statusCode, response.headers) + pipeline(response, outgoing, (error) => { if (error) upstream.destroy() }) + }) + upstream.on('socket', track) + upstream.on('error', () => outgoing.destroy()) + incoming.on('error', () => upstream.destroy()) + incoming.on('aborted', () => upstream.destroy()) + outgoing.on('close', () => { if (!outgoing.writableFinished) upstream.destroy() }) + incoming.pipe(upstream) + }) + server.on('connection', track) + server.on('connect', (request, client, head) => { + let target + try { target = targetFor(request.url, true) } catch {} + if (!target) { client.destroy(); return } + const upstream = track(connect(Number(target.port || (own.protocol === 'https:' ? 443 : 80)), target.hostname)) + upstream.once('connect', () => { + client.write('HTTP/1.1 200 Connection Established\r\n\r\n') + if (head.length) upstream.write(head) + client.pipe(upstream).pipe(client) + }) + client.on('error', () => upstream.destroy()) + upstream.on('error', () => client.destroy()) + client.on('close', () => upstream.destroy()) + upstream.on('close', () => client.destroy()) + }) + server.on('upgrade', (request, client, head) => { + let target + try { target = targetFor(request.url) } catch {} + if (!target || !['http:', 'ws:'].includes(target.protocol)) { client.destroy(); return } + const upstream = track(connect(Number(target.port || 80), target.hostname)) + upstream.once('connect', () => { + const headers = Object.entries(request.headers).filter(([key]) => key !== 'proxy-connection') + .map(([key, value]) => `${key}: ${value}`).join('\r\n') + upstream.write(`${request.method} ${target.pathname}${target.search} HTTP/${request.httpVersion}\r\n${headers}\r\n\r\n`) + if (head.length) upstream.write(head) + client.pipe(upstream).pipe(client) + }) + client.on('error', () => upstream.destroy()) + upstream.on('error', () => client.destroy()) + client.on('close', () => upstream.destroy()) + upstream.on('close', () => client.destroy()) + }) + server.listen(0, '127.0.0.1') + await once(server, 'listening') + return { + server: `http://127.0.0.1:${server.address().port}`, + close() { + server.close() + agent.destroy() + for (const socket of sockets) socket.destroy() + }, + } +} + +async function mockForeignImages(context, base) { + const origin = new URL(base).origin + await context.route((url) => url.origin !== origin, (route) => route.request().resourceType() === 'image' + ? route.fulfill({ contentType: 'image/svg+xml', body: '' }) + : route.abort()) +} + +export async function newCheckContext(browser, base, options = {}) { + const proxy = await proxyFor(base) + let context + try { + context = await browser.newContext({ ...options, serviceWorkers: 'block', proxy: { server: proxy.server, bypass: '<-loopback>' } }) + context.once('close', () => proxy.close()) + await mockForeignImages(context, base) + return context + } catch (error) { proxy.close(); await context?.close().catch(() => {}); throw error } +} + +export async function newCheckPage(browser, base, options = {}) { + const proxy = await proxyFor(base) + let page + try { + page = await browser.newPage({ ...options, serviceWorkers: 'block', proxy: { server: proxy.server, bypass: '<-loopback>' } }) + page.context().once('close', () => proxy.close()) + await mockForeignImages(page.context(), base) + return page + } catch (error) { proxy.close(); await page?.close().catch(() => {}); throw error } +} diff --git a/site/scripts/check-badge-centring.mjs b/site/scripts/check-badge-centring.mjs index c566cf8ec..f7b52191f 100644 --- a/site/scripts/check-badge-centring.mjs +++ b/site/scripts/check-badge-centring.mjs @@ -1,4 +1,5 @@ #!/usr/bin/env node +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' import { PNG } from 'pngjs' import { chromium } from 'playwright' @@ -590,7 +591,7 @@ export async function checkBadgeCentring(browser, base, { sample: bounded = fals const hi = await chromium.launch({ args: ['--force-device-scale-factor=2', '--window-size=1440,1000'] }) try { for (const [engine, factor] of [[browser, 1], [hi, 2]]) { - const context = await engine.newContext(factor === 1 ? { viewport: { width: 1440, height: 1000 }, reducedMotion: 'reduce' } : { viewport: null, reducedMotion: 'reduce' }) + const context = await newCheckContext(engine, base, factor === 1 ? { viewport: { width: 1440, height: 1000 }, reducedMotion: 'reduce' } : { viewport: null, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) // The first request for a reference page compiles it in the dev server, and the index and tool pages are large. @@ -616,7 +617,7 @@ export async function checkBadgeCentring(browser, base, { sample: bounded = fals * carries the mark and a later one is a plain link that keeps its kind. */ export async function checkMentionDensity(browser, base) { - const context = await browser.newContext({ viewport: { width: 1440, height: 1000 } }) + const context = await newCheckContext(browser, base, { viewport: { width: 1440, height: 1000 } }) const page = await context.newPage() page.setDefaultNavigationTimeout(60000) try { @@ -666,7 +667,7 @@ const CHIP_PAGES = ['server', 'session', 'window', 'pane', 'client'].map((name) */ export async function checkChipGrowth(browser, base) { // The contents column, and the Related APIs in it, show from 85rem. - const context = await browser.newContext({ viewport: { width: 1440, height: 900 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width: 1440, height: 900 }, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultNavigationTimeout(60000) const open = async (path) => { @@ -712,7 +713,7 @@ const USAGE = { list: '.tmux-usage', where: 'usage table', ink: true } * a chip squeezed by its qualifier and one chip moved onto another. */ export async function checkUsageChips(browser, base) { - const context = await browser.newContext({ viewport: { width: 1134, height: 900 } }) + const context = await newCheckContext(browser, base, { viewport: { width: 1134, height: 900 } }) const page = await context.newPage() page.setDefaultNavigationTimeout(60000) const ready = () => page.waitForFunction(() => document.documentElement.dataset.pageReadiness === 'ready', null, { timeout: 30000 }).catch(() => {}) diff --git a/site/scripts/check-browser-network.mjs b/site/scripts/check-browser-network.mjs new file mode 100644 index 000000000..f89b4d85c --- /dev/null +++ b/site/scripts/check-browser-network.mjs @@ -0,0 +1,193 @@ +import assert from 'node:assert/strict' +import { createHash } from 'node:crypto' +import { once } from 'node:events' +import { createServer } from 'node:http' +import { pathToFileURL } from 'node:url' +import { chromium } from 'playwright' +import { newCheckContext, newCheckPage } from './browser-context.mjs' + +/** A held image on another origin must never reach its server or delay load. */ +export async function checkBrowserNetwork(browser) { + let result = Promise.withResolvers() + let escaped = 0 + const foreign = createServer(() => { + // Deliberately leave this image response pending until fixture teardown. + }) + foreign.on('connection', () => { + escaped += 1 + result.resolve('escaped') + }) + foreign.listen(0, '127.0.0.1') + await once(foreign, 'listening') + const remote = `http://127.0.0.1:${foreign.address().port}` + let truncated + let pendingClosed = Promise.withResolvers() + const local = createServer((request, response) => { + if (['/truncated', '/pending'].includes(request.url)) { + response.writeHead(200, { 'Content-Type': 'application/octet-stream', 'Content-Length': '65536', 'X-Content-Type-Options': 'nosniff' }) + response.write('x'.repeat(16384)) + if (request.url === '/truncated') truncated = response + else response.once('close', () => { pendingClosed.resolve(); local.emit('pending-closed') }) + } else if (request.url === '/release-truncated') { + response.end('released') + truncated.destroy() + } else if (request.url === '/pending-state') { + void pendingClosed.promise.then(() => { if (!response.destroyed) response.end('closed') }) + } else if (request.url === '/local.js') { + response.writeHead(200, { 'Content-Type': 'application/javascript' }) + response.end('window.localScript = true') + } else if (request.url === '/local.css') { + response.writeHead(200, { 'Content-Type': 'text/css' }) + response.end('h1 { color: rgb(1, 2, 3) }') + } else if (request.url === '/redirected.svg') { + response.writeHead(302, { Location: `${remote}/held.svg` }) + response.end() + } else { + response.writeHead(200, { 'Content-Type': 'text/html' }) + const image = request.url === '/redirect-case' ? '/redirected.svg' : `${remote}/held.svg` + response.end(`Local fixture

Local fixture

`) + } + }) + const localSockets = new Set() + local.on('connection', (socket) => { + localSockets.add(socket) + socket.once('close', () => localSockets.delete(socket)) + socket.on('error', () => socket.destroy()) + }) + local.on('upgrade', (request, socket) => { + const accept = createHash('sha1').update(request.headers['sec-websocket-key'] + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest('base64') + socket.write(`HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ${accept}\r\n\r\n`) + socket.once('data', () => socket.end()) + }) + try { + local.listen(0, '127.0.0.1') + await once(local, 'listening') + const base = `http://127.0.0.1:${local.address().port}` + for (const factory of ['page', 'context', 'redirect', 'continued']) { + const page = factory === 'page' + ? await newCheckPage(browser, base, { viewport: { width: 640, height: 480 } }) + : await (await newCheckContext(browser, base, { viewport: { width: 640, height: 480 } })).newPage() + const context = page.context() + context.setDefaultNavigationTimeout(5000) + context.on('requestfailed', (request) => { + if (new URL(request.url()).origin === remote) result.resolve('blocked') + }) + context.on('response', (response) => { + if (new URL(response.url()).origin === remote) result.resolve('blocked') + }) + try { + if (factory === 'continued') await page.route('**/*', (route) => route.continue()) + result = Promise.withResolvers() + let loaded = false + const navigation = page.goto(base + (factory === 'redirect' ? '/redirect-case' : '/'), { waitUntil: 'load' }).then(() => { loaded = true }, (error) => { result.reject(error) }) + const outcome = await result.promise + if (outcome === 'escaped') assert.equal(loaded, false, 'The held image delays document load') + assert.equal(outcome, 'blocked', `${factory}: held image reached the foreign server`) + await navigation + assert.equal(await page.title(), 'Local fixture') + assert.deepEqual(await page.evaluate(() => [window.localScript, getComputedStyle(document.querySelector('h1')).color]), [true, 'rgb(1, 2, 3)']) + assert.equal(page.viewportSize().width, 640, 'Browser options survive the request policy') + if (['page', 'context'].includes(factory)) { + assert.equal(await page.evaluate(async () => { + await Promise.all(Array.from(document.images, (image) => image.decode())) + return document.images[0].naturalWidth + }), 1, 'Off-origin image fixtures decode without contacting their server') + } + if (factory === 'context') { + assert.equal(await page.evaluate((url) => new Promise((resolve, reject) => { + const socket = new WebSocket(url) + socket.onopen = () => { socket.close(); resolve('open') } + socket.onerror = () => reject(new Error('The owned server WebSocket did not open')) + }), base.replace('http:', 'ws:') + '/socket'), 'open') + result = Promise.withResolvers() + const incoming = page.waitForEvent('popup') + await page.evaluate(() => window.open('/popup')) + const popup = await incoming + assert.equal(await result.promise, 'blocked', 'Popup requests inherit the context policy') + await popup.waitForLoadState('load') + assert.equal(await popup.title(), 'Local fixture') + assert.equal(await popup.evaluate(async () => { await document.images[0].decode(); return document.images[0].naturalWidth }), 1) + await popup.close() + result = Promise.withResolvers() + const fetched = context.request.get(`${remote}/api`, { timeout: 1000 }) + .then(() => 'responded', () => 'blocked') + assert.equal(await Promise.race([result.promise, fetched]), 'blocked', 'Context request/fetch cannot escape through a decorator') + } + assert.equal(escaped, 0, 'No off-origin request reached the held-image server') + } finally { + if (factory === 'page') await page.close() + else await context.close() + } + } + const page = await newCheckPage(browser, base) + try { + await page.goto(base) + const truncation = await page.evaluate(async () => { + const controller = new AbortController() + const limit = setTimeout(() => controller.abort(), 1000) + try { + const response = await fetch('/truncated', { signal: controller.signal }) + const reader = response.body.getReader() + await reader.read() + await fetch('/release-truncated') + try { + let chunk = await reader.read() + while (!chunk.done) chunk = await reader.read() + return { failed: false } + } + catch { return { failed: true, deadline: controller.signal.aborted } } + } finally { clearTimeout(limit) } + }) + assert.deepEqual(truncation, { failed: true, deadline: false }, 'Truncated upstream fails before the fixture deadline') + pendingClosed = Promise.withResolvers() + assert.equal(await page.evaluate(async () => { + const controller = new AbortController() + const response = await fetch('/pending', { signal: controller.signal }) + await response.body.getReader().read() + controller.abort() + return (await fetch('/pending-state', { signal: AbortSignal.timeout(1000) })).text() + }), 'closed', 'Cancelling a client closes its owned upstream request') + } finally { await page.close() } + const context = await newCheckContext(browser, base) + try { + const page = await context.newPage() + await page.goto(base) + await page.evaluate(async () => { await (await fetch('/pending')).body.getReader().read() }) + await Promise.all([once(local, 'pending-closed', { signal: AbortSignal.timeout(1000) }), context.close()]) + } finally { await context.close() } + const before = browser.contexts().length + const failure = new Error('Image policy registration failed') + const broken = { + async newContext(options) { + const context = await browser.newContext(options) + context.route = async () => { throw failure } + return context + }, + async newPage(options) { + const page = await browser.newPage(options) + page.context().route = async () => { throw failure } + return page + }, + } + await assert.rejects(newCheckContext(broken, base), (error) => error === failure) + assert.equal(browser.contexts().length, before, 'Failed context policy registration closes its context') + await assert.rejects(newCheckPage(broken, base), (error) => error === failure) + assert.equal(browser.contexts().length, before, 'Failed page policy registration closes its context') + const driver = browser.browserType() + const closed = await driver.launch(driver.name() === 'chromium' ? { channel: process.env.LIBTMUX_DOCS_BROWSER_CHANNEL } : {}) + await closed.close() + await assert.rejects(newCheckContext(closed, base)) + await assert.rejects(newCheckPage(closed, base)) + console.log('Browser network: local assets load; off-origin images, redirects, decorators and popup requests cannot escape') + } finally { + local.closeAllConnections() + foreign.closeAllConnections() + for (const socket of localSockets) socket.destroy() + await Promise.all([new Promise((resolve) => local.close(resolve)), new Promise((resolve) => foreign.close(resolve))]) + } +} + +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { + const browser = await chromium.launch() + try { await checkBrowserNetwork(browser) } finally { await browser.close() } +} diff --git a/site/scripts/check-clipboard.mjs b/site/scripts/check-clipboard.mjs index caecd5fbf..da8a2cec6 100644 --- a/site/scripts/check-clipboard.mjs +++ b/site/scripts/check-clipboard.mjs @@ -1,4 +1,5 @@ #!/usr/bin/env node +import { newCheckPage } from './browser-context.mjs' import assert from 'node:assert/strict' import { createHash } from 'node:crypto' import { readFileSync } from 'node:fs' @@ -36,7 +37,7 @@ export function assertCompleteApiExample(rendered, example) { /** Inspect rendered API examples against their native execution receipts. */ export async function checkCompleteApiExamples(browser, base) { const examples = JSON.parse(readFileSync(new URL('../test/fixtures/api-examples.json', import.meta.url), 'utf8')).examples - const page = await browser.newPage() + const page = await newCheckPage(browser, base) try { for (const example of examples) { const path = example.page.replace(`ports/${example.port}/`, `${example.port}/latest/`) @@ -217,7 +218,7 @@ export async function checkClipboard(page, base) { if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { const browser = await chromium.launch() try { - const page = await browser.newPage() + const page = await newCheckPage(browser, base) page.setDefaultTimeout(1000) await checkClipboard(page, (process.argv[2] ?? 'http://localhost:8080/en').replace(/\/$/, '')) } finally { diff --git a/site/scripts/check-color-scheme.mjs b/site/scripts/check-color-scheme.mjs index 78288b657..9a700fa22 100644 --- a/site/scripts/check-color-scheme.mjs +++ b/site/scripts/check-color-scheme.mjs @@ -1,12 +1,13 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' /** Compact cycling and wide radios share the same saved preference. */ export async function checkColorScheme(browser, base) { for (const blocked of [false, true]) { - const context = await browser.newContext({ viewport: { width: 596, height: 777 }, colorScheme: 'light', reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width: 596, height: 777 }, colorScheme: 'light', reducedMotion: 'reduce' }) try { if (blocked) { - await context.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => route.fulfill({ contentType: 'application/javascript', body: 'export {}' })) + await context.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => new URL(route.request().url()).origin !== new URL(base).origin ? route.fallback() : route.fulfill({ contentType: 'application/javascript', body: 'export {}' })) await context.addInitScript(() => Object.defineProperty(window, 'localStorage', { get() { throw new DOMException('Storage blocked', 'SecurityError') }, })) @@ -58,7 +59,7 @@ export async function checkColorScheme(browser, base) { await context.close() } } - const reader = await browser.newContext({ viewport: { width: 1062, height: 789 }, colorScheme: 'light', reducedMotion: 'reduce' }) + const reader = await newCheckContext(browser, base, { viewport: { width: 1062, height: 789 }, colorScheme: 'light', reducedMotion: 'reduce' }) try { const page = await reader.newPage() await page.goto(`${base}/code-tabs-probe/`) @@ -99,7 +100,7 @@ export async function checkColorScheme(browser, base) { } finally { await reader.close() } - const context = await browser.newContext({ javaScriptEnabled: false, viewport: { width: 596, height: 777 } }) + const context = await newCheckContext(browser, base, { javaScriptEnabled: false, viewport: { width: 596, height: 777 } }) try { const page = await context.newPage() await page.goto(`${base}/`) diff --git a/site/scripts/check-dev-sample.mjs b/site/scripts/check-dev-sample.mjs index f46b57c78..561c2733e 100644 --- a/site/scripts/check-dev-sample.mjs +++ b/site/scripts/check-dev-sample.mjs @@ -1,3 +1,4 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' import { checkHomeResponsiveLayout } from './check-home-launcher.mjs' import { checkPickerFilters } from './check-picker-filters.mjs' @@ -96,7 +97,7 @@ function revealedContrast(id) { export async function checkRowPermalinks(browser, base, pages = ROW_PERMALINK_PAGES) { let rows = 0 for (const colorScheme of ['light', 'dark']) { - const context = await browser.newContext({ colorScheme, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { colorScheme, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) try { @@ -174,7 +175,7 @@ export async function checkDevSample(browser, base) { await checkKindBadgeLinks(browser, base, { sample: true }) await checkBlockLinksUndecorated(browser, base, { sample: true }) await checkTmuxKeys(browser, base) - const context = await browser.newContext({ reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce' }) const page = await context.newPage() const errors = [] page.on('pageerror', (error) => errors.push(error.message)) diff --git a/site/scripts/check-dev.mjs b/site/scripts/check-dev.mjs index cd50eca6c..4b5dbea2d 100644 --- a/site/scripts/check-dev.mjs +++ b/site/scripts/check-dev.mjs @@ -1,4 +1,5 @@ #!/usr/bin/env node +import { newCheckContext, newCheckPage } from './browser-context.mjs' import assert from 'node:assert/strict' import { cpSync, mkdirSync, mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs' import { join } from 'node:path' @@ -309,7 +310,7 @@ async function retryReload(check, page) { } async function checkSignatureLayouts(browser, base) { - const page = await browser.newPage({ javaScriptEnabled: false }) + const page = await newCheckPage(browser, base, { javaScriptEnabled: false }) try { await page.goto(`${base}/api-signature-probe/`, { waitUntil: 'load' }) const entries = page.locator('[data-signature-port]') @@ -450,7 +451,7 @@ async function checkSignatureLayouts(browser, base) { async function checkKeywordHelp(browser, base) { const fullMatrix = apiSignaturesOnly || keywordHelpOnly for (const javaScriptEnabled of [false, true]) { - const page = await browser.newPage({ javaScriptEnabled }) + const page = await newCheckPage(browser, base, { javaScriptEnabled }) const errors = [] page.on('pageerror', (error) => errors.push(error.message)) page.setDefaultTimeout(5000) @@ -542,7 +543,7 @@ async function checkMemberBodies(browser, base) { } async function checkReferenceAndHeroes(browser, base) { - const page = await browser.newPage({ reducedMotion: 'reduce' }) + const page = await newCheckPage(browser, base, { reducedMotion: 'reduce' }) page.setDefaultTimeout(process.env.CI ? 20000 : 10000) try { await page.goto(`${base}/api-body-probe/`) @@ -871,7 +872,7 @@ try { } else if (documentationNavigationOnly) { await retryReload(() => checkDocumentationNavigation(browser, base, true)) } else if (apiNavigationOnly) { - const page = await browser.newPage({ reducedMotion: 'reduce' }) + const page = await newCheckPage(browser, base, { reducedMotion: 'reduce' }) page.setDefaultTimeout(process.env.CI ? 20000 : 10000) await retryReload(() => checkApiNavigation(page, base)) await checkApiNavigationFail(browser, base) @@ -917,15 +918,15 @@ try { // Cold API indexes occupy the same development server as the page walk. // Finish that initial compilation before starting timed browser navigation. await apiExamples - const page = await browser.newPage({ reducedMotion: 'reduce' }) + const page = await newCheckPage(browser, base, { reducedMotion: 'reduce' }) page.setDefaultTimeout(process.env.CI ? 20000 : 10000) const manifest = await page.request.get(`${base}/page-links.json`) assert(manifest.ok(), `Native navigation manifest: HTTP ${manifest.status()}`) assert.equal((await manifest.json()).schema, 1) - const clipboardPage = await browser.newPage() + const clipboardPage = await newCheckPage(browser, base) clipboardPage.setDefaultTimeout(process.env.CI ? 20000 : 10000) const clipboard = schedule(() => checkClipboard(clipboardPage, base).finally(() => clipboardPage.close())) - const navigationPage = await browser.newPage({ reducedMotion: 'reduce' }) + const navigationPage = await newCheckPage(browser, base, { reducedMotion: 'reduce' }) navigationPage.setDefaultTimeout(process.env.CI ? 20000 : 10000) const navigation = schedule(() => retryReload(() => checkNavigation(navigationPage, base)).finally(() => navigationPage.close()) .then(() => retryReload(() => checkMcpInstallRevisit(browser, base)))) @@ -943,7 +944,7 @@ try { .then(() => checkStatusBadgesFail(browser, base))) const homeLauncher = schedule(() => checkHomeLauncher(browser, base)) const documentationNavigation = schedule(() => retryReload(() => checkDocumentationNavigation(browser, base))) - const apiNavigationPage = await browser.newPage({ reducedMotion: 'reduce' }) + const apiNavigationPage = await newCheckPage(browser, base, { reducedMotion: 'reduce' }) apiNavigationPage.setDefaultTimeout(process.env.CI ? 20000 : 10000) const apiNavigation = schedule(() => retryReload(() => checkApiNavigation(apiNavigationPage, base)).then(() => checkApiNavigationFail(browser, base)).finally(() => apiNavigationPage.close())) const apiAnchors = schedule(() => retryReload(() => checkApiAnchorArrival(browser, base))) @@ -1201,7 +1202,7 @@ try { }) assert.equal(toolbar.background, toolbar.page, `${colorScheme}: toolbar uses the page surface before theme initialization`) assert.equal(toolbar.icon, toolbar.text, `${colorScheme}: toolbar icons use the page text color`) - const context = await browser.newContext({ javaScriptEnabled: false, colorScheme, viewport: { width: 390, height: 844 } }) + const context = await newCheckContext(browser, base, { javaScriptEnabled: false, colorScheme, viewport: { width: 390, height: 844 } }) const noScript = await context.newPage() await noScript.goto(`${base}/tmux/concepts/server-session-window-pane/`, { waitUntil: 'load' }) const checkContrast = async (scheme, selectors = ['h1', '.prose h2', '.prose p']) => { diff --git a/site/scripts/check-fonts.mjs b/site/scripts/check-fonts.mjs index da8033c40..770b3351b 100755 --- a/site/scripts/check-fonts.mjs +++ b/site/scripts/check-fonts.mjs @@ -22,6 +22,7 @@ * * Usage: node scripts/check-fonts.mjs [--site DIR] [--url BASE] [--json] */ +import { newCheckPage } from './browser-context.mjs' import { existsSync, readFileSync } from 'node:fs' import { globSync } from 'node:fs' import { dirname, join, resolve } from 'node:path' @@ -169,7 +170,7 @@ try { const browser = await chromium.launch() usage = [] for (const [name, path, ours] of ARCHETYPES) { - const page = await browser.newPage({ viewport: { width: 1440, height: 900 } }) + const page = await newCheckPage(browser, BASE, { viewport: { width: 1440, height: 900 } }) const response = await page.goto(BASE + path, { waitUntil: 'networkidle' }).catch(() => null) if (!response?.ok()) { failures.push(`${name}: ${path} returned ${response?.status() ?? 'no response'}`) diff --git a/site/scripts/check-header-menu-sections.mjs b/site/scripts/check-header-menu-sections.mjs index 2a384e772..dbbb6d2a6 100644 --- a/site/scripts/check-header-menu-sections.mjs +++ b/site/scripts/check-header-menu-sections.mjs @@ -1,3 +1,4 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' /** @@ -252,7 +253,7 @@ export async function checkHeaderMenuSections(browser, base, options = {}) { kinds = KINDS, behavior = true, sabotage } = options let menus = 0 for (const scheme of schemes) { - const context = await browser.newContext({ colorScheme: scheme, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { colorScheme: scheme, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) // The first load of each port compiles its page in the development server. diff --git a/site/scripts/check-home-example-options.mjs b/site/scripts/check-home-example-options.mjs index 7622c8e2e..e83bef817 100644 --- a/site/scripts/check-home-example-options.mjs +++ b/site/scripts/check-home-example-options.mjs @@ -1,13 +1,14 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' import { PORTS } from '../src/lib/ports.ts' import { chooseHomeTask } from './check-home-task-reset.mjs' export async function checkHomeExampleOptions(browser, base) { for (const blocked of [false, true]) { - const context = await browser.newContext({ viewport: { width: 944, height: 777 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width: 944, height: 777 }, reducedMotion: 'reduce' }) try { if (blocked) { - await context.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => route.fulfill({ contentType: 'application/javascript', body: 'export {}' })) + await context.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => new URL(route.request().url()).origin !== new URL(base).origin ? route.fallback() : route.fulfill({ contentType: 'application/javascript', body: 'export {}' })) await context.addInitScript(() => Object.defineProperty(window, 'localStorage', { get() { throw new DOMException('Storage blocked', 'SecurityError') }, })) diff --git a/site/scripts/check-home-hover.mjs b/site/scripts/check-home-hover.mjs index c89b4b734..3b42e7e47 100644 --- a/site/scripts/check-home-hover.mjs +++ b/site/scripts/check-home-hover.mjs @@ -1,9 +1,10 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' import { PORTS } from '../src/lib/ports.ts' /** Real pointer events, with the clock advanced instead of sleeping per option. */ export async function checkHomeHover(browser, base) { - const context = await browser.newContext({ viewport: { width: 914, height: 777 }, colorScheme: 'light', reducedMotion: 'no-preference' }) + const context = await newCheckContext(browser, base, { viewport: { width: 914, height: 777 }, colorScheme: 'light', reducedMotion: 'no-preference' }) const page = await context.newPage() const errors = [] page.on('pageerror', (error) => errors.push(error.message)) diff --git a/site/scripts/check-home-launcher.mjs b/site/scripts/check-home-launcher.mjs index 0f14ca68c..b23844476 100644 --- a/site/scripts/check-home-launcher.mjs +++ b/site/scripts/check-home-launcher.mjs @@ -1,3 +1,4 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' import { PORTS } from '../src/lib/ports.ts' import HOME_PROOF from '../test/fixtures/home-examples.json' with { type: 'json' } @@ -119,7 +120,7 @@ async function checkSolutionHome(page, solution, port) { /** Exercise the real homepage, including the prompt controlled by its picker. */ export async function checkHomeLauncher(browser, base) { - const context = await browser.newContext({ reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) const errors = [] @@ -375,10 +376,10 @@ export async function checkHomeLauncher(browser, base) { } finally { await context.close() } - const blockedStorage = await browser.newContext() + const blockedStorage = await newCheckContext(browser, base) try { // Astro's development toolbar reads storage unguarded; it is absent from published pages. - await blockedStorage.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => route.fulfill({ contentType: 'application/javascript', body: 'export {}' })) + await blockedStorage.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => new URL(route.request().url()).origin !== new URL(base).origin ? route.fallback() : route.fulfill({ contentType: 'application/javascript', body: 'export {}' })) await blockedStorage.addInitScript(() => Object.defineProperty(window, 'localStorage', { get() { throw new DOMException('Storage blocked', 'SecurityError') }, })) @@ -399,7 +400,7 @@ export async function checkHomeLauncher(browser, base) { } finally { await blockedStorage.close() } - const noScript = await browser.newContext({ javaScriptEnabled: false, viewport: { width: 390, height: 777 } }) + const noScript = await newCheckContext(browser, base, { javaScriptEnabled: false, viewport: { width: 390, height: 777 } }) try { const page = await noScript.newPage() await page.goto(`${base}/`) diff --git a/site/scripts/check-home-task-reset.mjs b/site/scripts/check-home-task-reset.mjs index 76cb8ba2a..a946b9374 100644 --- a/site/scripts/check-home-task-reset.mjs +++ b/site/scripts/check-home-task-reset.mjs @@ -1,3 +1,4 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' async function checkTaskFirstPaint(browser, base) { @@ -7,16 +8,19 @@ async function checkTaskFirstPaint(browser, base) { { slug: 'v0.1.0-alpha.12', label: 'v0.1.0-alpha.12', kind: 'prerelease', supported: true }, ] } } for (const width of [853, 390, 280]) { - const context = await browser.newContext({ viewport: { width, height: 789 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width, height: 789 }, reducedMotion: 'reduce' }) let releaseWidget const widgetReady = new Promise((resolve) => { releaseWidget = resolve }) try { - await context.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => route.fulfill({ contentType: 'application/javascript', body: 'export {}' })) + await context.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => new URL(route.request().url()).origin === new URL(base).origin + ? route.fulfill({ contentType: 'application/javascript', body: 'export {}' }) : route.fallback()) await context.route('**/*AgentPrompt*', async (route) => { + if (new URL(route.request().url()).origin !== new URL(base).origin) return route.fallback() if (route.request().resourceType() === 'script') await widgetReady - await route.continue() + await route.fallback() }) - await context.route('**/versions.json', (route) => route.fulfill({ json: versions })) + await context.route('**/versions.json', (route) => new URL(route.request().url()).origin === new URL(base).origin + ? route.fulfill({ json: versions }) : route.fallback()) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) const response = await page.goto(`${base}/?port=ts&errors=1&cleanup=1`, { waitUntil: 'commit' }) @@ -72,10 +76,11 @@ export async function chooseHomeTask(page, topic) { export async function checkHomeTaskReset(browser, base) { await checkTaskFirstPaint(browser, base) for (const blocked of [false, true]) { - const context = await browser.newContext({ viewport: { width: 914, height: 777 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width: 914, height: 777 }, reducedMotion: 'reduce' }) try { if (blocked) { - await context.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => route.fulfill({ contentType: 'application/javascript', body: 'export {}' })) + await context.route('**/astro/runtime/client/dev-toolbar/entrypoint.js', (route) => new URL(route.request().url()).origin === new URL(base).origin + ? route.fulfill({ contentType: 'application/javascript', body: 'export {}' }) : route.fallback()) await context.addInitScript(() => Object.defineProperty(window, 'localStorage', { get() { throw new DOMException('Storage blocked', 'SecurityError') }, })) diff --git a/site/scripts/check-language-icon-scheme.mjs b/site/scripts/check-language-icon-scheme.mjs index afff84c3f..7971c04ad 100644 --- a/site/scripts/check-language-icon-scheme.mjs +++ b/site/scripts/check-language-icon-scheme.mjs @@ -1,3 +1,4 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' import { PNG } from 'pngjs' @@ -56,7 +57,7 @@ export function readPlate(buffer) { async function readIcon(browser, url, icon, { device, site, css, replacement, forced = false, read = readMark }) { // A null site is a visit without JavaScript: no saved choice, so the page follows the device. - const context = await browser.newContext({ colorScheme: device, forcedColors: forced ? 'active' : 'none', reducedMotion: 'reduce', javaScriptEnabled: site !== null, viewport: { width: 1280, height: 777 } }) + const context = await newCheckContext(browser, url, { colorScheme: device, forcedColors: forced ? 'active' : 'none', reducedMotion: 'reduce', javaScriptEnabled: site !== null, viewport: { width: 1280, height: 777 } }) try { if (site !== null) await context.addInitScript((choice) => localStorage.setItem('color-scheme', choice), site) // Added before the page parses, so an image is first drawn with it. @@ -66,7 +67,7 @@ async function readIcon(browser, url, icon, { device, site, css, replacement, fo else new MutationObserver((_, observer) => { if (document.documentElement) { observer.disconnect(); add() } }).observe(document, { childList: true }) }, css) const page = await context.newPage() - if (replacement) await page.route('**/brand/languages/rs/icon.svg', (route) => route.fulfill({ contentType: 'image/svg+xml', body: replacement })) + if (replacement) await page.route('**/brand/languages/rs/icon.svg', (route) => new URL(route.request().url()).origin !== new URL(url).origin ? route.fallback() : route.fulfill({ contentType: 'image/svg+xml', body: replacement })) await page.goto(url) const image = page.locator(icon) await image.waitFor({ state: 'visible' }) diff --git a/site/scripts/check-mobile-nav.mjs b/site/scripts/check-mobile-nav.mjs index 8a1679183..840d45e8a 100755 --- a/site/scripts/check-mobile-nav.mjs +++ b/site/scripts/check-mobile-nav.mjs @@ -21,6 +21,7 @@ * * Usage: node scripts/check-mobile-nav.mjs [base-url] */ +import { newCheckContext } from './browser-context.mjs' import { chromium } from 'playwright' import { checkApiNavigation } from './check-navigation.mjs' const BASE = (process.argv[2] ?? 'http://localhost:8080').replace(/\/$/, '') @@ -28,7 +29,7 @@ const b = await chromium.launch() const fails = [], ok = [] const note = (pass, msg) => (pass ? ok : fails).push(msg) const WITH_TOC = '/tmux/topics/traversal/', NO_TOC = '/tmux/concepts/' -const ctx = await b.newContext() +const ctx = await newCheckContext(b, BASE) const apiPage = await ctx.newPage() try { await checkApiNavigation(apiPage, BASE) diff --git a/site/scripts/check-native-layout.mjs b/site/scripts/check-native-layout.mjs index 76f476f0e..2aeb6f02c 100644 --- a/site/scripts/check-native-layout.mjs +++ b/site/scripts/check-native-layout.mjs @@ -1,3 +1,4 @@ +import { newCheckPage } from './browser-context.mjs' import assert from 'node:assert/strict' /** Controls beside a signature may sit this far from the centre of its first line. */ @@ -198,7 +199,7 @@ const DECLARATION_SAMPLES = [ * names, or the check would pass without measuring anything. */ export async function checkDeclarationControlAlignment(browser, base, widths = [1440, 768, 500, 390]) { - const page = await browser.newPage({ javaScriptEnabled: false }) + const page = await newCheckPage(browser, base, { javaScriptEnabled: false }) const beside = new Map(widths.map((width) => [width, 0])) const measured = [] try { @@ -363,7 +364,8 @@ export async function checkNativeFirstPaint(page, url) { const delayedScript = new Promise((resolve) => { release = resolve }) const pendingRoutes = [] const routeScript = (route) => { - const pending = delayedScript.then(() => route.continue()) + if (new URL(route.request().url()).origin !== new URL(url).origin) return route.fallback() + const pending = delayedScript.then(() => route.fallback()) pendingRoutes.push(pending) return pending } @@ -480,7 +482,7 @@ const MEMBER_BODY_PAGES = [ /** A body's padding alone sets its inset: top and bottom match each other and the padding. */ export async function checkMemberBodyInsets(browser, base) { const tolerance = 1 - const page = await browser.newPage({ reducedMotion: 'reduce' }) + const page = await newCheckPage(browser, base, { reducedMotion: 'reduce' }) page.setDefaultTimeout(process.env.CI ? 20000 : 10000) const failures = [] let measured = 0 diff --git a/site/scripts/check-native-navigation.mjs b/site/scripts/check-native-navigation.mjs index 8d1f2f6ba..937b5cbee 100644 --- a/site/scripts/check-native-navigation.mjs +++ b/site/scripts/check-native-navigation.mjs @@ -1,4 +1,5 @@ #!/usr/bin/env node +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' import { chromium } from 'playwright' @@ -103,7 +104,7 @@ async function checkMetadata(page) { try { for (const [width, colorScheme, reducedMotion] of [[1027, 'light', 'no-preference'], [390, 'dark', 'reduce']]) { - const context = await browser.newContext({ viewport: { width, height: 900 }, colorScheme, reducedMotion, permissions: ['clipboard-read', 'clipboard-write'] }) + const context = await newCheckContext(browser, base, { viewport: { width, height: 900 }, colorScheme, reducedMotion, permissions: ['clipboard-read', 'clipboard-write'] }) try { const page = await context.newPage() const errors = [], documents = [] @@ -159,7 +160,7 @@ try { } finally { await context.close() } } for (const width of [1027, 390]) { - const context = await browser.newContext({ viewport: { width, height: 900 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width, height: 900 }, reducedMotion: 'reduce' }) try { const page = await context.newPage() const current = 'internals/api/libtmux._internal.query_list/' @@ -172,7 +173,7 @@ try { } finally { await context.close() } } for (const javaScriptEnabled of [false, true]) { - const context = await browser.newContext({ javaScriptEnabled, viewport: { width: 1027, height: 1450 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { javaScriptEnabled, viewport: { width: 1027, height: 1450 }, reducedMotion: 'reduce' }) try { const page = await context.newPage() await page.goto(root) diff --git a/site/scripts/check-native-shell.mjs b/site/scripts/check-native-shell.mjs index a961d2f01..c975032cc 100644 --- a/site/scripts/check-native-shell.mjs +++ b/site/scripts/check-native-shell.mjs @@ -1,4 +1,5 @@ #!/usr/bin/env node +import { newCheckContext, newCheckPage } from './browser-context.mjs' import assert from 'node:assert/strict' import { chromium } from 'playwright' import { checkNativeFirstPaint, checkNativeHeader } from './check-native-layout.mjs' @@ -8,7 +9,7 @@ const version = process.argv.find((arg) => arg.startsWith('--version='))?.slice( const browser = await chromium.launch({ channel: process.env.LIBTMUX_DOCS_BROWSER_CHANNEL }) try { for (const javaScriptEnabled of [true, false]) { - const context = await browser.newContext({ javaScriptEnabled, reducedMotion: 'reduce', viewport: { width: 390, height: 900 } }) + const context = await newCheckContext(browser, base, { javaScriptEnabled, reducedMotion: 'reduce', viewport: { width: 390, height: 900 } }) try { const page = await context.newPage() const id = 'libtmux._internal.query_list.QueryList' @@ -24,7 +25,7 @@ try { await context.close() } } - const page = await browser.newPage() + const page = await newCheckPage(browser, base) page.setDefaultTimeout(process.env.CI ? 20000 : 10000) const loaded = new Set() page.on('response', (response) => { diff --git a/site/scripts/check-navigation.mjs b/site/scripts/check-navigation.mjs index caccb9b52..9254c7e59 100644 --- a/site/scripts/check-navigation.mjs +++ b/site/scripts/check-navigation.mjs @@ -1,3 +1,5 @@ +import { newCheckContext, newCheckPage } from './browser-context.mjs' +import { checkBrowserNetwork } from './check-browser-network.mjs' import assert from 'node:assert/strict' import { PORTS, productAvailable, productStatus } from '../src/lib/ports.ts' import registry from '../src/data/registry.json' with { type: 'json' } @@ -7,36 +9,28 @@ import { checkPickerFilters } from './check-picker-filters.mjs' /** The version the dev build mounts a port's prose pages at: its default, as check-dev sets it. */ const defaultVersion = (port) => JSON.parse(process.env.LIBTMUX_DOCS_PORT_DEFAULTS || '{}')[port] ?? 'latest' -/** A legacy guide reaches its article while external README badges remain pending. */ +/** A legacy guide loads with third-party requests blocked by its context. */ export async function checkGuideRedirect(browser, base) { - const page = await browser.newPage({ reducedMotion: 'reduce' }) + await checkBrowserNetwork(browser) + const page = await newCheckPage(browser, base, { reducedMotion: 'reduce' }) page.setDefaultTimeout(process.env.CI ? 20000 : 10000) - let release - let requested = 0 - const pending = new Promise((resolve) => { release = resolve }) - await page.route('https://img.shields.io/**', async (route) => { - requested += 1 - await pending - await route.fulfill({ contentType: 'image/svg+xml', body: '' }) - }) try { - await page.goto(`${base}/ruby/latest/guides/overview/`, { waitUntil: 'domcontentloaded' }) - await page.waitForURL(`${base}/ruby/latest/guides/getting-started/`, { waitUntil: 'domcontentloaded' }) + await page.goto(`${base}/ruby/latest/guides/overview/`, { waitUntil: 'load' }) + await page.waitForURL(`${base}/ruby/latest/guides/getting-started/`, { waitUntil: 'load' }) + await page.locator('html[data-page-readiness="ready"]').waitFor({ state: 'attached' }) assert.equal((await page.locator('main h1').textContent()).trim(), 'Getting started') + assert(await page.locator('main h1').isVisible(), 'The loaded guide is readable') assert.equal(await page.title(), 'Getting started | libtmux-ruby') - assert(requested > 0, 'The real guide requested external badges') - assert.equal(await page.evaluate(() => document.readyState), 'interactive', 'The destination document is parsed before external badges complete') - console.log('Guide redirect: the legacy Ruby URL reaches its article with external badges still pending') + assert.equal(await page.evaluate(() => document.readyState), 'complete') + console.log('Guide redirect: the legacy Ruby URL loads its article without third-party requests') } finally { - release() - await page.unrouteAll({ behavior: 'wait' }) await page.close() } } /** Optional scripts injected at the end of the body cannot gate navigation. */ export async function checkNavigationBeforeAnalytics(browser, base) { - const page = await browser.newPage({ viewport: { width: 390, height: 900 }, reducedMotion: 'reduce' }) + const page = await newCheckPage(browser, base, { viewport: { width: 390, height: 900 }, reducedMotion: 'reduce' }) page.setDefaultTimeout(5000) await page.clock.install({ time: 0 }) await page.clock.pauseAt(1000) @@ -205,7 +199,7 @@ export async function checkDocumentationNavigation(browser, base, complete = fal await checkPickerFilters(browser, base, complete) await checkNavigationBeforeAnalytics(browser, base) const ports = complete ? PORTS : PORTS.filter((port) => ['fsharp', 'ruby'].includes(port.slug)) - const page = await browser.newPage({ viewport: { width: 1440, height: 900 }, reducedMotion: 'reduce' }) + const page = await newCheckPage(browser, base, { viewport: { width: 1440, height: 900 }, reducedMotion: 'reduce' }) page.setDefaultTimeout(process.env.CI ? 20000 : 10000) await observeInitialPageLoad(page) const desktopPicker = (reader) => reader.locator('[data-documentation-context] [data-surface-picker]') @@ -333,7 +327,7 @@ export async function checkDocumentationNavigation(browser, base, complete = fal if (!complete) return for (const javaScriptEnabled of [true, false]) { for (const colorScheme of ['light', 'dark']) { - const context = await browser.newContext({ javaScriptEnabled, colorScheme, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { javaScriptEnabled, colorScheme, reducedMotion: 'reduce' }) const reader = await context.newPage() reader.setDefaultTimeout(process.env.CI ? 20000 : 10000) try { @@ -566,7 +560,7 @@ export async function checkApiNavigation(page, base, { sabotage } = {}) { const nav = document.querySelector('.api-nav') sessionStorage.removeItem(`libtmux:api-tree:${nav.dataset.base}`) }) - await page.route('**/tree.json', (route) => route.fulfill({ status: 503, body: 'Unavailable' })) + await page.route('**/tree.json', (route) => new URL(route.request().url()).origin !== new URL(base).origin ? route.fallback() : route.fulfill({ status: 503, body: 'Unavailable' })) await page.reload({ waitUntil: 'commit' }) await page.waitForFunction(() => window.__docsPageLoaded) await page.locator('[data-api-nav-toggle]').click() @@ -630,7 +624,7 @@ export async function checkApiNavigation(page, base, { sabotage } = {}) { await page.keyboard.press('Escape') assert.equal(await page.locator('.api-nav').evaluate((nav) => nav.inert), true, 'The CLI drawer dismisses with Escape') await page.setViewportSize({ width: 1440, height: 900 }) - await page.route('**/tree.json', (route) => route.fulfill({ status: 503, body: 'Unavailable' })) + await page.route('**/tree.json', (route) => new URL(route.request().url()).origin !== new URL(base).origin ? route.fallback() : route.fulfill({ status: 503, body: 'Unavailable' })) await page.goto(`${base}/lua/latest/reference/`, { waitUntil: 'commit' }) await page.waitForFunction(() => window.__docsPageLoaded) assert.equal(await page.locator('.api-nav__tree [role="treeitem"][tabindex="0"]').count(), 1, 'The server-rendered index remains keyboard reachable when its inventory cannot load') @@ -641,7 +635,7 @@ export async function checkApiNavigation(page, base, { sabotage } = {}) { /** Public symbol fragments and earlier declaration links reach the same bar. */ export async function checkApiAnchorArrival(browser, base) { const paths = new Set([`${base}/py/latest/reference/libtmux-_internal-query_list-querylist/`]) - const catalog = await browser.newPage() + const catalog = await newCheckPage(browser, base) try { for (const port of PORTS) { await catalog.goto(`${base}/${port.slug}/latest/reference/`, { waitUntil: 'load' }) @@ -656,7 +650,7 @@ export async function checkApiAnchorArrival(browser, base) { [390, 'light', true], [1280, 'dark', true], [390, 'dark', false], [1280, 'light', false], ]) { - const context = await browser.newContext({ viewport: { width, height: 1000 }, colorScheme, + const context = await newCheckContext(browser, base, { viewport: { width, height: 1000 }, colorScheme, javaScriptEnabled, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) @@ -714,7 +708,7 @@ export async function checkPermalinkReveal(browser, base, { only, sabotage } = { ['a parameter line', 'ul.api-parameters > li[id] > p > a.api-heading-link']]], ] const open = async (options) => { - const context = await browser.newContext({ reducedMotion: 'reduce', ...options }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce', ...options }) if (sabotage?.css) await context.addInitScript((css) => document.addEventListener('DOMContentLoaded', () => { document.head.append(Object.assign(document.createElement('style'), { textContent: css })) }), sabotage.css) @@ -947,7 +941,7 @@ export async function checkPermalinkRevealFail(browser, base) { /** The control for `checkApiNavigation`: a drawer whose close button does nothing must fail it. */ export async function checkApiNavigationFail(browser, base) { - const page = await browser.newPage({ reducedMotion: 'reduce' }) + const page = await newCheckPage(browser, base, { reducedMotion: 'reduce' }) try { await assert.rejects(() => checkApiNavigation(page, base, { sabotage: () => { document.addEventListener('click', (event) => { @@ -963,7 +957,7 @@ export async function checkApiNavigationFail(browser, base) { * style to the page, for the control below. */ export async function checkReferenceSidebarBounds(browser, base, { sabotage } = {}) { - const page = await browser.newPage({ viewport: { width: 1233, height: 1220 }, reducedMotion: 'reduce', colorScheme: 'dark' }) + const page = await newCheckPage(browser, base, { viewport: { width: 1233, height: 1220 }, reducedMotion: 'reduce', colorScheme: 'dark' }) try { await page.goto(`${base}/tmux/latest/manual/#options`) await page.locator('html[data-page-readiness="ready"]').waitFor() @@ -1024,7 +1018,7 @@ export async function checkApiStickyHeadings(browser, base, { only, sabotage } = const timeout = process.env.CI ? 20000 : 10000 const wants = (scenario) => !only || only.includes(scenario) const open = async (viewport) => { - const context = await browser.newContext({ viewport }) + const context = await newCheckContext(browser, base, { viewport }) if (sabotage?.script) await context.addInitScript(sabotage.script) const page = await context.newPage() page.setDefaultTimeout(timeout) @@ -1380,7 +1374,7 @@ export async function checkNavigation(page, base) { await page.goto(`${legacy}?from=legacy#where-this-comes-from`, { waitUntil: 'load' }) await page.waitForURL(`${current}?from=legacy#where-this-comes-from`) assert.equal(await page.locator('#where-this-comes-from').count(), 1, 'Legacy section still exists') - const fallback = await page.context().browser().newContext({ javaScriptEnabled: false }) + const fallback = await newCheckContext(page.context().browser(), base, { javaScriptEnabled: false }) try { const reader = await fallback.newPage() await reader.goto(legacy, { waitUntil: 'load' }) @@ -1412,7 +1406,7 @@ export async function checkApiExampleOwnership(page, base, path = 'ts/latest/ref * attributes that snippet set on , so the widget has to restore them. */ export async function checkMcpInstallRevisit(browser, base) { - const page = await browser.newPage({ reducedMotion: 'reduce' }) + const page = await newCheckPage(browser, base, { reducedMotion: 'reduce' }) try { const shown = () => page.evaluate(() => [...document.querySelectorAll('.lm-mcp-install__panel')] .filter((panel) => panel.checkVisibility()).length) diff --git a/site/scripts/check-page-readiness.mjs b/site/scripts/check-page-readiness.mjs index 81a6ef95e..d49f7ba71 100644 --- a/site/scripts/check-page-readiness.mjs +++ b/site/scripts/check-page-readiness.mjs @@ -1,3 +1,4 @@ +import { newCheckContext, newCheckPage } from './browser-context.mjs' import assert from 'node:assert/strict' import pixelmatch from 'pixelmatch' import { PNG } from 'pngjs' @@ -56,7 +57,7 @@ async function observeAppearance(context) { /** Optional policy and beacon requests cannot hold browser lifecycle events. */ export async function checkWebAnalytics(browser, base) { for (const kind of ['beacon', 'policy', 'excluded']) { - const context = await browser.newContext({ viewport: { width: 390, height: 900 } }) + const context = await newCheckContext(browser, base, { viewport: { width: 390, height: 900 } }) await observeAppearance(context) const page = await context.newPage() const errors = [] @@ -65,6 +66,7 @@ export async function checkWebAnalytics(browser, base) { const held = new Promise((resolve) => { release = resolve }) try { await page.route('**/_shell/web-analytics.json', async (route) => { + if (new URL(route.request().url()).origin !== new URL(base).origin) return route.fallback() if (kind === 'policy') { requested = true await held @@ -123,13 +125,14 @@ export async function checkWebAnalytics(browser, base) { /** Reproduce a late beacon arriving between an Astro swap and script execution. */ export async function checkWebAnalyticsTransitions(browser, base) { for (const markHandled of [true, false]) { - const context = await browser.newContext({ reducedMotion: 'reduce', viewport: { width: 390, height: 900 } }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce', viewport: { width: 390, height: 900 } }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) let release, requested = false const held = new Promise((resolve) => { release = resolve }) try { await page.route('**/_shell/web-analytics.json', async (route) => { + if (new URL(route.request().url()).origin !== new URL(base).origin) return route.fallback() const response = await route.fetch() await route.fulfill({ response, headers: { ...response.headers(), 'x-libtmux-analytics': 'allow' } }) }) @@ -186,7 +189,7 @@ export async function checkRequiredAppearance(browser, base) { ['module', '/java/latest/reference/io-github-libtmux-buffers-buffers-delete/', 1280], ['effect', '/prompts/?port=ts', 390], ]) { - const context = await browser.newContext({ viewport: { width, height: 900 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width, height: 900 }, reducedMotion: 'reduce' }) await observeAppearance(context) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) @@ -214,6 +217,7 @@ export async function checkRequiredAppearance(browser, base) { : request.url() === module const incoming = page.waitForRequest(required) await page.route('**/*', async (route) => { + if (new URL(route.request().url()).origin !== new URL(base).origin) return route.fallback() if (required(route.request())) { requested = true; await hold } if (kind === 'effect' && required(route.request())) { // Exercise insertion even when a new preview's actual manifest has @@ -225,7 +229,7 @@ export async function checkRequiredAppearance(browser, base) { await route.fulfill({ json: { schema: 1, ports: { py: entries, ts: entries } } }) return } - await route.continue() + await route.fallback() }) await page.goto(`${base}${path}`, { waitUntil: 'commit' }) await incoming @@ -273,11 +277,11 @@ export async function checkRequiredAppearance(browser, base) { } finally { release(); await context.close() } } - const context = await browser.newContext({ reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) try { - await page.route('**/*', (route) => route.request().resourceType() === 'font' ? route.abort() : route.continue()) + await page.route('**/*', (route) => route.request().resourceType() === 'font' ? route.abort() : route.fallback()) await page.goto(`${base}/`, { waitUntil: 'commit' }) await page.getByRole('alert').waitFor({ state: 'visible' }) assert.equal(await page.locator('html').getAttribute('data-page-readiness'), 'failed') @@ -288,7 +292,7 @@ export async function checkRequiredAppearance(browser, base) { await page.locator('html[data-page-readiness="ready"]').waitFor({ state: 'attached' }) assert(await page.locator('main h1').isVisible(), 'Reload recovers after the required resource becomes available') } finally { await context.close() } - const legacy = await browser.newPage() + const legacy = await newCheckPage(browser, base) try { const probe = `${base}/legacy-shell-probe/` await legacy.route(probe, (route) => route.fulfill({ contentType: 'text/html', body: @@ -461,7 +465,7 @@ async function addBadgeLinkFixtures(page) { * name's text, and leads it by about a quarter em. */ export async function checkKindBadgeLinks(browser, base, { sample = false, entries = BADGE_LINKS } = {}) { - const context = await browser.newContext({ reducedMotion: 'reduce', viewport: { width: 1600, height: 1000 } }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce', viewport: { width: 1600, height: 1000 } }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) const failures = [] @@ -564,7 +568,7 @@ function dottedDecorations() { * line; only inline text runs carry the dotted underline. */ export async function checkBlockLinksUndecorated(browser, base, { sample = false } = {}) { - const context = await browser.newContext({ reducedMotion: 'reduce', viewport: { width: 1440, height: 1000 } }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce', viewport: { width: 1440, height: 1000 } }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) const failures = [] @@ -676,7 +680,7 @@ async function functionLinkMarked(page) { * taken away, and a page that never had the section. */ export async function checkTmuxReferencePreviewsFail(browser, base) { - const context = await browser.newContext({ reducedMotion: 'reduce', viewport: { width: 1440, height: 1000 } }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce', viewport: { width: 1440, height: 1000 } }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) try { @@ -700,7 +704,7 @@ const TMUX_FUNCTION_LINK = 'section.api-tmux-section:has(> #api-tmux-command) .t const TMUX_METHOD_PAGE = '/cxx/latest/reference/libtmux-server-panes/' export async function checkTmuxReferencePreviews(browser, base, { served: build } = {}) { - const context = await browser.newContext({ reducedMotion: 'reduce', viewport: { width: 1440, height: 1000 } }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce', viewport: { width: 1440, height: 1000 } }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) const opened = () => page.evaluate(() => document.getElementById('reference-link-preview')?.matches(':popover-open') ?? false) diff --git a/site/scripts/check-picker-filters.mjs b/site/scripts/check-picker-filters.mjs index 3aa0c47bb..45eda7db9 100644 --- a/site/scripts/check-picker-filters.mjs +++ b/site/scripts/check-picker-filters.mjs @@ -1,3 +1,4 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' async function bounds(page, panel) { @@ -61,7 +62,7 @@ async function exercise(page, selector, query, count) { export async function checkPickerFilters(browser, base, complete = false) { const sizes = complete ? [{ width: 853, height: 789 }, { width: 320, height: 360 }, { width: 280, height: 320 }] : [{ width: 320, height: 360 }] for (const colorScheme of complete ? ['light', 'dark'] : ['light']) { - const context = await browser.newContext({ colorScheme, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { colorScheme, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(5000) try { @@ -77,10 +78,11 @@ export async function checkPickerFilters(browser, base, complete = false) { } if (!complete) return - const context = await browser.newContext({ viewport: { width: 853, height: 789 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width: 853, height: 789 }, reducedMotion: 'reduce' }) let release const pending = new Promise((resolve) => { release = resolve }) await context.route('**/versions.json', async (route) => { + if (new URL(route.request().url()).origin !== new URL(base).origin) return route.fallback() await pending await route.fulfill({ contentType: 'application/json', body: JSON.stringify({ schema: 1, ports: { kotlin: [ { slug: 'latest', label: 'latest', kind: 'trunk', supported: true }, @@ -120,7 +122,7 @@ export async function checkPickerFilters(browser, base, complete = false) { assert.equal(new URL(page.url()).hash, '#demo-versions', 'Sample versions use their own destination after choosing a sample language') } finally { release(); await context.unrouteAll({ behavior: 'wait' }); await context.close() } - const noScript = await browser.newContext({ javaScriptEnabled: false, viewport: { width: 853, height: 789 } }) + const noScript = await newCheckContext(browser, base, { javaScriptEnabled: false, viewport: { width: 853, height: 789 } }) try { const page = await noScript.newPage() await page.goto(`${base}/demo/widgets/pickers/`) diff --git a/site/scripts/check-reference-preferences.mjs b/site/scripts/check-reference-preferences.mjs index b1da486c5..6d9e37c71 100644 --- a/site/scripts/check-reference-preferences.mjs +++ b/site/scripts/check-reference-preferences.mjs @@ -1,10 +1,11 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' /** Exercise native disclosures and fragment navigation on a short API page. */ export async function checkReferencePreferences(browser, base) { const path = '/java/latest/reference/io-github-libtmux-buffers-buffers-delete/' const key = 'libtmux-docs.api-source-details' - const context = await browser.newContext({ reducedMotion: 'reduce', viewport: { width: 784, height: 760 } }) + const context = await newCheckContext(browser, base, { reducedMotion: 'reduce', viewport: { width: 784, height: 760 } }) await context.addInitScript(() => { window.__sourceFrames = [] const seen = new WeakSet() @@ -82,7 +83,7 @@ export async function checkReferencePreferences(browser, base) { } for (const javaScriptEnabled of [false, true]) { - const fallback = await browser.newContext({ javaScriptEnabled, reducedMotion: 'reduce' }) + const fallback = await newCheckContext(browser, base, { javaScriptEnabled, reducedMotion: 'reduce' }) if (javaScriptEnabled) await fallback.addInitScript(() => { Object.defineProperty(window, 'localStorage', { get() { throw new Error('Storage blocked') } }) }) @@ -208,7 +209,7 @@ export async function checkHeaderLinks(page, path, width, scripted) { */ export async function checkHeaderLinksFail(browser, base) { const run = async ({ path = '/rs/latest/', width = 1440, css, script }) => { - const context = await browser.newContext({ javaScriptEnabled: true, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { javaScriptEnabled: true, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) try { @@ -277,7 +278,7 @@ export async function checkHeaderLinksRender(browser, base, { path = '/rs/latest if ((script || css) && javaScript.includes(false)) throw new Error('checkHeaderLinksRender: script and css apply only where JavaScript is on') for (const colorScheme of schemes) for (const width of widths) for (const javaScriptEnabled of javaScript) { const where = `${path} at ${width}px, ${colorScheme}, ${javaScriptEnabled ? 'with' : 'without'} JavaScript` - const context = await browser.newContext({ viewport: { width, height: 900 }, colorScheme, javaScriptEnabled, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width, height: 900 }, colorScheme, javaScriptEnabled, reducedMotion: 'reduce' }) if (javaScriptEnabled) { await context.addInitScript(() => { window.__headerShift = 0 @@ -405,7 +406,7 @@ export async function checkHeaderLinksRenderFail(browser, base) { /** The global header has no repeated destination strip, including without JS. */ export async function checkGlobalHeader(browser, base) { for (const javaScriptEnabled of [false, true]) { - const context = await browser.newContext({ javaScriptEnabled, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { javaScriptEnabled, reducedMotion: 'reduce' }) const page = await context.newPage() const headerFrames = new Map() try { @@ -464,7 +465,7 @@ export async function checkScrollbarStability(browser, base) { }) try { for (const width of [280, 628, 1280]) for (const colorScheme of ['light', 'dark']) for (const javaScriptEnabled of [true, false]) { - const context = await classic.newContext({ viewport: { width, height: 900 }, colorScheme, javaScriptEnabled, reducedMotion: 'reduce' }) + const context = await newCheckContext(classic, base, { viewport: { width, height: 900 }, colorScheme, javaScriptEnabled, reducedMotion: 'reduce' }) const page = await context.newPage() const frame = () => page.evaluate(() => { const rect = (selector) => { diff --git a/site/scripts/check-ruby-lua.mjs b/site/scripts/check-ruby-lua.mjs index 558a7b533..7b9bf8fba 100644 --- a/site/scripts/check-ruby-lua.mjs +++ b/site/scripts/check-ruby-lua.mjs @@ -1,5 +1,6 @@ #!/usr/bin/env node /** Browser coverage for the Ruby and Lua documentation surfaces. */ +import { newCheckContext } from './browser-context.mjs' import { chromium } from 'playwright' const BASE = (process.argv[2] ?? 'http://localhost:8080/en').replace(/\/$/, '') @@ -33,7 +34,7 @@ const check = (condition, message) => { for (const scheme of ['light', 'dark']) { for (const [viewport, width, height] of VIEWPORTS) { - const context = await browser.newContext({ + const context = await newCheckContext(browser, base, { viewport: { width, height }, colorScheme: scheme, }) diff --git a/site/scripts/check-sidebar-demo.mjs b/site/scripts/check-sidebar-demo.mjs index 3ceb43692..4ac27f13d 100644 --- a/site/scripts/check-sidebar-demo.mjs +++ b/site/scripts/check-sidebar-demo.mjs @@ -1,5 +1,6 @@ #!/usr/bin/env node // Outer loop: real browser interactions across sidebar modes, themes, and viewports. +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' import { mkdir } from 'node:fs/promises' import { resolve } from 'node:path' @@ -10,7 +11,7 @@ import { chromium } from 'playwright' export async function checkSidebarDemo(browser, url, options = {}) { const values = { url, screenshots: options.screenshots, 'negative-control': options.negativeControl } const started = performance.now() - const context = await browser.newContext({ viewport: { width: 1600, height: 1150 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width: 1600, height: 1150 }, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(1000) const navigationTimeout = process.env.CI ? 20000 : 10000 diff --git a/site/scripts/check-status-badges.mjs b/site/scripts/check-status-badges.mjs index 8b920199a..899986589 100644 --- a/site/scripts/check-status-badges.mjs +++ b/site/scripts/check-status-badges.mjs @@ -1,3 +1,4 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' import { CONCEPT_DESCRIPTION, PICKER_GROUP_SUMMARY, PORT_BY_SLUG, PRODUCT_STATUS_GUIDE, PRODUCT_STATUS_LINK, productStatusLine, productAvailable, productStatus } from '../src/lib/ports.ts' import registry from '../src/data/registry.json' with { type: 'json' } @@ -222,7 +223,7 @@ export async function checkStatusBadges(browser, base, options = {}) { touch = true, timeout, sabotage } = options let rows = 0 for (const scheme of schemes) { - const context = await browser.newContext({ colorScheme: scheme, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { colorScheme: scheme, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(timeout ?? (process.env.CI ? 20000 : 10000)) page.setDefaultNavigationTimeout(60000) @@ -269,7 +270,7 @@ export async function checkStatusBadges(browser, base, options = {}) { } } if (touch && !sabotage) { - const context = await browser.newContext({ viewport: { width: 390, height: 844 }, hasTouch: true, isMobile: true, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width: 390, height: 844 }, hasTouch: true, isMobile: true, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) page.setDefaultNavigationTimeout(60000) diff --git a/site/scripts/check-style-parity.mjs b/site/scripts/check-style-parity.mjs index ead796b35..09c48e390 100755 --- a/site/scripts/check-style-parity.mjs +++ b/site/scripts/check-style-parity.mjs @@ -17,6 +17,7 @@ * * Usage: node scripts/check-style-parity.mjs [base-url] */ +import { newCheckPage } from './browser-context.mjs' import { chromium } from 'playwright' const base = process.argv[2] ?? 'http://localhost:8080' @@ -163,7 +164,7 @@ async function styles(page, url, cases, side) { } const browser = await chromium.launch() -const page = await browser.newPage({ viewport: { width: 1440, height: 900 } }) +const page = await newCheckPage(browser, base, { viewport: { width: 1440, height: 900 } }) const sphinx = await styles(page, SPHINX, CASES, 'sphinx') /* * Two visits, one array. diff --git a/site/scripts/check-tables.mjs b/site/scripts/check-tables.mjs index 254eea1f6..f5b5bb2c7 100644 --- a/site/scripts/check-tables.mjs +++ b/site/scripts/check-tables.mjs @@ -1,4 +1,5 @@ #!/usr/bin/env node +import { newCheckPage } from './browser-context.mjs' import assert from 'node:assert/strict' import { globSync, readFileSync } from 'node:fs' import { join } from 'node:path' @@ -31,7 +32,7 @@ const browser = await chromium.launch({ channel: process.env.LIBTMUX_DOCS_BROWSE let checked = 0 try { for (const width of [1440, 768, 390]) { - const page = await browser.newPage({ viewport: { width, height: 1000 } }) + const page = await newCheckPage(browser, base, { viewport: { width, height: 1000 } }) for (const path of paths) { const response = await page.goto(base + path) assert(response?.ok(), `${path}: HTTP ${response?.status()}`) diff --git a/site/scripts/check-tmux-keys.mjs b/site/scripts/check-tmux-keys.mjs index 20d3d05f0..fadc9d09c 100644 --- a/site/scripts/check-tmux-keys.mjs +++ b/site/scripts/check-tmux-keys.mjs @@ -1,3 +1,4 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' /** Contrast of a rendered element's text against what is painted behind it. */ @@ -53,7 +54,7 @@ export const TMUX_KEY_PAGES = [ */ export async function checkTmuxKeys(browser, base) { for (const colorScheme of ['light', 'dark']) { - const context = await browser.newContext({ colorScheme, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { colorScheme, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) const errors = [] diff --git a/site/scripts/check-type-parameters.mjs b/site/scripts/check-type-parameters.mjs index a7ffe4637..d7bbbf330 100644 --- a/site/scripts/check-type-parameters.mjs +++ b/site/scripts/check-type-parameters.mjs @@ -1,3 +1,4 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' /** @@ -18,7 +19,7 @@ export const TYPE_PARAMETER_PAGES = [ * declaration exists on the owner's page, and the Markdown twin says the same. */ export async function checkTypeParameters(browser, base, pages = TYPE_PARAMETER_PAGES) { - const context = await browser.newContext({ viewport: { width: 1280, height: 1000 }, reducedMotion: 'reduce' }) + const context = await newCheckContext(browser, base, { viewport: { width: 1280, height: 1000 }, reducedMotion: 'reduce' }) const page = await context.newPage() page.setDefaultTimeout(process.env.CI ? 20000 : 10000) try { diff --git a/site/scripts/check-visual.mjs b/site/scripts/check-visual.mjs index 10e9e16da..9caa7b658 100755 --- a/site/scripts/check-visual.mjs +++ b/site/scripts/check-visual.mjs @@ -17,6 +17,7 @@ * * Usage: node scripts/check-visual.mjs [--update] [base-url] */ +import { newCheckPage } from './browser-context.mjs' import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs' import { dirname, join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' @@ -60,7 +61,7 @@ let written = 0 for (const [scheme] of [['light'], ['dark']]) { for (const [vname, width, height] of VIEWPORTS) { - const page = await browser.newPage({ viewport: { width, height }, colorScheme: scheme }) + const page = await newCheckPage(browser, base, { viewport: { width, height }, colorScheme: scheme }) for (const [pname, path] of PAGES) { const name = `${pname}-${vname}-${scheme}.png` const file = join(dir, name) diff --git a/site/scripts/check-workspace-hover.mjs b/site/scripts/check-workspace-hover.mjs index 5bdcf5c6d..8ed8274fe 100644 --- a/site/scripts/check-workspace-hover.mjs +++ b/site/scripts/check-workspace-hover.mjs @@ -1,8 +1,9 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' /** Real pointer events on the preset picker, with the clock advanced instead of sleeping. */ export async function checkWorkspaceHover(browser, base) { - const context = await browser.newContext({ viewport: { width: 1280, height: 900 }, colorScheme: 'light' }) + const context = await newCheckContext(browser, base, { viewport: { width: 1280, height: 900 }, colorScheme: 'light' }) const page = await context.newPage() const errors = [] page.on('pageerror', (error) => errors.push(error.message)) diff --git a/site/scripts/check-workspace-shift.mjs b/site/scripts/check-workspace-shift.mjs index 3575d55f9..db8d68211 100644 --- a/site/scripts/check-workspace-shift.mjs +++ b/site/scripts/check-workspace-shift.mjs @@ -1,8 +1,9 @@ +import { newCheckContext } from './browser-context.mjs' import assert from 'node:assert/strict' /** A cold deep link into the preset picker lands in one scroll and shifts nothing. */ export async function checkWorkspaceShift(browser, base) { - const context = await browser.newContext({ viewport: { width: 1280, height: 900 }, colorScheme: 'light' }) + const context = await newCheckContext(browser, base, { viewport: { width: 1280, height: 900 }, colorScheme: 'light' }) const page = await context.newPage() const errors = [] page.on('pageerror', (error) => errors.push(error.message)) From 83ea95328bedb09e8b5322aaa3d5177be4048e2c Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 7 Nov 2026 18:32:01 -0600 Subject: [PATCH 03/30] docs(feat[perl]) Integrate native Perl API and source distributions why: Perl callers need native reference material and runnable source-package workflows tied to the code they can install. what: - Preserve PPI signatures, authored POD links, source identities and command evidence - Register core, optional async and workspace packages with source-only availability - Add reader guides, owned examples, navigation and shared branding - Separate compiler and catalog audits from development checks and preserve unchanged guides - Keep model readers and preview metadata independent of native extraction setup --- .github/CONTRIBUTING.md | 31 +- .github/workflows/port-docs.yml | 52 +- .github/workflows/reusable-deploy.yml | 4 +- notes/adding-a-port.md | 6 +- packages/api-model/package.json | 6 +- packages/api-model/src/concepts.ts | 115 + packages/api-model/src/doc/roles.ts | 6 +- packages/api-model/src/index.ts | 1 + packages/api-model/src/inventory.ts | 1 + packages/api-model/src/languages/perl.ts | 77 + packages/api-model/src/mentions.ts | 1 + packages/api-model/src/model.ts | 4 +- packages/api-model/src/nav-config.ts | 15 +- packages/api-model/src/prose-fields.ts | 1 + packages/api-model/src/prose.ts | 1 + packages/api-model/src/reference.ts | 24 + packages/api-model/src/resolver.ts | 1 + packages/api-model/test/guarantees.test.ts | 72 +- .../test/inventory-sphinx.outer.test.ts | 72 + packages/api-model/test/perl.test.ts | 50 + .../api-model/test/prose-audit.outer.test.ts | 45 + packages/api-model/test/prose-audit.test.ts | 40 - .../test/resolver-corpus.outer.test.ts | 50 + packages/api-model/test/resolver.test.ts | 39 +- scripts/build-site.sh | 14 +- scripts/gen-api-model.mjs | 7 +- scripts/gen-tmux-usage.mjs | 8 +- scripts/gen-workspace-showcase.mjs | 12 +- scripts/lib/api-destinations.mjs | 1 + scripts/lib/api-identities.mjs | 10 + scripts/lib/api-links.mjs | 3 +- scripts/lib/api-sources.mjs | 1 + scripts/lib/destination-verification.mjs | 12 +- scripts/lib/manifest-packages.mjs | 14 +- scripts/lib/tmux-usage-perl.mjs | 44 + scripts/lib/tmux-usage-scan.mjs | 10 +- scripts/lib/tmux-usage-sweep.mjs | 1 + scripts/publication-provenance.mjs | 2 +- scripts/stage-port-docs.mjs | 55 +- scripts/test-loop.mjs | 23 +- scripts/test-tiers.json | 150 + scripts/tmux-usage/claims.json | 5872 +++++++++++++++++ scripts/tmux-usage/not-senders.json | 162 + site/public/_shell/brand.css | 125 + site/public/_shell/shell.js | 1 + site/public/brand/catalog.json | 933 ++- site/public/brand/languages/perl/LICENSE.txt | 20 + site/public/brand/languages/perl/icon.svg | 1 + .../brand/languages/perl/provenance.json | 25 + .../brand/perl/library/app-icon-1024-dark.png | Bin 0 -> 28398 bytes .../perl/library/app-icon-1024-light.png | Bin 0 -> 28089 bytes .../perl/library/apple-touch-icon-dark.png | Bin 0 -> 3853 bytes .../perl/library/apple-touch-icon-light.png | Bin 0 -> 3823 bytes .../brand/perl/library/browserconfig-dark.xml | 1 + .../brand/perl/library/browserconfig.xml | 1 + site/public/brand/perl/library/favicon.ico | Bin 0 -> 22603 bytes .../brand/perl/library/github-social-dark.png | Bin 0 -> 38324 bytes .../perl/library/github-social-light.png | Bin 0 -> 37946 bytes site/public/brand/perl/library/logo-1024.png | Bin 0 -> 36411 bytes site/public/brand/perl/library/logo-128.png | Bin 0 -> 3699 bytes site/public/brand/perl/library/logo-144.png | Bin 0 -> 4159 bytes site/public/brand/perl/library/logo-152.png | Bin 0 -> 4303 bytes site/public/brand/perl/library/logo-16.png | Bin 0 -> 588 bytes site/public/brand/perl/library/logo-167.png | Bin 0 -> 4768 bytes site/public/brand/perl/library/logo-180.png | Bin 0 -> 5248 bytes site/public/brand/perl/library/logo-192.png | Bin 0 -> 5586 bytes site/public/brand/perl/library/logo-24.png | Bin 0 -> 778 bytes site/public/brand/perl/library/logo-256.png | Bin 0 -> 7501 bytes site/public/brand/perl/library/logo-32.png | Bin 0 -> 1038 bytes site/public/brand/perl/library/logo-384.png | Bin 0 -> 11621 bytes site/public/brand/perl/library/logo-48.png | Bin 0 -> 1493 bytes site/public/brand/perl/library/logo-512.png | Bin 0 -> 16073 bytes site/public/brand/perl/library/logo-64.png | Bin 0 -> 1920 bytes site/public/brand/perl/library/logo-96.png | Bin 0 -> 2761 bytes site/public/brand/perl/library/logo.svg | 2 + .../brand/perl/library/maskable-192-dark.png | Bin 0 -> 3101 bytes .../brand/perl/library/maskable-192-light.png | Bin 0 -> 3076 bytes .../brand/perl/library/maskable-512-dark.png | Bin 0 -> 9321 bytes .../brand/perl/library/maskable-512-light.png | Bin 0 -> 9235 bytes .../brand/perl/library/mstile-150-dark.png | Bin 0 -> 3020 bytes .../brand/perl/library/mstile-150-light.png | Bin 0 -> 2992 bytes .../brand/perl/library/mstile-310-dark.png | Bin 0 -> 6514 bytes .../brand/perl/library/mstile-310-light.png | Bin 0 -> 6457 bytes .../brand/perl/library/opengraph-dark.jpg | Bin 0 -> 60448 bytes .../brand/perl/library/opengraph-dark.png | Bin 0 -> 38701 bytes .../brand/perl/library/opengraph-light.jpg | Bin 0 -> 64251 bytes .../brand/perl/library/opengraph-light.png | Bin 0 -> 38308 bytes .../brand/perl/library/safari-pinned-tab.svg | 2 + .../brand/perl/library/site-dark.webmanifest | 36 + .../brand/perl/library/site.webmanifest | 36 + .../brand/perl/library/social-square-dark.png | Bin 0 -> 44221 bytes .../perl/library/social-square-light.png | Bin 0 -> 43918 bytes .../brand/perl/library/twitter-dark.png | Bin 0 -> 38505 bytes .../brand/perl/library/twitter-light.png | Bin 0 -> 38109 bytes .../perl/workspace/app-icon-1024-dark.png | Bin 0 -> 11359 bytes .../perl/workspace/app-icon-1024-light.png | Bin 0 -> 11495 bytes .../perl/workspace/apple-touch-icon-dark.png | Bin 0 -> 1285 bytes .../perl/workspace/apple-touch-icon-light.png | Bin 0 -> 1310 bytes .../perl/workspace/browserconfig-dark.xml | 1 + .../brand/perl/workspace/browserconfig.xml | 1 + site/public/brand/perl/workspace/favicon.ico | Bin 0 -> 17557 bytes .../perl/workspace/github-social-dark.png | Bin 0 -> 22972 bytes .../perl/workspace/github-social-light.png | Bin 0 -> 22840 bytes .../public/brand/perl/workspace/logo-1024.png | Bin 0 -> 13757 bytes site/public/brand/perl/workspace/logo-128.png | Bin 0 -> 1143 bytes site/public/brand/perl/workspace/logo-144.png | Bin 0 -> 1296 bytes site/public/brand/perl/workspace/logo-152.png | Bin 0 -> 1327 bytes site/public/brand/perl/workspace/logo-16.png | Bin 0 -> 291 bytes site/public/brand/perl/workspace/logo-167.png | Bin 0 -> 1504 bytes site/public/brand/perl/workspace/logo-180.png | Bin 0 -> 1629 bytes site/public/brand/perl/workspace/logo-192.png | Bin 0 -> 1743 bytes site/public/brand/perl/workspace/logo-24.png | Bin 0 -> 324 bytes site/public/brand/perl/workspace/logo-256.png | Bin 0 -> 2455 bytes site/public/brand/perl/workspace/logo-32.png | Bin 0 -> 415 bytes site/public/brand/perl/workspace/logo-384.png | Bin 0 -> 3781 bytes site/public/brand/perl/workspace/logo-48.png | Bin 0 -> 544 bytes site/public/brand/perl/workspace/logo-512.png | Bin 0 -> 5396 bytes site/public/brand/perl/workspace/logo-64.png | Bin 0 -> 644 bytes site/public/brand/perl/workspace/logo-96.png | Bin 0 -> 856 bytes site/public/brand/perl/workspace/logo.svg | 2 + .../perl/workspace/maskable-192-dark.png | Bin 0 -> 1122 bytes .../perl/workspace/maskable-192-light.png | Bin 0 -> 1137 bytes .../perl/workspace/maskable-512-dark.png | Bin 0 -> 3776 bytes .../perl/workspace/maskable-512-light.png | Bin 0 -> 3815 bytes .../brand/perl/workspace/mstile-150-dark.png | Bin 0 -> 976 bytes .../brand/perl/workspace/mstile-150-light.png | Bin 0 -> 988 bytes .../brand/perl/workspace/mstile-310-dark.png | Bin 0 -> 2180 bytes .../brand/perl/workspace/mstile-310-light.png | Bin 0 -> 2228 bytes .../brand/perl/workspace/opengraph-dark.jpg | Bin 0 -> 41101 bytes .../brand/perl/workspace/opengraph-dark.png | Bin 0 -> 22680 bytes .../brand/perl/workspace/opengraph-light.jpg | Bin 0 -> 43736 bytes .../brand/perl/workspace/opengraph-light.png | Bin 0 -> 22570 bytes .../perl/workspace/safari-pinned-tab.svg | 2 + .../perl/workspace/site-dark.webmanifest | 36 + .../brand/perl/workspace/site.webmanifest | 36 + .../perl/workspace/social-square-dark.png | Bin 0 -> 25379 bytes .../perl/workspace/social-square-light.png | Bin 0 -> 25292 bytes .../brand/perl/workspace/twitter-dark.png | Bin 0 -> 22533 bytes .../brand/perl/workspace/twitter-light.png | Bin 0 -> 22424 bytes site/public/versions.json | 11 +- site/src/components/CoreHome.astro | 7 +- site/src/components/ProseText.astro | 2 +- .../components/api/ApiCommandParameters.astro | 2 +- site/src/components/api/ApiEntry.astro | 2 +- site/src/components/api/ApiReference.astro | 2 +- .../src/components/api/ApiRelationships.astro | 2 +- .../api/ApiSignatureParameters.astro | 2 +- site/src/components/api/ApiType.astro | 2 +- site/src/components/api/ProductApiIndex.astro | 2 +- site/src/components/api/ProductApiPage.astro | 2 +- .../components/mcp/ProtocolReference.astro | 2 +- .../src/content/docs/ports/perl/core/index.md | 23 + .../docs/ports/perl/workspace/index.md | 21 + site/src/data/api-destination-evidence.json | 6 +- site/src/data/api/perl.json | 1 + site/src/data/api/perl.nav.json | 1 + site/src/data/api/perl.paths.json | 1 + site/src/data/core-home.json | 22 + site/src/data/destination-evidence.json | 105 + site/src/data/home-examples.json | 36 + site/src/data/manifest-packages.json | 39 +- site/src/data/mentions.json | 98 + site/src/data/port-guides/perl.json | 52 + site/src/data/registry.json | 30 + site/src/data/tmux-usage/perl.json | 2173 ++++++ site/src/db/seed.ts | 2 +- site/src/lib/api-glossary-routes.ts | 2 +- site/src/lib/api-models.ts | 9 +- site/src/lib/api-relationships.ts | 2 +- site/src/lib/api-sections.ts | 6 +- site/src/lib/api-tmux-sections.ts | 2 +- site/src/lib/api-tree.ts | 2 +- site/src/lib/brand-palettes.json | 26 + site/src/lib/code-language.ts | 32 + site/src/lib/code-layout.ts | 11 +- site/src/lib/core-home.ts | 19 +- site/src/lib/header-links.ts | 8 +- site/src/lib/highlight.ts | 37 +- site/src/lib/inventory-publisher.ts | 2 +- site/src/lib/inventory-targets.ts | 2 +- site/src/lib/link-preview.ts | 6 +- site/src/lib/llms.ts | 2 +- site/src/lib/mcp-preview.ts | 2 +- site/src/lib/mcp-reference.ts | 2 +- site/src/lib/mcp-rest.ts | 2 +- site/src/lib/native-name.ts | 3 +- site/src/lib/page-port-links.ts | 2 +- site/src/lib/port-documentation.ts | 20 + site/src/lib/port-families.ts | 2 +- site/src/lib/port-inventory.ts | 9 + site/src/lib/ports.ts | 30 + site/src/lib/product-api.ts | 2 +- site/src/lib/prose-markdown.ts | 2 +- site/src/lib/prose-resolver.ts | 2 +- site/src/lib/reference-page-links.ts | 2 +- site/src/lib/symbol-form.ts | 1 + site/src/lib/symbol-markdown.ts | 2 +- site/src/lib/tmux-catalog-usage.ts | 2 +- site/src/lib/tmux-catalog.ts | 2 +- site/src/lib/tmux-library-usage.ts | 5 +- site/src/lib/tmux-manual-data.ts | 2 +- site/src/lib/tmux-reference.ts | 2 +- site/src/pages/[...slug].md.ts | 2 +- site/src/pages/[...slug].preview.json.ts | 2 +- site/src/pages/docs.json.ts | 2 +- site/src/pages/reference/[...slug].md.ts | 2 +- .../tmux/[version]/reference/[...slug].md.ts | 2 +- site/src/plugins/rehype-api-links.ts | 2 +- site/src/styles/brand.css | 125 + site/test/api-components.ts | 2 +- site/test/api-db-concepts.outer.test.ts | 2 +- ...i-destination-evidence.publication.test.ts | 94 + site/test/api-destination-evidence.test.ts | 94 +- site/test/api-doc-mentions.test.ts | 2 +- site/test/api-fidelity.test.ts | 2 +- site/test/api-headings.test.ts | 2 +- site/test/api-links-rendered.test.ts | 2 +- site/test/api-prose-fields.test.ts | 2 +- site/test/api-prose.test.ts | 2 +- site/test/api-scalar-members.outer.test.ts | 2 +- site/test/api-sections.test.ts | 9 + site/test/api-signature-scope.test.ts | 2 +- site/test/api-tmux-sections.test.ts | 2 +- site/test/api-tree.test.ts | 2 +- site/test/authored-links.test.ts | 2 +- site/test/branding.test.ts | 6 +- site/test/c-layout.test.ts | 2 +- site/test/concept-coverage.test.ts | 4 +- site/test/core-home.test.ts | 9 + site/test/csharp-layout.test.ts | 2 +- site/test/cxx-layout.test.ts | 2 +- site/test/cxx-signature.test.ts | 2 +- site/test/destination-evidence.test.ts | 17 +- .../elixir-layout-rendering.outer.test.ts | 37 + site/test/elixir-layout.test.ts | 28 - site/test/enum-variants.test.ts | 2 +- site/test/field-members.test.ts | 2 +- site/test/field-table-pages.test.ts | 2 +- site/test/fixtures/header-links.ts | 11 + site/test/fixtures/home-examples.json | 92 + site/test/header-link-data.test.ts | 2 +- site/test/inventory-federation.test.ts | 2 +- site/test/inventory.test.ts | 2 +- site/test/link-preview-payload.test.ts | 2 +- site/test/literal-links.test.ts | 2 +- site/test/lua-layout-rendering.outer.test.ts | 26 + site/test/lua-layout.test.ts | 19 +- site/test/mcp-description-audit.ts | 2 +- site/test/mcp-session.outer.test.ts | 195 + site/test/mcp-session.test.ts | 172 +- site/test/mcp-transcript-checks.test.ts | 165 - site/test/mcp-transcript-corpus.outer.test.ts | 173 + site/test/native-name.test.ts | 4 +- site/test/native-prose-ownership.test.ts | 2 +- site/test/native-shell-context.outer.test.ts | 116 + site/test/native-shell-context.test.ts | 118 +- site/test/native-signature.test.ts | 5 +- site/test/page-transitions.outer.test.ts | 25 + site/test/page-transitions.test.ts | 24 +- site/test/parameter-permalinks.test.ts | 4 +- site/test/perl-pod-links.test.ts | 30 + site/test/perl-source-usage.test.ts | 33 + site/test/port-inventory.test.ts | 19 +- site/test/port-prose.test.ts | 2 +- site/test/powershell-prose-links.test.ts | 2 +- site/test/prerelease-notice.test.ts | 2 +- site/test/product-api-index.test.ts | 2 +- site/test/product-docs.test.ts | 8 +- site/test/product-reference.test.ts | 2 +- site/test/publication-provenance.test.ts | 8 +- site/test/published-inventory.test.ts | 2 +- site/test/python-layout.test.ts | 2 +- site/test/related-labels.test.ts | 2 +- site/test/ruby-layout-rendering.outer.test.ts | 27 + site/test/ruby-layout.test.ts | 20 +- site/test/rust-variant-fields.test.ts | 2 +- site/test/signature-fragment.ts | 1 + site/test/source-only-inventory.test.ts | 26 + site/test/stage-port-docs.outer.test.ts | 9 +- site/test/stage-port-docs.test.ts | 15 +- site/test/swift-layout.test.ts | 2 +- site/test/symbol-form.test.ts | 1 + site/test/tmux-catalog-coverage.outer.test.ts | 2 +- site/test/tmux-catalog-links.test.ts | 2 +- site/test/tmux-links.test.ts | 2 +- site/test/tmux-reference.test.ts | 2 +- site/test/type-alias-declaration.test.ts | 2 +- site/test/type-parameters.test.ts | 2 +- 288 files changed, 12091 insertions(+), 1064 deletions(-) create mode 100644 packages/api-model/src/languages/perl.ts create mode 100644 packages/api-model/src/reference.ts create mode 100644 packages/api-model/test/inventory-sphinx.outer.test.ts create mode 100644 packages/api-model/test/perl.test.ts create mode 100644 packages/api-model/test/prose-audit.outer.test.ts create mode 100644 packages/api-model/test/resolver-corpus.outer.test.ts create mode 100644 scripts/lib/tmux-usage-perl.mjs create mode 100644 scripts/test-tiers.json create mode 100644 site/public/brand/languages/perl/LICENSE.txt create mode 100644 site/public/brand/languages/perl/icon.svg create mode 100644 site/public/brand/languages/perl/provenance.json create mode 100644 site/public/brand/perl/library/app-icon-1024-dark.png create mode 100644 site/public/brand/perl/library/app-icon-1024-light.png create mode 100644 site/public/brand/perl/library/apple-touch-icon-dark.png create mode 100644 site/public/brand/perl/library/apple-touch-icon-light.png create mode 100644 site/public/brand/perl/library/browserconfig-dark.xml create mode 100644 site/public/brand/perl/library/browserconfig.xml create mode 100644 site/public/brand/perl/library/favicon.ico create mode 100644 site/public/brand/perl/library/github-social-dark.png create mode 100644 site/public/brand/perl/library/github-social-light.png create mode 100644 site/public/brand/perl/library/logo-1024.png create mode 100644 site/public/brand/perl/library/logo-128.png create mode 100644 site/public/brand/perl/library/logo-144.png create mode 100644 site/public/brand/perl/library/logo-152.png create mode 100644 site/public/brand/perl/library/logo-16.png create mode 100644 site/public/brand/perl/library/logo-167.png create mode 100644 site/public/brand/perl/library/logo-180.png create mode 100644 site/public/brand/perl/library/logo-192.png create mode 100644 site/public/brand/perl/library/logo-24.png create mode 100644 site/public/brand/perl/library/logo-256.png create mode 100644 site/public/brand/perl/library/logo-32.png create mode 100644 site/public/brand/perl/library/logo-384.png create mode 100644 site/public/brand/perl/library/logo-48.png create mode 100644 site/public/brand/perl/library/logo-512.png create mode 100644 site/public/brand/perl/library/logo-64.png create mode 100644 site/public/brand/perl/library/logo-96.png create mode 100644 site/public/brand/perl/library/logo.svg create mode 100644 site/public/brand/perl/library/maskable-192-dark.png create mode 100644 site/public/brand/perl/library/maskable-192-light.png create mode 100644 site/public/brand/perl/library/maskable-512-dark.png create mode 100644 site/public/brand/perl/library/maskable-512-light.png create mode 100644 site/public/brand/perl/library/mstile-150-dark.png create mode 100644 site/public/brand/perl/library/mstile-150-light.png create mode 100644 site/public/brand/perl/library/mstile-310-dark.png create mode 100644 site/public/brand/perl/library/mstile-310-light.png create mode 100644 site/public/brand/perl/library/opengraph-dark.jpg create mode 100644 site/public/brand/perl/library/opengraph-dark.png create mode 100644 site/public/brand/perl/library/opengraph-light.jpg create mode 100644 site/public/brand/perl/library/opengraph-light.png create mode 100644 site/public/brand/perl/library/safari-pinned-tab.svg create mode 100644 site/public/brand/perl/library/site-dark.webmanifest create mode 100644 site/public/brand/perl/library/site.webmanifest create mode 100644 site/public/brand/perl/library/social-square-dark.png create mode 100644 site/public/brand/perl/library/social-square-light.png create mode 100644 site/public/brand/perl/library/twitter-dark.png create mode 100644 site/public/brand/perl/library/twitter-light.png create mode 100644 site/public/brand/perl/workspace/app-icon-1024-dark.png create mode 100644 site/public/brand/perl/workspace/app-icon-1024-light.png create mode 100644 site/public/brand/perl/workspace/apple-touch-icon-dark.png create mode 100644 site/public/brand/perl/workspace/apple-touch-icon-light.png create mode 100644 site/public/brand/perl/workspace/browserconfig-dark.xml create mode 100644 site/public/brand/perl/workspace/browserconfig.xml create mode 100644 site/public/brand/perl/workspace/favicon.ico create mode 100644 site/public/brand/perl/workspace/github-social-dark.png create mode 100644 site/public/brand/perl/workspace/github-social-light.png create mode 100644 site/public/brand/perl/workspace/logo-1024.png create mode 100644 site/public/brand/perl/workspace/logo-128.png create mode 100644 site/public/brand/perl/workspace/logo-144.png create mode 100644 site/public/brand/perl/workspace/logo-152.png create mode 100644 site/public/brand/perl/workspace/logo-16.png create mode 100644 site/public/brand/perl/workspace/logo-167.png create mode 100644 site/public/brand/perl/workspace/logo-180.png create mode 100644 site/public/brand/perl/workspace/logo-192.png create mode 100644 site/public/brand/perl/workspace/logo-24.png create mode 100644 site/public/brand/perl/workspace/logo-256.png create mode 100644 site/public/brand/perl/workspace/logo-32.png create mode 100644 site/public/brand/perl/workspace/logo-384.png create mode 100644 site/public/brand/perl/workspace/logo-48.png create mode 100644 site/public/brand/perl/workspace/logo-512.png create mode 100644 site/public/brand/perl/workspace/logo-64.png create mode 100644 site/public/brand/perl/workspace/logo-96.png create mode 100644 site/public/brand/perl/workspace/logo.svg create mode 100644 site/public/brand/perl/workspace/maskable-192-dark.png create mode 100644 site/public/brand/perl/workspace/maskable-192-light.png create mode 100644 site/public/brand/perl/workspace/maskable-512-dark.png create mode 100644 site/public/brand/perl/workspace/maskable-512-light.png create mode 100644 site/public/brand/perl/workspace/mstile-150-dark.png create mode 100644 site/public/brand/perl/workspace/mstile-150-light.png create mode 100644 site/public/brand/perl/workspace/mstile-310-dark.png create mode 100644 site/public/brand/perl/workspace/mstile-310-light.png create mode 100644 site/public/brand/perl/workspace/opengraph-dark.jpg create mode 100644 site/public/brand/perl/workspace/opengraph-dark.png create mode 100644 site/public/brand/perl/workspace/opengraph-light.jpg create mode 100644 site/public/brand/perl/workspace/opengraph-light.png create mode 100644 site/public/brand/perl/workspace/safari-pinned-tab.svg create mode 100644 site/public/brand/perl/workspace/site-dark.webmanifest create mode 100644 site/public/brand/perl/workspace/site.webmanifest create mode 100644 site/public/brand/perl/workspace/social-square-dark.png create mode 100644 site/public/brand/perl/workspace/social-square-light.png create mode 100644 site/public/brand/perl/workspace/twitter-dark.png create mode 100644 site/public/brand/perl/workspace/twitter-light.png create mode 100644 site/src/content/docs/ports/perl/core/index.md create mode 100644 site/src/content/docs/ports/perl/workspace/index.md create mode 100644 site/src/data/api/perl.json create mode 100644 site/src/data/api/perl.nav.json create mode 100644 site/src/data/api/perl.paths.json create mode 100644 site/src/data/port-guides/perl.json create mode 100644 site/src/data/tmux-usage/perl.json create mode 100644 site/src/lib/code-language.ts create mode 100644 site/test/api-destination-evidence.publication.test.ts create mode 100644 site/test/elixir-layout-rendering.outer.test.ts create mode 100644 site/test/lua-layout-rendering.outer.test.ts create mode 100644 site/test/mcp-session.outer.test.ts create mode 100644 site/test/mcp-transcript-corpus.outer.test.ts create mode 100644 site/test/native-shell-context.outer.test.ts create mode 100644 site/test/page-transitions.outer.test.ts create mode 100644 site/test/perl-pod-links.test.ts create mode 100644 site/test/perl-source-usage.test.ts create mode 100644 site/test/ruby-layout-rendering.outer.test.ts create mode 100644 site/test/source-only-inventory.test.ts diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a5c2eb50e..73fe20485 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -104,7 +104,9 @@ $ pnpm test The outer loop includes the `*.outer.test.ts` integration suites, which seed the full API catalog, run native compiler comparisons, or exercise subprocess shutdown. Elixir exporter fixtures and live clang-format comparisons run here; -the medium loop keeps the pinned formatter fixtures. It also adds type +the medium loop keeps the pinned formatter fixtures. Adversarial example, +workspace-showcase, and product-copy CLI checks also run in outer because +they spawn subprocesses and temporary Git repositories. It also adds type checks and starts its own Astro development server from current source. Browser checks cover prose, an MCP table, row permalinks, API equivalents, and phone dropdown placement at 1440, 768, and 390 pixels. The @@ -115,14 +117,25 @@ medium, and outer respectively; measure the complete pnpm command when changing a loop. `test:fast` aliases medium. The runner stops an over-budget loop and fails. -The medium and outer loops first stage the integrated Ruby and Lua guides -from local Git objects. Each revision comes from `site/src/data/api/.json`; -the checkout's current branch and uncommitted files do not affect these guides. -Keep those repositories at their standard `checkout` paths in `ports.ts`, or -set `LIBTMUX_DOCS_CHECKOUT_RUBY` and `LIBTMUX_DOCS_CHECKOUT_LUA` to local clones -containing the required commits. Missing repositories or commits fail with -the required revision and environment variable. The gate does not fetch; -a fresh docs clone needs these source checkouts before `pnpm test`. +`scripts/test-tiers.json` assigns existing compiler/rendering, subprocess/Git, +and full-catalog integration suites to outer, with a reason for each group. +Publication retains exhaustive link rendering and destination/literal catalog audits. +Medium and outer exclude publication suites; the unfiltered package tests in +`test:publication` run every suite, including both manifest tiers and suffix +tiers. Native shell tree/search fixtures stay in inner; owned Git collection +fixtures run in outer. No tier changes a test's assertions. + +The medium and outer loops stage every port in `SOURCE_GUIDE_PORTS` in +[`port-documentation.ts`](../site/src/lib/port-documentation.ts), including Perl. +Native guides come from local Git objects at each integrated +`site/src/data/api/.json` revision; the checkout's current branch and +uncommitted files do not affect them. Wrapper guides use the committed guide cache. +Keep native repositories at their `checkout` paths in +[`ports.ts`](../site/src/lib/ports.ts), or set `LIBTMUX_DOCS_CHECKOUT_` +to a clone containing the required commit, such as `LIBTMUX_DOCS_CHECKOUT_PERL`. +Missing repositories or commits report the exact revision and override. +The gate never fetches. Provision every catalogued native checkout before +running these loops in a fresh docs clone; unchanged staged guides retain their timestamps. Browser checks use Playwright's installed Chromium by default. To use local Chrome: diff --git a/.github/workflows/port-docs.yml b/.github/workflows/port-docs.yml index 88b9edabc..a3f7c5a19 100644 --- a/.github/workflows/port-docs.yml +++ b/.github/workflows/port-docs.yml @@ -100,7 +100,7 @@ jobs: echo "::error::GitHub Cloud job.workflow_repository/job.workflow_sha are required" >&2 exit 1 } - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ job.workflow_repository }} ref: ${{ job.workflow_sha }} @@ -108,7 +108,7 @@ jobs: scripts site/src/lib persist-credentials: false - - uses: actions/setup-node@v7 + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7 with: node-version: '26' - id: identity @@ -160,7 +160,7 @@ jobs: echo "::error::GitHub Cloud job.workflow_repository/job.workflow_sha are required" >&2 exit 1 } - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.identity.outputs.source-ref }} fetch-depth: 0 @@ -183,7 +183,7 @@ jobs: } echo "sha=$sha" >> "$GITHUB_OUTPUT" - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ job.workflow_repository }} ref: ${{ job.workflow_sha }} @@ -194,7 +194,7 @@ jobs: # Record both checkouts before either native exporter produces files. - name: Check out native documentation tooling if: matrix.port == 'powershell' || matrix.port == 'julia' - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.sha }} path: docs-generator @@ -234,14 +234,14 @@ jobs: echo "$product=$ref" >> "$GITHUB_OUTPUT" done - if: inputs.port == 'py' - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: tmux-python/tmuxp ref: ${{ steps.python-products.outputs.workspace }} path: python-workspace persist-credentials: false - if: inputs.port == 'py' - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: tmux-python/libtmux-mcp ref: ${{ steps.python-products.outputs.mcp }} @@ -251,10 +251,10 @@ jobs: # No dependency cache: this job checks out whichever ref it was asked # to publish, and a cache it saved could be restored by a later # default-branch run. - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@73e46992e05b19abd31f2f3c20e0e7370d762115 # v6 with: package_json_file: docs/package.json - - uses: actions/setup-node@v7 + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7 with: node-version: '26' - run: pnpm install --frozen-lockfile @@ -497,6 +497,38 @@ jobs: mix deps.get --only prod mix run --no-start "$EXPORTER" _build/docs/api.json + - name: Read the selected Perl documentation runtime + if: matrix.port == 'perl' + id: perl-runtime + working-directory: port + run: | + python3 - <<'PYCODE' + import os, pathlib, re + rows = [line.split() for line in pathlib.Path('.tool-versions').read_text().splitlines()] + versions = [row[1] for row in rows if len(row) == 2 and row[0] == 'perl'] + if len(versions) != 1 or not re.fullmatch(r'[0-9]+\.[0-9]+\.[0-9]+', versions[0]): + raise ValueError('Perl documentation requires an exact native runtime pin') + with open(os.environ['GITHUB_OUTPUT'], 'a') as output: + output.write(f'version={versions[0]}\n') + PYCODE + - name: Install the selected Perl and documentation dependencies + if: matrix.port == 'perl' + uses: shogo82148/actions-setup-perl@eebc5c886de14ebbfcd2493d49a12007d2c30477 # v1.44.5 + with: + perl-version: ${{ steps.perl-runtime.outputs.version }} + working-directory: port + install-modules-with: cpm + install-modules-args: --top-level-phase configure,runtime,develop + enable-modules-cache: false + - name: Export the selected Perl declarations and native POD + if: matrix.port == 'perl' + working-directory: port + env: + SOURCE_SHA: ${{ steps.source.outputs.sha }} + run: | + perl scripts/export-api.pl --revision "$SOURCE_SHA" \ + --exporter-revision "$SOURCE_SHA" --output docs/_build/api.json + - if: matrix.port == 'ruby' uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0 with: @@ -510,7 +542,7 @@ jobs: run: bundle install - if: inputs.port == 'py' - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: false python-version: '3.14' diff --git a/.github/workflows/reusable-deploy.yml b/.github/workflows/reusable-deploy.yml index 2c32efe52..68e754e3c 100644 --- a/.github/workflows/reusable-deploy.yml +++ b/.github/workflows/reusable-deploy.yml @@ -144,7 +144,7 @@ jobs: echo "::error::path-prefix '$p' must be an unrooted path using letters, digits, '.', '_', '-' and '/', without '..'" >&2 exit 1 fi - reserved=(py ruby lua powershell julia elixir ts rs go java kotlin scala csharp fsharp cxx swift manifest _shell) + reserved=(py ruby lua powershell julia elixir ts rs go java kotlin scala csharp fsharp cxx swift perl manifest _shell) for r in "${reserved[@]}"; do if [[ "$p" == "$r" ]]; then echo "::error::path-prefix '$p' is a bare reserved top-level name — qualify it, e.g. '$r/latest'" >&2 @@ -153,7 +153,7 @@ jobs: done if [[ -n "${PORT_IN:-}" ]]; then case "$PORT_IN" in - py|ruby|lua|powershell|julia|elixir|ts|rs|go|java|kotlin|scala|csharp|fsharp|cxx|swift) ;; + py|ruby|lua|powershell|julia|elixir|perl|ts|rs|go|java|kotlin|scala|csharp|fsharp|cxx|swift) ;; *) echo "::error::unknown port '$PORT_IN'" >&2; exit 1 ;; esac if [[ ! "$VERSION_IN" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ || "$VERSION_IN" == *..* ]]; then diff --git a/notes/adding-a-port.md b/notes/adding-a-port.md index 62720f9a9..621443001 100644 --- a/notes/adding-a-port.md +++ b/notes/adding-a-port.md @@ -54,7 +54,9 @@ products. Leave out private workspaces and development tools. Name a package page or API reference only where the host really serves one. A port installed from Git, or from its own registry, names no host page. Set an entry `planned` or `configured-unpublished` until its host serves it: only -`published` entries produce links. List a page an ecosystem suggests and its +`published` entries produce registry/API links. Set `sourceAvailable: true` +only for a verified public source directory or file; that source can be linked +while the distribution remains `configured-unpublished`. List a page an ecosystem suggests and its host does not serve as `unavailable`. Give a package that ships inside another distribution (a Go package, a @@ -85,7 +87,7 @@ $ node scripts/verify-destinations.mjs ``` The verifier refuses to run, with or without `--check`, if a port in `ports.ts` -has no inventory entry with a published library: the header builds its links +has no library with a published distribution or explicitly available source: the header builds its links from that entry, so a port without one would offer nothing. A host the inventory has not named before needs an identity rule in `scripts/lib/destination-verification.mjs` and its cases in diff --git a/packages/api-model/package.json b/packages/api-model/package.json index 3f2d1c352..1573bed11 100644 --- a/packages/api-model/package.json +++ b/packages/api-model/package.json @@ -5,7 +5,11 @@ "type": "module", "description": "A shared API model for language ports, extracted from native documentation artifacts and source.", "exports": { - ".": "./src/index.ts" + ".": "./src/index.ts", + "./products": "./src/products.ts", + "./modules": "./src/modules.ts", + "./link": "./src/link.ts", + "./reference": "./src/reference.ts" }, "scripts": { "test": "vitest run", diff --git a/packages/api-model/src/concepts.ts b/packages/api-model/src/concepts.ts index f5b23c9ac..75d471406 100644 --- a/packages/api-model/src/concepts.ts +++ b/packages/api-model/src/concepts.ts @@ -3823,6 +3823,121 @@ for (const [id, binding] of Object.entries(ELIXIR_CONCEPTS)) { concept.symbols.elixir = binding.symbol if (binding.note) (concept.notes ??= {}).elixir = binding.note } +// Captured Perl entities resolve locally; Server owns every explicit operation. +const PERL_CONCEPTS: Record = { + server: { symbol: 'LibTmux::Server', note: 'Construction records connection settings without tmux I/O. Optional LibTmux::Async::Server returns standard Future results for operations.' }, + session: { symbol: 'LibTmux::Session', note: 'A captured read-only entity; explicit Server operations accept its stable identity.' }, + window: { symbol: 'LibTmux::Window', note: 'Physical window identity. WindowLink owns each session/index placement.' }, + pane: { symbol: 'LibTmux::Pane', note: 'A physical pane retains its captured graph, without retaining transport.' }, + 'workspace-description': { symbol: 'LibTmux::Workspace::new', note: 'Validates and copies a libtmux.workspace/v1 JSON-compatible configuration.' }, + 'build-workspace': { symbol: 'LibTmux::Workspace::load', note: 'Loads through installed public core APIs; existing-target policy and known owned rollback effects are explicit.' }, + snapshot: { symbol: 'LibTmux::Server::snapshot', note: 'Strict acquisition observes an interval, not an atomic transaction; retained handles do not refresh.' }, + 'server-cmd': { symbol: 'LibTmux::Server::cmd', note: 'Checked literal argument vector; no shell wrapper or implicit tmux command list.' }, + 'list-sessions': { symbol: 'LibTmux::Snapshot::sessions', note: 'Reads captured membership locally, preserving order.' }, + 'list-server-windows': { symbol: 'LibTmux::Snapshot::windows', note: 'One entry per physical identity. window_links retains all session placements.' }, + 'list-server-panes': { symbol: 'LibTmux::Snapshot::panes', note: 'One entry per captured physical pane; raw listings preserve contextual rows separately.' }, + 'list-clients': { symbol: 'LibTmux::Snapshot::clients', note: 'Local captured client membership; Server::clients explicitly acquires a new graph.' }, + 'list-panes': { symbol: 'LibTmux::Window::panes', note: 'Reads this physical window’s captured panes without I/O.' }, + 'pane-window': { symbol: 'LibTmux::Pane::window', note: 'Resolves the physical window from the retained graph, without selecting a session context.' }, + 'window-session': { symbol: 'LibTmux::WindowLink::session', note: 'The session belongs to an explicit WindowLink placement; a physical Window has no arbitrary single session.' }, + 'window-link-window': { symbol: 'LibTmux::WindowLink::window' }, + 'client-session': { symbol: 'LibTmux::Client::session', note: 'Captured nullable relation; unloaded data remains an error.' }, + 'active-pane': { symbol: 'LibTmux::Window::active_pane', note: 'Local captured relation. Unknown membership cannot prove that no pane is active.' }, + 'get-session': { symbol: 'LibTmux::Snapshot::session_by_id', note: 'Captured stable-ID lookup returns an entity or undef. Use Selection::one for strict criteria/name lookup.' }, + 'get-window': { symbol: 'LibTmux::Snapshot::window_by_id', note: 'Resolves physical identity without choosing an arbitrary session placement.' }, + 'get-pane': { symbol: 'LibTmux::Snapshot::pane_by_id' }, + 'search-server-panes': { symbol: 'LibTmux::Server::query_panes', note: 'Explicit acquisition supports validated criteria or an exclusive native_filter expression. Local Selection::where performs no I/O.' }, +} +for (const [concept, method] of Object.entries({ + 'capture-pane': 'capture_pane', 'send-keys': 'send_keys', 'split-pane': 'split_pane', + 'set-pane-title': 'set_title', 'select-layout': 'select_layout', 'unlink-window': 'unlink_window', + 'new-session': 'new_session', 'new-window': 'new_window', 'kill-server': 'kill_server', + 'kill-session': 'kill_session', 'kill-window': 'kill_window', 'kill-pane': 'kill_pane', + 'rename-session': 'rename_session', 'rename-window': 'rename_window', 'select-window': 'select_window', + 'select-pane': 'select_pane', 'resize-pane': 'resize_pane', 'link-window': 'link_window', + 'move-window': 'move_window', 'detach-client': 'detach_client', 'show-buffer': 'show_buffer', + 'set-buffer': 'set_buffer', 'delete-buffer': 'delete_buffer', +})) { + PERL_CONCEPTS[concept] = { symbol: `LibTmux::Server::${method}`, + note: ['select-window', 'move-window', 'unlink-window'].includes(concept) + ? 'Requires an explicit WindowLink or session_id:index context; a physical window alone does not select a session placement.' + : 'Explicit Server operation. Captured entities remain local observations; use a new snapshot to observe changes.' } +} +for (const [concept, owner, field] of [ + ['session-id', 'Session', 'id'], ['window-id', 'Window', 'id'], ['pane-id', 'Pane', 'id'], + ['session-name', 'Session', 'name'], ['window-name', 'Window', 'name'], + ['window-index', 'WindowLink', 'index'], ['window-active', 'WindowLink', 'active'], + ['pane-index', 'Pane', 'index'], ['window-height', 'Window', 'height'], ['window-width', 'Window', 'width'], + ['pane-height', 'Pane', 'height'], ['pane-width', 'Pane', 'width'], ['pane-title', 'Pane', 'title'], + ['pane-active', 'Pane', 'active'], ['session-attached', 'Session', 'attached'], ['session-created', 'Session', 'created'], + ['session-path', 'Session', 'path'], ['window-layout', 'Window', 'layout'], + ['pane-current-command', 'Pane', 'current_command'], ['pane-current-path', 'Pane', 'current_path'], + ['pane-pid', 'Pane', 'pid'], ['pane-dead', 'Pane', 'dead'], +]) { + PERL_CONCEPTS[concept] = { symbol: `LibTmux::${owner}::${field}`, note: owner === 'WindowLink' + ? 'Captured session-relative placement data; this is not a property of the physical window.' + : concept === 'session-attached' ? 'Returns the captured attached-client count; zero means no attached client.' + : 'Schema-validated captured data; reading performs no tmux I/O.' } +} +for (const scope of ['server', 'session', 'window', 'pane']) { + for (const [verb, method] of [['', 'get_option'], ['set-', 'set_option'], ['unset-', 'unset_option']]) { + PERL_CONCEPTS[`${verb}${scope}-option`] = { symbol: `LibTmux::Server::${method}`, + note: `Pass scope => '${scope}' and the explicit target ID where applicable; inherited and global reads are deliberate options.` } + } +} +PERL_CONCEPTS['set-global-option'] = { symbol: 'LibTmux::Server::set_option', note: "Pass scope => 'session', global => true to set a session default." } +for (const scope of ['server', 'session']) { + const selection = scope === 'server' ? 'global => true' : 'an explicit session target ID' + PERL_CONCEPTS[`${scope}-hooks`] = { symbol: 'LibTmux::Server::show_hooks', note: `Use ${selection}; raw bytes preserve sparse hook indexes and tmux quoting.` } + PERL_CONCEPTS[`set-${scope}-hook`] = { symbol: 'LibTmux::Server::set_hook', note: `Use ${selection}; command is an explicit native tmux command string.` } + for (const [concept, method] of [[`set-${scope}-environment`, 'set_environment'], [`unset-${scope}-environment`, 'unset_environment'], [`${scope}-get-environment`, 'get_environment']]) { + PERL_CONCEPTS[concept] = { symbol: `LibTmux::Server::${method}`, note: scope === 'server' + ? 'Omit session for the global environment. Missing or explicitly unset values remain failures.' + : 'Pass an explicit session ID. Empty text and zero-like text remain values.' } + } +} +for (const [id, binding] of Object.entries(PERL_CONCEPTS)) { + const concept = CONCEPTS[id] + if (!concept) throw new Error(`concepts: Perl maps unknown concept ${id}`) + concept.symbols.perl = binding.symbol + if (binding.note) (concept.notes ??= {}).perl = binding.note + if (binding.symbol.startsWith('LibTmux::Server::') && !binding.symbol.endsWith('::attach_argv')) { + (concept.variants ??= {}).perl = [binding.symbol.replace('LibTmux::Server::', 'LibTmux::Async::Server::')] + } +} +const PERL_ABSENT: Record = { + 'attach-session': 'attach_argv builds caller-owned terminal arguments without performing attachment; the caller owns process and TTY lifetime.', + 'chain-commands': 'batch executes ordered independent requests, not a tmux command list in one invocation; command chaining is deferred.', + 'freeze-workspace': 'The JSON workspace distribution validates, plans and loads configurations; live-session export is outside the selected scope.', + 'list-windows': 'Traverse Session::window_links and resolve each link’s window, preserving explicit session placement and multiplicity.', + 'list-session-panes': 'Traverse the session’s window links and physical windows; choose explicitly whether repeated linked panes should repeat.', + 'active-window': 'Select the active captured WindowLink, then resolve its physical window.', + 'linked-sessions': 'Window::links returns WindowLink records; resolve each link’s session explicitly.', + 'pane-session': 'A physical pane’s window can be linked into several sessions; choose an explicit WindowLink context.', + 'pane-window-id': 'Use pane->window->id; the public pane relationship returns the physical Window rather than a separate ID reader.', + 'pane-session-id': 'Physical panes have no arbitrary session context; obtain the session ID through an explicit WindowLink.', + 'window-session-id': 'Use link->session->id; physical Window identity is separate from session placement.', + 'session-window-count': 'Count Session::window_links membership; repeated links remain distinct occurrences.', + 'window-pane-count': 'Count the Window::panes selection or use native Perl array length.', + 'server-alive': 'Explicit snapshot acquisition returns observed data or a typed failure; operational failures are not converted to false.', + 'raise-if-dead': 'Explicit acquisition already propagates typed operational failures.', + 'server-version': 'Read the acquired snapshot metadata version; the core has no standalone live version getter.', + 'config-file': 'config_file is a constructor setting; there is no public configuration-file accessor.', + 'socket-path': 'socket_path is a constructor selector; acquired snapshots record observed server scope separately.', + 'socket-name': 'socket_name is a constructor selector; no inferred name is added to captured handles.', + 'session-server': 'Captured handles retain a graph store, not a live Server or transport.', + 'window-server': 'Captured handles retain a graph store, not a live Server or transport.', + 'pane-server': 'Captured handles retain a graph store, not a live Server or transport.', + 'client-server': 'Captured handles retain a graph store, not a live Server or transport.', + 'refresh-session': 'Acquire a new snapshot; retained captured entities never refresh in place.', + 'refresh-window': 'Acquire a new snapshot; retained captured entities never refresh in place.', + 'refresh-pane': 'Acquire a new snapshot; retained captured entities never refresh in place.', +} +for (const [id, concept] of Object.entries(CONCEPTS)) { + if (!concept.symbols.perl) (concept.absent ??= {}).perl = PERL_ABSENT[id] + ?? 'No dedicated equivalent in the selected Perl surface. Explicit Server::cmd remains available for native tmux commands.' +} + CONCEPTS['list-session-panes']!.absent!.julia = 'Traverse `windows(session)` and `panes(window)` in the captured snapshot. `panes(snapshot)` has server-wide scope.' for (const concept of Object.values(CONCEPTS)) { concept.absent ??= {} diff --git a/packages/api-model/src/doc/roles.ts b/packages/api-model/src/doc/roles.ts index 791867b29..d2eccf217 100644 --- a/packages/api-model/src/doc/roles.ts +++ b/packages/api-model/src/doc/roles.ts @@ -278,6 +278,8 @@ function labelFor(raw: string): { target: string; label: string } { */ const SYNTAX: Record> = { py: new Set(['rest', 'citation']), + // Pod::Simple exports local POD targets as roles and external targets as Markdown links. + perl: new Set(['pod', 'markdown-link']), rs: new Set(['intra-doc']), go: new Set(['go-link']), java: new Set(['jsdoc']), @@ -514,7 +516,7 @@ function tokenizeRun(text: string, lang?: string): DocSpan[] { } } - if (syntax.has('rest')) for (const m of text.matchAll(ROLE_RE)) { + if (syntax.has('rest') || syntax.has('pod')) for (const m of text.matchAll(ROLE_RE)) { const role = m[1].replace(/^py:/, '') const { target, label } = labelFor(m[2]) if (!ROLES.has(m[1])) { @@ -599,7 +601,7 @@ function tokenizeRun(text: string, lang?: string): DocSpan[] { } } else { for (const code of markdownCode(text, masked.join(''))) { - const span: DocSpan = code.ticks === 1 + const span: DocSpan = syntax.has('pod') ? { kind: 'code', text: code.text } : code.ticks === 1 ? { kind: 'ref', role: 'any', target: syntax.has('intra-doc') && RUST_CODE_PATH_RE.test(code.text) ? rustTarget(code.text) : code.text, label: code.text } : syntax.has('docc') && code.ticks === 2 ? { kind: 'ref', role: 'any', target: doccTarget(code.text), label: code.text } diff --git a/packages/api-model/src/index.ts b/packages/api-model/src/index.ts index f85d23d4f..246427e8d 100644 --- a/packages/api-model/src/index.ts +++ b/packages/api-model/src/index.ts @@ -1,3 +1,4 @@ +export { extractPerlArtifact } from './languages/perl.ts' export * from './model.ts' export { sourceUrl, symbolsForProduct } from './products.ts' export { loadLanguage, parserFor, type GrammarName } from './parser.ts' diff --git a/packages/api-model/src/inventory.ts b/packages/api-model/src/inventory.ts index 7c6867981..d2593d4e2 100644 --- a/packages/api-model/src/inventory.ts +++ b/packages/api-model/src/inventory.ts @@ -32,6 +32,7 @@ export function symbolEntries(entries: T[]): T[] { /** Sphinx v2 uses object types in records; roles resolve those types. */ const DOMAIN: Record = { + perl: 'std', py: 'py', ruby: 'std', lua: 'std', diff --git a/packages/api-model/src/languages/perl.ts b/packages/api-model/src/languages/perl.ts new file mode 100644 index 000000000..f7961d5f5 --- /dev/null +++ b/packages/api-model/src/languages/perl.ts @@ -0,0 +1,77 @@ +import type { ApiModel, ApiSymbol, DocBlock } from '../model.ts' + +interface PerlArtifact extends ApiModel { + schema: string + examples?: { owner: string; path: string; code: string }[] +} + +const PACKAGES = new Set(['LibTmux', 'LibTmux-Async', 'LibTmux-Workspace']) +const SHA = /^[a-f0-9]{40}$/ +const publicId = /^LibTmux(?:::[A-Za-z][A-Za-z0-9_]*)*$/ + +/** Adapt PPI signatures and Pod::Simple links; never parse Perl as TypeScript. */ +export function extractPerlArtifact(input: unknown, revision?: string): ApiModel { + const artifact = input as PerlArtifact + if (artifact?.schema !== 'libtmux.perl-api/v1' || artifact.port !== 'perl' || + !SHA.test(artifact.revision ?? '') || revision !== undefined && revision !== artifact.revision) { + throw new Error('Perl native artifact schema or library revision mismatch') + } + const exporter = artifact.nativeProvenance?.exporter + if (!exporter || (typeof exporter.revision !== 'string' || !SHA.test(exporter.revision)) || exporter.working_tree !== false || + !artifact.nativeProvenance?.files.length || !Array.isArray(artifact.symbols) || !artifact.symbols.length) { + throw new Error('Perl artifact requires committed exporter and public input provenance') + } + const ids = new Set(artifact.symbols.map((symbol) => symbol.id)) + if (ids.size !== artifact.symbols.length) throw new Error('Duplicate Perl public identity') + const files = new Set(artifact.nativeProvenance.files.map((file) => file.path)) + for (const file of artifact.nativeProvenance.files) { + if (!/^[a-f0-9]{64}$/.test(file.sha256) || file.path.startsWith('/') || file.path.split('/').includes('..')) { + throw new Error('Invalid Perl native input provenance') + } + } + for (const symbol of artifact.symbols) { + if (!publicId.test(symbol.id) || symbol.name.startsWith('_') || symbol.name === 'DESTROY' || + /^LibTmux::(?:Codec|Platform)(?:::|$)/.test(symbol.id) || symbol.apiScope !== 'exported' || + !PACKAGES.has(symbol.package ?? '') || !['core', 'workspace'].includes(symbol.product ?? '') || + symbol.parent && !ids.has(symbol.parent) || symbol.publicId !== symbol.id) { + throw new Error(`Invalid Perl public declaration: ${symbol.id}`) + } + if (!/^packages\/(?:core|async|workspace)\/lib\/LibTmux(?:\/[^/]+)*\.pm$/.test(symbol.source.file) || + !files.has(symbol.source.file) || !Number.isInteger(symbol.source.line) || (symbol.source.line ?? 0) < 1 || + symbol.source.revision !== artifact.revision || !Array.isArray(symbol.signatures) || + symbol.signatures.some((signature) => !signature.raw || !Array.isArray(signature.params))) { + throw new Error(`Invalid Perl native signature or source identity: ${symbol.id}`) + } + } + const resolvePod = (text: string): string => text.replace(/\[([^\]]+)\]\(pod:([^\s)]+)\)/g, (_all, label: string, target: string) => { + const [module, section] = target.split('/', 2) + if (!module.startsWith('LibTmux')) { + const href = module === 'JSON::PP' ? 'https://perldoc.perl.org/5.44.0/JSON::PP' + : `https://metacpan.org/pod/${module}` + return `[${label}](${href}${section ? `#${encodeURIComponent(section)}` : ''})` + } + const id = module === 'LibTmux::Transport' && section === 'RESULTS' ? 'LibTmux::CommandResult' + : section ? `${module}::${section}` : module + if (!ids.has(id)) throw new Error(`Unresolved authored Perl POD target: ${target}`) + return `:obj:\`${label.replace(/`/g, '')} <${id}>\`` + }) + const doc = (value?: DocBlock): DocBlock | undefined => value ? { + ...value, summary: resolvePod(value.summary), ...(value.body ? { body: resolvePod(value.body) } : {}), + ...(value.examples ? { examples: value.examples.map((example) => ({ ...example, ...(example.intro ? { intro: resolvePod(example.intro) } : {}) })) } : {}), + } : undefined + const symbols: ApiSymbol[] = artifact.symbols.map((symbol) => ({ + ...symbol, signatures: symbol.signatures.map((signature) => ({ ...signature, params: signature.params.map((param) => ({ ...param })) })), doc: doc(symbol.doc), + })) + for (const example of artifact.examples ?? []) { + const owner = symbols.find((symbol) => symbol.id === example.owner) + if (!owner || !/^examples\/[a-z-]+\.pl$/.test(example.path) || !files.has(example.path) || !example.code) { + throw new Error('Invalid complete Perl example provenance') + } + owner.doc ??= { summary: '' } + owner.doc.examples = [...owner.doc.examples ?? [], { lang: 'perl', code: example.code, + intro: 'Complete installed-package program with an owned tmux fixture and result/cleanup assertions.', + sourceUrl: `https://github.com/libtmux/libtmux-perl/blob/${artifact.revision}/${example.path}` }] + } + return { port: 'perl', repo: artifact.repo, revision: artifact.revision, sources: artifact.sources, + extractor: artifact.extractor, nativeProvenance: artifact.nativeProvenance, symbols } +} diff --git a/packages/api-model/src/mentions.ts b/packages/api-model/src/mentions.ts index f93be1085..850801d65 100644 --- a/packages/api-model/src/mentions.ts +++ b/packages/api-model/src/mentions.ts @@ -94,6 +94,7 @@ const FENCE_PORT: Record = { cpp: 'cxx', 'c++': 'cxx', swift: 'swift', powershell: 'powershell', pwsh: 'powershell', ps1: 'powershell', julia: 'julia', elixir: 'elixir', ex: 'elixir', exs: 'elixir', + perl: 'perl', pl: 'perl', pm: 'perl', } /** A symbol that a link on a page names. */ diff --git a/packages/api-model/src/model.ts b/packages/api-model/src/model.ts index 7ebbdd9c4..293183382 100644 --- a/packages/api-model/src/model.ts +++ b/packages/api-model/src/model.ts @@ -14,7 +14,7 @@ */ /** Language libraries, by the slug the site uses. */ -export type PortSlug = 'py' | 'ruby' | 'lua' | 'ts' | 'rs' | 'go' | 'java' | 'csharp' | 'cxx' | 'swift' | 'kotlin' | 'scala' | 'fsharp' | 'powershell' | 'julia' | 'elixir' +export type PortSlug = 'perl' | 'py' | 'ruby' | 'lua' | 'ts' | 'rs' | 'go' | 'java' | 'csharp' | 'cxx' | 'swift' | 'kotlin' | 'scala' | 'fsharp' | 'powershell' | 'julia' | 'elixir' export type ApiProduct = 'core' | 'workspace' | 'mcp' @@ -169,6 +169,8 @@ export interface Signature { extension?: string /** Native signature text when its grammar carries more than the shared fields. */ raw?: string + /** Native producer offsets into raw declaration text; no renderer reparsing. */ + nativeSyntax?: ({ start: number; end: number; kind: 'name' } | { start: number; end: number; kind: 'parameter'; parameter: number })[] /** Native impl or trait header that owns this callable, without its body. */ enclosingDeclaration?: string /** Lexical bindings from that impl or trait, separate from callable generics. */ diff --git a/packages/api-model/src/nav-config.ts b/packages/api-model/src/nav-config.ts index 5ed414cd3..fd60f8b32 100644 --- a/packages/api-model/src/nav-config.ts +++ b/packages/api-model/src/nav-config.ts @@ -597,6 +597,12 @@ const OVERRIDES: Record }> = { 'libtmux.Watch': 'watch handle shared by several tmux objects', }, }, + perl: { + unsettled: { + LibTmux: 'distribution namespace and version; concrete packages have their own placements', + 'LibTmux::Entity': 'shared captured-handle base; concrete entity packages own the tmux objects', + }, + }, ruby: { unsettled: { 'LibTmux::Entity': 'base of the tmux entity hierarchy; the concrete entity is the subclass', @@ -744,6 +750,13 @@ const OVERRIDES: Record }> = { /** Place language-specific public helpers with the task they support. */ const LANGUAGE_PLACEMENTS: Record> = { + perl: { + queries: ['Schema', 'Selection', 'Selection::Iterator', 'PaneSelection', 'WindowSelection', + 'WindowLinkSelection', 'SessionSelection', 'ClientSelection'].map((name) => `LibTmux::${name}`), + commands: ['LibTmux::Operation'], + async: ['LibTmux::Async::Server', 'LibTmux::Async::Transport'], + errors: ['LibTmux::X', 'LibTmux::Async::X', 'LibTmux::Workspace::X'], + }, powershell: { commands: ['LibTmux\\Invoke-TmuxChain'], pane: ['LibTmux\\Send-TmuxText'], @@ -854,7 +867,7 @@ function languageBucket(bucket: Bucket, port: string, root = bucket.id): Bucket } export const NAV: Record = Object.fromEntries( - ['powershell', 'julia', 'elixir', 'py', 'ruby', 'lua', 'ts', 'rs', 'go', 'java', 'kotlin', 'scala', 'fsharp', 'csharp', 'cxx', 'swift'].map((port) => [ + ['perl', 'powershell', 'julia', 'elixir', 'py', 'ruby', 'lua', 'ts', 'rs', 'go', 'java', 'kotlin', 'scala', 'fsharp', 'csharp', 'cxx', 'swift'].map((port) => [ port, { port, diff --git a/packages/api-model/src/prose-fields.ts b/packages/api-model/src/prose-fields.ts index 988a36a2e..6239250fa 100644 --- a/packages/api-model/src/prose-fields.ts +++ b/packages/api-model/src/prose-fields.ts @@ -55,6 +55,7 @@ export const STRUCTURAL_FIELDS: string[] = [ '.typeParameters[].bound', '.typeParameters[].default', '.typeParameters[].kind', '.typeParameters[].modifier', '.typeParameters[].name', '.signatures[].enclosingDeclaration', '.signatures[].enclosingTypeParamNames[]', '.signatures[].extension', '.signatures[].identity', '.signatures[].label', '.signatures[].methodKind', '.signatures[].raw', '.signatures[].returns', + '.signatures[].nativeSyntax[].kind', '.signatures[].source.*', '.signatures[].typeParamNames[]', '.signatures[].typeParams[]', '.signatures[].typeParameters[].bound', '.signatures[].typeParameters[].default', '.signatures[].typeParameters[].kind', '.signatures[].typeParameters[].modifier', '.signatures[].typeParameters[].name', diff --git a/packages/api-model/src/prose.ts b/packages/api-model/src/prose.ts index f7486aab9..5d77f054a 100644 --- a/packages/api-model/src/prose.ts +++ b/packages/api-model/src/prose.ts @@ -17,6 +17,7 @@ import { neverLinks } from './never-links.ts' export const PORT_NAME: Record = { py: 'Python', + perl: 'Perl', ts: 'TypeScript', rs: 'Rust', go: 'Go', diff --git a/packages/api-model/src/reference.ts b/packages/api-model/src/reference.ts new file mode 100644 index 000000000..f6787818d --- /dev/null +++ b/packages/api-model/src/reference.ts @@ -0,0 +1,24 @@ +/** Model, linking and navigation for readers; native extraction stays in the author entry. */ +export * from './model.ts' +export { sourceUrl, symbolsForProduct } from './products.ts' +export { SymbolIndex, keywordArgument, parameterId, typeParameterId, type LinkTarget, type KeywordHelp, type TypeParameterBinding } from './link.ts' +export { boundLabel, parseTypeParameter, parseTypeParameters, typeParameterList, typeParametersOf, withTypeParameterDocs } from './type-params.ts' +export { tokenizeDoc, docSummaryText, referencesIn, type DocSpan } from './doc/roles.ts' +export { writeInventory, writeInventoryEntries, readInventory, inventoryType, isSymbolEntry, symbolEntries, NON_SYMBOL_ROLES, type InventoryEntry } from './inventory.ts' +export { targetKey, targetEntries, compatibilityEntries, type InventoryTarget } from './targets.ts' +export { Resolver, notASymbol, toPath, DEFAULT_TEMPLATES, DEFAULT_PRIMARY_MODULES } from './resolver.ts' +export type { Resolution, UrlTemplate } from './resolver.ts' +export { qualifiedNameOf, moduleOf, modulesIn } from './modules.ts' +export { CONCEPTS, conceptsFor, type Concept } from './concepts.ts' +export { PROSE_FIELDS, RENDERED_TEXTS, STRUCTURAL_FIELDS, commandFacts, conceptNotes, isProseField, isStructuralField, parameterBindingFacts, parameterBindingText, proseTexts, stringFields, unclassifiedFields, type ProseForm, type ProseText } from './prose-fields.ts' +export { neverLinks } from './never-links.ts' +export { looksLikeApiMention, tableMentions, proseMentions, pageMentions, LinkedOwners, type TableMention, type ProseMention, type LinkedOwner, type DanglingMention, type PageMentionsInput } from './mentions.ts' +export { parseHunks, mapLine, type Hunk } from './source-lines.ts' +export * from './prose.ts' +export { BUILTINS, builtinHref } from './builtins.ts' +export { cargoFeatureHref } from './cargo-features.ts' +export * from './nav.ts' +export { NAV } from './nav-config.ts' +export { MEMBER_TIERS, memberSignals, memberTier, compareMembers, membersOf, pageMembersOf, aliasTarget, aliasMembersTarget, type MemberSignals, type MemberTier } from './member-order.ts' +export { parentInventory } from './parent-inventory.ts' +export { navSidecarFor, type NavConfig } from './nav-sidecar.ts' diff --git a/packages/api-model/src/resolver.ts b/packages/api-model/src/resolver.ts index 676e2b52d..aae2eb4a0 100644 --- a/packages/api-model/src/resolver.ts +++ b/packages/api-model/src/resolver.ts @@ -76,6 +76,7 @@ export const DEFAULT_PRIMARY_MODULES: Record = { powershell: 'LibTmux', julia: 'LibTmux', elixir: 'LibTmux', + perl: 'LibTmux', } export const DEFAULT_TEMPLATES: UrlTemplate[] = [ diff --git a/packages/api-model/test/guarantees.test.ts b/packages/api-model/test/guarantees.test.ts index b2f4451a4..76a9d987c 100644 --- a/packages/api-model/test/guarantees.test.ts +++ b/packages/api-model/test/guarantees.test.ts @@ -1,6 +1,4 @@ -import { execFileSync } from 'node:child_process' -import { existsSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' +import { existsSync, readFileSync } from 'node:fs' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' @@ -9,7 +7,6 @@ import { tokenizeDoc, docSummaryText } from '../src/doc/roles.ts' import { SymbolIndex } from '../src/link.ts' import { javadocToMarkdown, parseJavadoc } from '../src/doc/javadoc.ts' import { tableMentions } from '../src/mentions.ts' -import { readInventory, writeInventory } from '../src/inventory.ts' import type { ApiModel } from '../src/model.ts' const here = dirname(fileURLToPath(import.meta.url)) @@ -21,73 +18,6 @@ function load(port: string): ApiModel | undefined { return existsSync(path) ? (JSON.parse(readFileSync(path, 'utf8')) as ApiModel) : undefined } -/** Whether `uv` can run Sphinx here. Absent on a machine without it. */ -function sphinxAvailable(): boolean { - try { - execFileSync('uv', ['--version'], { stdio: 'ignore' }) - return true - } catch { - return false - } -} - -describe('Sphinx itself can read every inventory we write', () => { - /** - * Our reader is not evidence that our writer is right. - * - * `readInventory` and `writeInventory` were written together from the same - * reading of the format, so a shared misunderstanding round-trips perfectly - * and fails only in Sphinx. This loads each file with - * `sphinx.util.inventory.InventoryFile.load` — the code that will actually - * consume these files — and compares what it finds against the model. - * - * The header is as load-bearing as the body: four plaintext lines, the - * fourth naming the compression, then zlib. Sphinx rejects the file outright - * if any of that is wrong, which is a better failure than a silently empty - * inventory. - */ - const canRun = sphinxAvailable() - - it.runIf(canRun).each(PORTS)('%s loads in Sphinx with every entry intact', (port) => { - const model = load(port) - if (!model) return - - const bytes = writeInventory(model, { - project: `libtmux-${port}`, - version: 'test', - uriFor: (s) => `reference/${port}/#${s.publicId ?? s.id}`, - }) - const dir = mkdtempSync(join(tmpdir(), 'libtmux-inv-')) - const file = join(dir, 'objects.inv') - writeFileSync(file, bytes) - - const script = ` -import json, sys -from sphinx.util.inventory import InventoryFile -with open(sys.argv[1], "rb") as fh: - inv = InventoryFile.load(fh, "https://libtmux.org/", lambda base, uri: base + uri) -count = sum(len(entries) for entries in inv.values()) -names = sorted({name for entries in inv.values() for name in entries}) -print(json.dumps({"count": count, "domains": sorted(inv), "sample": names[:3]})) -` - const out = execFileSync( - 'uv', - ['run', '--with', 'sphinx', 'python', '-c', script, file], - { encoding: 'utf8', timeout: 120_000 }, - ) - const result = JSON.parse(out.trim().split('\n').pop() ?? '{}') as { - count: number - domains: string[] - sample: string[] - } - - expect(result.count, `${port}: Sphinx read a different number of entries`).toBe( - model.symbols.length, - ) - expect(result.domains.length, `${port}: no domains`).toBeGreaterThan(0) - }) -}) - describe('names are representable', () => { /** * An inventory record is whitespace-delimited, so a name containing a space diff --git a/packages/api-model/test/inventory-sphinx.outer.test.ts b/packages/api-model/test/inventory-sphinx.outer.test.ts new file mode 100644 index 000000000..81a4aa965 --- /dev/null +++ b/packages/api-model/test/inventory-sphinx.outer.test.ts @@ -0,0 +1,72 @@ +// Outer: compare generated inventories with the installed, lock-pinned Sphinx reader. +import { execFileSync } from 'node:child_process' +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { describe, expect, it } from 'vitest' +import { writeInventory } from '../src/inventory.ts' +import type { ApiModel } from '../src/model.ts' + +const here = dirname(fileURLToPath(import.meta.url)) +const DATA = join(here, '../../../site/src/data/api') +const PORTS = ['py', 'ruby', 'lua', 'ts', 'rs', 'go', 'java', 'csharp', 'cxx', 'swift', 'perl'] as const +const load = (port: string): ApiModel => JSON.parse(readFileSync(join(DATA, `${port}.json`), 'utf8')) + +describe('Sphinx itself can read every inventory we write', () => { + /** + * Our reader is not evidence that our writer is right. + * + * `readInventory` and `writeInventory` were written together from the same + * reading of the format, so a shared misunderstanding round-trips perfectly + * and fails only in Sphinx. This loads each file with + * `sphinx.util.inventory.InventoryFile.load` — the code that will actually + * consume these files — and compares what it finds against the model. + * + * The header is as load-bearing as the body: four plaintext lines, the + * fourth naming the compression, then zlib. Sphinx rejects the file outright + * if any of that is wrong, which is a better failure than a silently empty + * inventory. + */ + it.each(PORTS)('%s loads in Sphinx with every entry intact', (port) => { + const model = load(port) + const bytes = writeInventory(model, { + project: `libtmux-${port}`, + version: 'test', + uriFor: (s) => `reference/${port}/#${s.publicId ?? s.id}`, + }) + const dir = mkdtempSync(join(tmpdir(), 'libtmux-inv-')) + const file = join(dir, 'objects.inv') + writeFileSync(file, bytes) + + const script = ` +import json, sys +from sphinx.util.inventory import InventoryFile +with open(sys.argv[1], "rb") as fh: + inv = InventoryFile.load(fh, "https://libtmux.org/", lambda base, uri: base + uri) +count = sum(len(entries) for entries in inv.values()) +names = sorted({name for entries in inv.values() for name in entries}) +print(json.dumps({"count": count, "domains": sorted(inv), "sample": names[:3]})) +` + let out: string + try { + out = execFileSync( + join(here, '../../../.venv/bin/python'), + ['-c', script, file], + { encoding: 'utf8', timeout: 5_000 }, + ) + } finally { + rmSync(dir, { recursive: true, force: true }) + } + const result = JSON.parse(out.trim().split('\n').pop() ?? '{}') as { + count: number + domains: string[] + sample: string[] + } + + expect(result.count, `${port}: Sphinx read a different number of entries`).toBe( + model.symbols.length, + ) + expect(result.domains.length, `${port}: no domains`).toBeGreaterThan(0) + }) +}) diff --git a/packages/api-model/test/perl.test.ts b/packages/api-model/test/perl.test.ts new file mode 100644 index 000000000..a96bafaa4 --- /dev/null +++ b/packages/api-model/test/perl.test.ts @@ -0,0 +1,50 @@ +import { describe, expect, it } from 'vitest' +import { SymbolIndex } from '../src/link.ts' +import { extractPerlArtifact } from '../src/languages/perl.ts' + +const revision = 'a'.repeat(40) +const source = { file: 'packages/core/lib/LibTmux/Selection.pm', line: 1, revision, repo: 'libtmux/libtmux-perl' } +const artifact = () => ({ + schema: 'libtmux.perl-api/v1', port: 'perl', repo: 'libtmux/libtmux-perl', revision, + nativeProvenance: { files: [{ path: source.file, sha256: 'b'.repeat(64) }], exporter: { repository: 'libtmux/libtmux-perl', revision: 'c'.repeat(40), working_tree: false } }, + sources: [{ package: 'LibTmux', product: 'core', revision, version: '0.001_001' }], + symbols: [ + { id: 'LibTmux::Selection', publicId: 'LibTmux::Selection', name: 'Selection', kind: 'class', modifiers: [], signatures: [], package: 'LibTmux', product: 'core', apiScope: 'exported', source }, + { id: 'LibTmux::Selection::grep', publicId: 'LibTmux::Selection::grep', name: 'grep', parent: 'LibTmux::Selection', kind: 'method', modifiers: [], signatures: [{ raw: 'sub grep($self, $callback)', receiver: { name: 'self' }, params: [{ name: 'callback' }] }], doc: { summary: 'See [Selection](pod:LibTmux::Selection).' }, package: 'LibTmux', product: 'core', apiScope: 'exported', source }, + ], +}) +describe('native Perl POD and signatures', () => { + it('preserves declared signatures and resolves authored links to exact owners', () => { + const model = extractPerlArtifact(artifact(), revision) + expect(model.symbols[1].signatures[0].raw).toBe('sub grep($self, $callback)') + expect(model.symbols[1].doc?.summary).toContain(':obj:`Selection `') + expect(model.nativeProvenance?.exporter.revision).toBe('c'.repeat(40)) + }) + it('renders normalized POD links in its declared Perl dialect', () => { + const input = artifact() + input.symbols[1].doc = { summary: '`new(config => $hashref)` copies a `libtmux.workspace/v1` record. Use [Selection](pod:LibTmux::Selection) with [Future](pod:Future).' } + const model = extractPerlArtifact(input, revision) + const index = new SymbolIndex(model.symbols, (symbol) => `/${symbol.id}/`, 'perl') + const spans = index.docSpans(model.symbols[1].doc!.summary, model.symbols[1]) + expect(spans).toContainEqual({ kind: 'code', text: 'new(config => $hashref)' }) + expect(spans).toContainEqual({ kind: 'code', text: 'libtmux.workspace/v1' }) + expect(spans).toContainEqual(expect.objectContaining({ kind: 'link', text: 'Future', href: 'https://metacpan.org/pod/Future' })) + expect(spans).toContainEqual(expect.objectContaining({ kind: 'ref', link: expect.objectContaining({ href: '/LibTmux::Selection/' }) })) + }) + it('keeps public codec exceptions while excluding the private codec module', () => { + const input = artifact() + input.symbols.push({ ...input.symbols[0], id: 'LibTmux::X::Codec', publicId: 'LibTmux::X::Codec', name: 'Codec', kind: 'exception' }) + expect(extractPerlArtifact(input, revision).symbols.some(({ id }) => id === 'LibTmux::X::Codec')).toBe(true) + input.symbols.push({ ...input.symbols[0], id: 'LibTmux::Codec', publicId: 'LibTmux::Codec', name: 'Codec' }) + expect(() => extractPerlArtifact(input, revision)).toThrow(/public/) + }) + it('rejects stale/dirty identities and private or unresolved public targets', () => { + expect(() => extractPerlArtifact(artifact(), 'd'.repeat(40))).toThrow(/revision/) + const dirty = artifact(); dirty.nativeProvenance.exporter.working_tree = true + expect(() => extractPerlArtifact(dirty, revision)).toThrow(/committed/) + const broken = artifact(); broken.symbols[1].doc = { summary: '[Missing](pod:LibTmux::Missing)' } + expect(() => extractPerlArtifact(broken, revision)).toThrow(/Unresolved/) + const privateApi = artifact(); privateApi.symbols[1].name = '_read' + expect(() => extractPerlArtifact(privateApi, revision)).toThrow(/public/) + }) +}) diff --git a/packages/api-model/test/prose-audit.outer.test.ts b/packages/api-model/test/prose-audit.outer.test.ts new file mode 100644 index 000000000..66ba065a2 --- /dev/null +++ b/packages/api-model/test/prose-audit.outer.test.ts @@ -0,0 +1,45 @@ +// Outer: the real CLI loads the complete prose corpus in subprocesses. +import { spawnSync } from 'node:child_process' +import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { describe, expect, it } from 'vitest' + +const root = fileURLToPath(new URL('../../../', import.meta.url)) +const audit = (...args: string[]) => spawnSync(process.execPath, ['scripts/check-api-links.mjs', ...args, '--json'], { cwd: root, encoding: 'utf8' }) + +describe('product prose audit', () => { + it('audits native commands and dependency types without accepting invented commands', () => { + const scratch = mkdtempSync(join(tmpdir(), 'libtmux-powershell-audit-')) + const file = join(scratch, 'topic.md') + try { + writeFileSync(file, '---\ntitle: Snapshot\nport: powershell\n---\n\nUse `Get-TmuxSnapshot` with `LibTmux.Server`.\n') + expect(audit(file).status).toBe(0) + writeFileSync(file, '---\ntitle: Snapshot\nport: powershell\n---\n\nUse `Invent-TmuxSnapshot`.\n') + const result = audit(file) + expect(result.status).toBe(1) + expect(JSON.parse(result.stdout).unresolved.map((entry: { text: string }) => entry.text)).toEqual(['Invent-TmuxSnapshot']) + } finally { + rmSync(scratch, { recursive: true }) + } + }) + + it('checks the product collection by default', () => { + const result = audit() + expect(JSON.parse(result.stdout).pages).toContain('ports/ts/mcp/index.md') + }) + + it('does not let another language satisfy an authored port reference', () => { + const scratch = mkdtempSync(join(tmpdir(), 'libtmux-prose-audit-')) + const file = join(scratch, 'topic.md') + try { + writeFileSync(file, '---\ntitle: Capture\nport: ts\nproduct: mcp\n---\n\nUse `capture_pane()` for output.\n') + const result = audit(file) + expect(result.status).toBe(1) + expect(JSON.parse(result.stdout).unresolved.map((entry: { text: string }) => entry.text)).toEqual(['capture_pane()']) + } finally { + rmSync(scratch, { recursive: true }) + } + }) +}) diff --git a/packages/api-model/test/prose-audit.test.ts b/packages/api-model/test/prose-audit.test.ts index 91647e4ac..1b2c9b2db 100644 --- a/packages/api-model/test/prose-audit.test.ts +++ b/packages/api-model/test/prose-audit.test.ts @@ -1,8 +1,6 @@ -import { spawnSync } from 'node:child_process' import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' import type { ApiModel, ApiSymbol } from '../src/model.ts' import { Resolver, notASymbol } from '../src/resolver.ts' @@ -13,44 +11,6 @@ import { builtinHref } from '../src/builtins.ts' import { extractWithSpec } from '../src/languages/spec.ts' import { GO } from '../src/languages/specs.ts' -const root = fileURLToPath(new URL('../../../', import.meta.url)) -const audit = (...args: string[]) => spawnSync(process.execPath, ['scripts/check-api-links.mjs', ...args, '--json'], { cwd: root, encoding: 'utf8' }) - -describe('product prose audit', () => { - it('audits native commands and dependency types without accepting invented commands', () => { - const scratch = mkdtempSync(join(tmpdir(), 'libtmux-powershell-audit-')) - const file = join(scratch, 'topic.md') - try { - writeFileSync(file, '---\ntitle: Snapshot\nport: powershell\n---\n\nUse `Get-TmuxSnapshot` with `LibTmux.Server`.\n') - expect(audit(file).status).toBe(0) - writeFileSync(file, '---\ntitle: Snapshot\nport: powershell\n---\n\nUse `Invent-TmuxSnapshot`.\n') - const result = audit(file) - expect(result.status).toBe(1) - expect(JSON.parse(result.stdout).unresolved.map((entry: { text: string }) => entry.text)).toEqual(['Invent-TmuxSnapshot']) - } finally { - rmSync(scratch, { recursive: true }) - } - }) - - it('checks the product collection by default', () => { - const result = audit() - expect(JSON.parse(result.stdout).pages).toContain('ports/ts/mcp/index.md') - }) - - it('does not let another language satisfy an authored port reference', () => { - const scratch = mkdtempSync(join(tmpdir(), 'libtmux-prose-audit-')) - const file = join(scratch, 'topic.md') - try { - writeFileSync(file, '---\ntitle: Capture\nport: ts\nproduct: mcp\n---\n\nUse `capture_pane()` for output.\n') - const result = audit(file) - expect(result.status).toBe(1) - expect(JSON.parse(result.stdout).unresolved.map((entry: { text: string }) => entry.text)).toEqual(['capture_pane()']) - } finally { - rmSync(scratch, { recursive: true }) - } - }) -}) - describe('product context in prose', () => { const symbols = [ { id: 'tmux.Window', name: 'Window', kind: 'struct', product: 'core' }, diff --git a/packages/api-model/test/resolver-corpus.outer.test.ts b/packages/api-model/test/resolver-corpus.outer.test.ts new file mode 100644 index 000000000..cf3962a1d --- /dev/null +++ b/packages/api-model/test/resolver-corpus.outer.test.ts @@ -0,0 +1,50 @@ +// Outer: audit the source documentation corpus against all registered port models. +import { existsSync, readFileSync, readdirSync } from 'node:fs' +import { dirname, join, relative } from 'node:path' +import { fileURLToPath } from 'node:url' +import { it, expect } from 'vitest' +import { API_MODEL_PORTS } from '../../../site/src/lib/ports.ts' +import { Resolver } from '../src/resolver.ts' +import { readInventory } from '../src/inventory.ts' +import { proseMentions } from '../src/mentions.ts' +import { portFromSentence } from '../src/prose.ts' +import type { ApiModel } from '../src/model.ts' +const here = dirname(fileURLToPath(import.meta.url)) +const DATA = join(here, '../../../site/src/data/api') +const PORTS = API_MODEL_PORTS.map((port) => port.slug) +const r = new Resolver(PORTS.map((port) => JSON.parse(readFileSync(join(DATA, `${port}.json`), 'utf8')) as ApiModel)) +const inventory = join(here, '../../../site/src/data/inventories/python.inv') +if (existsSync(inventory)) r.addInventory('Python', 'https://docs.python.org/3/', readInventory(readFileSync(inventory)).entries) + +it('resolves most unlinked references in the real corpus', () => { + const LABEL: Record = { + Python: 'py', Ruby: 'ruby', Lua: 'lua', TypeScript: 'ts', Rust: 'rs', Go: 'go', + ...Object.fromEntries(API_MODEL_PORTS.map((port) => [port.language, port.slug])), '.NET': 'csharp', + } + const docs = join(here, '../../../site/src/content/docs') + const walk = (dir: string): string[] => + readdirSync(dir, { withFileTypes: true }).flatMap((e) => + e.isDirectory() ? walk(join(dir, e.name)) : e.name.endsWith('.md') ? [join(dir, e.name)] : []) + let linkable = 0 + let resolved = 0 + for (const f of walk(docs)) { + const [area, port] = relative(docs, f).replace(/^_staged[\\/]/, '').split(/[\\/]/) + const owner = ['ports', '_staged'].includes(area) && PORTS.some((entry) => entry === port) ? port : undefined + for (const mention of proseMentions(readFileSync(f, 'utf8'), LABEL, () => owner)) { + // Authored links already select a destination, which may be a protocol + // object or external API. The name resolver does not own those labels. + if (mention.linked) continue + const { text, before } = mention + const port = portFromSentence(before) ?? mention.port + if (!port) continue + if (!/^[A-Za-z_.][\w.]*(\s*\(|\.)/.test(text) && !/\(\)$/.test(text)) continue + const res = r.resolve(port, text) + if (res.how === 'not-a-symbol') continue + linkable++ + if (!['ambiguous', 'no-symbol'].includes(res.how)) resolved++ + } + } + expect(linkable).toBeGreaterThan(200) + // Floor, not a pin. 87% at the time of writing. + expect(resolved / linkable).toBeGreaterThan(0.8) + }) diff --git a/packages/api-model/test/resolver.test.ts b/packages/api-model/test/resolver.test.ts index 968b8d19a..4f63b684e 100644 --- a/packages/api-model/test/resolver.test.ts +++ b/packages/api-model/test/resolver.test.ts @@ -1,12 +1,10 @@ -import { existsSync, readFileSync, readdirSync } from 'node:fs' -import { homedir } from 'node:os' -import { dirname, join, relative } from 'node:path' +import { existsSync, readFileSync } from 'node:fs' +import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { beforeAll, describe, expect, it } from 'vitest' import { readInventory } from '../src/inventory.ts' import type { ApiModel, ApiSymbol } from '../src/model.ts' import { Resolver, notASymbol, toPath } from '../src/resolver.ts' -import { proseMentions } from '../src/mentions.ts' import { portFromSentence } from '../src/prose.ts' /** @@ -152,38 +150,7 @@ d('resolver', () => { expect('symbol' in rust ? rust.symbol.product : undefined).toBe('mcp') }) - it('resolves most unlinked references in the real corpus', () => { - const LABEL: Record = { - Python: 'py', Ruby: 'ruby', Lua: 'lua', TypeScript: 'ts', Rust: 'rs', Go: 'go', - Java: 'java', '.NET': 'csharp', 'C++': 'cxx', Swift: 'swift', - } - const docs = join(here, '../../../site/src/content/docs') - const walk = (dir: string): string[] => - readdirSync(dir, { withFileTypes: true }).flatMap((e) => - e.isDirectory() ? walk(join(dir, e.name)) : e.name.endsWith('.md') ? [join(dir, e.name)] : []) - let linkable = 0 - let resolved = 0 - for (const f of walk(docs)) { - const [area, port] = relative(docs, f).split(/[\\/]/) - const owner = ['ports', '_staged'].includes(area) && PORTS.some((entry) => entry === port) ? port : undefined - for (const mention of proseMentions(readFileSync(f, 'utf8'), LABEL, () => owner)) { - // Authored links already select a destination, which may be a protocol - // object or external API. The name resolver does not own those labels. - if (mention.linked) continue - const { text, before } = mention - const port = portFromSentence(before) ?? mention.port - if (!port) continue - if (!/^[A-Za-z_.][\w.]*(\s*\(|\.)/.test(text) && !/\(\)$/.test(text)) continue - const res = r.resolve(port, text) - if (res.how === 'not-a-symbol') continue - linkable++ - if (!['ambiguous', 'no-symbol'].includes(res.how)) resolved++ - } - } - expect(linkable).toBeGreaterThan(200) - // Floor, not a pin. 87% at the time of writing. - expect(resolved / linkable).toBeGreaterThan(0.8) - }) + }) describe('mention paths by port', () => { diff --git a/scripts/build-site.sh b/scripts/build-site.sh index b970b1aec..12add0d6e 100755 --- a/scripts/build-site.sh +++ b/scripts/build-site.sh @@ -303,7 +303,7 @@ if [ -n "${LIBTMUX_DOCS_PORT:-}" ] && { [ "$LIBTMUX_DOCS_PORT" = ruby ] || [ "$L node "$script_dir/gen-api-model.mjs" --port "$LIBTMUX_DOCS_PORT" node "$script_dir/stage-port-docs.mjs" --port "$LIBTMUX_DOCS_PORT" elif [ -n "${LIBTMUX_DOCS_SOURCE_SHA:-}" ] && { [ "$LIBTMUX_DOCS_PORT" = powershell ] || [ "$LIBTMUX_DOCS_PORT" = julia ] || - [ "$LIBTMUX_DOCS_PORT" = elixir ]; }; then + [ "$LIBTMUX_DOCS_PORT" = elixir ] || [ "$LIBTMUX_DOCS_PORT" = perl ]; }; then node "$script_dir/gen-api-model.mjs" --port "$LIBTMUX_DOCS_PORT" node "$script_dir/stage-port-docs.mjs" --port "$LIBTMUX_DOCS_PORT" --from-source node "$script_dir/gen-api-model.mjs" --port "$LIBTMUX_DOCS_PORT" --nav @@ -320,12 +320,20 @@ elif [ -n "${LIBTMUX_DOCS_SOURCE_SHA:-}" ]; then node "$script_dir/gen-api-model.mjs" --port "$LIBTMUX_DOCS_PORT" node "$script_dir/gen-api-model.mjs" --port "$LIBTMUX_DOCS_PORT" --nav fi +if [ "${LIBTMUX_DOCS_PORT:-}" = perl ] && [ -n "${LIBTMUX_DOCS_SOURCE_SHA:-}" ]; then + node "$script_dir/gen-tmux-usage.mjs" --ports perl +fi node "$script_dir/stage-port-docs.mjs" --wrappers if [ -n "${LIBTMUX_DOCS_SOURCE_SHA:-}" ]; then # The selected API and wire contracts must come from the same product source. # Python's MCP product has its own checkout and revision. - node "$script_dir/gen-mcp-protocol.mjs" --port "$LIBTMUX_DOCS_PORT" --source-bound - node "$script_dir/gen-mcp-tools.mjs" --port "$LIBTMUX_DOCS_PORT" --source-bound + if node --input-type=module -e ' + const { PORT_BY_SLUG } = await import("file://'"$site_dir"'/src/lib/ports.ts"); + process.exit(PORT_BY_SLUG[process.env.LIBTMUX_DOCS_PORT]?.productAvailability?.mcp === "excluded" ? 1 : 0); + '; then + node "$script_dir/gen-mcp-protocol.mjs" --port "$LIBTMUX_DOCS_PORT" --source-bound + node "$script_dir/gen-mcp-tools.mjs" --port "$LIBTMUX_DOCS_PORT" --source-bound + fi fi node "$script_dir/gen-example-sources.mjs" node "$script_dir/gen-mentions.mjs" diff --git a/scripts/gen-api-model.mjs b/scripts/gen-api-model.mjs index 804f74e23..985b661af 100644 --- a/scripts/gen-api-model.mjs +++ b/scripts/gen-api-model.mjs @@ -15,6 +15,7 @@ import { fileURLToPath } from 'node:url' import { PORTS as PORT_DEFS } from '../site/src/lib/ports.ts' import { extractDoxygen } from '../packages/api-model/src/languages/doxygen.ts' import { extractLua } from '../packages/api-model/src/languages/lua.ts' +import { extractPerlArtifact } from '../packages/api-model/src/languages/perl.ts' import { extractRuby } from '../packages/api-model/src/languages/ruby.ts' import { extractPowerShell } from '../packages/api-model/src/languages/powershell.ts' import { extractJulia } from '../packages/api-model/src/languages/julia.ts' @@ -219,6 +220,10 @@ const PORTS = { excludePaths: [/(^|\.)_vendor\./, /(^|\.)_compat\./], }, }, + perl: { + checkout: '~/work/libtmux/libtmux-perl-docs-site', root: '.', nativeArtifact: 'docs/_build/api.json', + repo: 'libtmux/libtmux-perl', options: {}, + }, ruby: { checkout: '~/work/libtmux/libtmux-ruby-docs', root: '.', @@ -639,7 +644,7 @@ for (const [port, cfg] of Object.entries(PORTS)) { process.exit(1) } const artifact = JSON.parse(readFileSync(artifactPath, 'utf8')) - const nativeExtractors = { ruby: extractRuby, lua: extractLua, powershell: extractPowerShell, julia: extractJulia, elixir: extractElixir } + const nativeExtractors = { perl: extractPerlArtifact, ruby: extractRuby, lua: extractLua, powershell: extractPowerShell, julia: extractJulia, elixir: extractElixir } model = nativeExtractors[port](artifact, head) } else { model = await extractProject({ diff --git a/scripts/gen-tmux-usage.mjs b/scripts/gen-tmux-usage.mjs index c48e680a1..fffdabbc3 100644 --- a/scripts/gen-tmux-usage.mjs +++ b/scripts/gen-tmux-usage.mjs @@ -30,7 +30,6 @@ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync import { homedir, tmpdir } from 'node:os' import { dirname, join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' -import { extractProject } from '../packages/api-model/src/project.ts' import { GRAMMARS, isLibrarySource, scanSource } from './lib/tmux-usage-scan.mjs' import { applyConditions, applyExclusions, conditionProblem, deriveUsage, partialProblems, ruleHolds, verifyClaims } from './lib/tmux-usage-derive.mjs' import { auditEvidence } from './lib/tmux-usage-audit.mjs' @@ -209,8 +208,12 @@ export async function scanPort({ port, model, commands, checkout, known, dispatc const types = [] const sources = librarySources(checkout, model.revision, grammar) const wanted = new Set(commands) + const native = port === 'perl' ? readJson(join(checkout, 'docs/_build/api.json')) : undefined + if (native && (native.nativeScan?.schema !== 'libtmux.perl-source/v1' || native.nativeScan.revision !== model.revision || native.nativeProvenance?.exporter?.working_tree !== false)) { + throw new Error('Perl command indexing requires committed source-bound native PPI analysis') + } for (const [path, text] of sources) { - const scanned = await scanSource({ grammar, text, commands: wanted, known, dispatch, builders, guards, labels, trace }) + const scanned = await scanSource({ grammar, text, commands: wanted, known, dispatch, builders, guards, labels, trace, native: native?.nativeScan.files[path] }) for (const fn of scanned.functions) functions.push({ ...fn, file: path }) for (const type of scanned.types) types.push({ ...type, file: path }) } @@ -261,6 +264,7 @@ const CORE_EXTRACTION = { csharp: { roots: ['src/LibTmux'], options: { inherited /** The public symbols of a core library as they were at a revision, extracted from that revision's own files. */ async function modelAtRevision({ port, checkout, revision }) { + const { extractProject } = await import('../packages/api-model/src/project.ts') const config = CORE_EXTRACTION[port] if (!config) throw new Error(`${port}: no source roots are configured to read its symbols at ${revision.slice(0, 8)}`) const dir = mkdtempSync(join(tmpdir(), 'tmux-usage-')) diff --git a/scripts/gen-workspace-showcase.mjs b/scripts/gen-workspace-showcase.mjs index df6f4c95a..d2a9ad18c 100644 --- a/scripts/gen-workspace-showcase.mjs +++ b/scripts/gen-workspace-showcase.mjs @@ -36,19 +36,27 @@ const { parseFrontmatter } = createRequire(join(root, 'site', 'package.json'))(' const digest = (text) => createHash('sha256').update(text).digest('hex') const lineOf = (text, index) => text.slice(0, index).split('\n').length +// Committed inputs are immutable within this read-only generator invocation. +const committedFiles = new Map() +const availableRevisions = new Set() /** Committed bytes of `path` at `revision`. */ export function readAt({ checkout, revision, path }) { if (!/^[a-f0-9]{40}$/.test(revision)) throw new Error(`Invalid revision: ${revision}`) - return execFileSync('git', ['-C', checkout, 'show', `${revision}:${path}`], - { encoding: 'utf8', maxBuffer: 8 * 1024 * 1024, stdio: ['ignore', 'pipe', 'pipe'] }) + const key = JSON.stringify([resolve(checkout), revision, path]) + if (!committedFiles.has(key)) committedFiles.set(key, execFileSync('git', ['-C', checkout, 'show', `${revision}:${path}`], + { encoding: 'utf8', maxBuffer: 8 * 1024 * 1024, stdio: ['ignore', 'pipe', 'pipe'] })) + return committedFiles.get(key) } /** Whether the checkout has the revision's objects. */ export function hasRevision({ checkout, revision }) { if (!checkout || !existsSync(join(checkout, '.git'))) return false + const key = JSON.stringify([resolve(checkout), revision]) + if (availableRevisions.has(key)) return true try { execFileSync('git', ['-C', checkout, 'cat-file', '-e', `${revision}^{commit}`], { stdio: 'ignore' }) + availableRevisions.add(key) return true } catch { return false } } diff --git a/scripts/lib/api-destinations.mjs b/scripts/lib/api-destinations.mjs index 6957c0dad..54c0031d2 100644 --- a/scripts/lib/api-destinations.mjs +++ b/scripts/lib/api-destinations.mjs @@ -62,6 +62,7 @@ export const API_HOSTS = new Set([ 'docs.oracle.com', 'docs.junit.org', 'kotlinlang.org', 'www.scala-lang.org', 'docs.scala-lang.org', 'typelevel.org', 'javadoc.io', 'learn.microsoft.com', 'fsharp.github.io', 'en.cppreference.com', 'eel.is', 'developer.apple.com', 'docs.swift.org', 'docs.ruby-lang.org', 'ruby-doc.org', 'www.lua.org', 'luals.github.io', 'docs.julialang.org', 'hexdocs.pm', 'www.erlang.org', + 'perldoc.perl.org', 'metacpan.org', 'gofastmcp.com', 'csharp.sdk.modelcontextprotocol.io', 'ts.sdk.modelcontextprotocol.io', 'modelcontextprotocol.io', 'cmake.org', ]) diff --git a/scripts/lib/api-identities.mjs b/scripts/lib/api-identities.mjs index 8d0e79de3..95363e41a 100644 --- a/scripts/lib/api-identities.mjs +++ b/scripts/lib/api-identities.mjs @@ -305,6 +305,15 @@ export function doccIdentity(url, data) { return { via: 'docc', declared: kind ?? 'topic', kind: DOCC_KINDS[kind] ?? (kind ? 'other' : 'topic'), path, title: data.metadata?.title ?? '' } } +/** Native POD names a module in its NAME paragraph, independently of its URL. */ +function pod(_url, page, fragment) { + if (fragment) return undefined + const paragraph = /]*\bid=["']NAME["'][^>]*>[\s\S]*?<\/h[1-6]>\s*

([\s\S]*?)<\/p>/i.exec(page.html)?.[1] + const name = paragraph && /^([A-Za-z]\w*(?:::\w+)*)\s+-\s+/.exec(strip(paragraph))?.[1] + if (!name) return undefined + return { via: 'pod', declared: 'module', kind: 'module', path: name.split('::'), title: page.title } +} + /** * The identity a page declares, or `undefined` when the host publishes none we * read (a handbook, a manual, a wiki): those links stand on the rules of @@ -333,6 +342,7 @@ function parserFor(hostname, pathname, page) { if (hostname === 'learn.microsoft.com' && /\/(dotnet\/api|powershell\/module)\//i.test(pathname)) return learn if (hostname === 'docs.python.org') return cpython if (hostname === 'pkg.go.dev') return godoc + if (hostname === 'perldoc.perl.org' || hostname === 'metacpan.org') return pod if (hostname === 'docs.julialang.org') return documenter if (hostname === 'developer.mozilla.org') return mdn return undefined diff --git a/scripts/lib/api-links.mjs b/scripts/lib/api-links.mjs index b2fcfae9c..219cb68c1 100644 --- a/scripts/lib/api-links.mjs +++ b/scripts/lib/api-links.mjs @@ -96,6 +96,7 @@ export function languageOfUrl(url) { 'www.lua.org': 'lua', 'luals.github.io': 'lua', 'docs.julialang.org': 'julia', 'www.erlang.org': 'erlang', + 'perldoc.perl.org': 'perl', 'metacpan.org': 'perl', 'modelcontextprotocol.io': 'any', } if (byHost[hostname]) return byHost[hostname] @@ -107,7 +108,7 @@ export function languageOfUrl(url) { /** The languages each port's documentation legitimately reaches: its own, and what its platform shares. */ export const PORT_LANGUAGES = { - py: ['python'], rs: ['rust'], go: ['go'], ts: ['typescript'], java: ['java'], + py: ['python'], perl: ['perl'], rs: ['rust'], go: ['go'], ts: ['typescript'], java: ['java'], kotlin: ['kotlin', 'java'], scala: ['scala', 'java'], csharp: ['csharp', 'dotnet'], fsharp: ['fsharp', 'dotnet'], powershell: ['powershell', 'dotnet'], cxx: ['cpp'], swift: ['swift'], julia: ['julia'], lua: ['lua'], elixir: ['elixir', 'erlang'], ruby: ['ruby'], diff --git a/scripts/lib/api-sources.mjs b/scripts/lib/api-sources.mjs index 4d42bbbaa..5579bb74d 100644 --- a/scripts/lib/api-sources.mjs +++ b/scripts/lib/api-sources.mjs @@ -102,6 +102,7 @@ export const DEFAULT_SCOPES = { py: ['', 'builtins'], julia: ['Base', 'Core'], elixir: [''], + perl: [''], cxx: ['', 'std'], lua: [''], powershell: [''], diff --git a/scripts/lib/destination-verification.mjs b/scripts/lib/destination-verification.mjs index 70af3910b..918117ffb 100644 --- a/scripts/lib/destination-verification.mjs +++ b/scripts/lib/destination-verification.mjs @@ -525,7 +525,9 @@ export function collectDestinations(inventory, manifests) { for (const entry of entries) { const unlinked = entry.status !== 'published' for (const destination of entryDestinations(entry)) { - if (!unlinked || destination.kind !== 'source') add(port, entry, destination, entry.status) + if (!unlinked || destination.kind !== 'source' || entry.sourceAvailable) { + add(port, entry, destination, destination.kind === 'source' && entry.sourceAvailable ? 'published' : entry.status) + } } for (const destination of entryCandidates(entry)) add(port, entry, destination, 'candidate') } @@ -577,15 +579,15 @@ export function staleWarnings(stale, maxAgeDays = EVIDENCE_MAX_AGE_DAYS) { * * A registered port the inventory omits gets no header links and no * verification, and nothing else notices: the header just offers nothing. So - * each registered port must have an entry whose library is published, which is - * what the header builds its links from, and each entry must belong to a + * each registered port must have a published library or explicitly available + * library source, which is what the header builds its links from, and each entry must belong to a * registered port. */ export function inventoryCoverage(inventory, registered) { const missing = registered.filter((slug) => !inventory[slug]?.length) .map((slug) => `${slug} is registered in ports.ts but has no inventory entry, so its header offers nothing`) - const unlinked = registered.filter((slug) => inventory[slug]?.length && !inventory[slug].some((entry) => entry.kind === 'library' && entry.status === 'published')) - .map((slug) => `${slug} has no published library entry, so its header offers nothing`) + const unlinked = registered.filter((slug) => inventory[slug]?.length && !inventory[slug].some((entry) => entry.kind === 'library' && (entry.status === 'published' || entry.sourceAvailable))) + .map((slug) => `${slug} has no available library source or publication, so its header offers nothing`) const orphaned = Object.keys(inventory).filter((slug) => !registered.includes(slug)) .map((slug) => `${slug} has inventory entries but is not registered in ports.ts`) return [...missing, ...unlinked, ...orphaned] diff --git a/scripts/lib/manifest-packages.mjs b/scripts/lib/manifest-packages.mjs index 78937bc5f..2870294f3 100644 --- a/scripts/lib/manifest-packages.mjs +++ b/scripts/lib/manifest-packages.mjs @@ -68,6 +68,16 @@ function newestTag(tags, prefix) { } const READERS = { + /** Each MakeMaker declaration owns one native Perl distribution. */ + perl(repo) { + const distributions = repo.files().filter((path) => /^packages\/(core|async|workspace)\/Makefile\.PL$/.test(path)).map((manifest) => { + const text = repo.read(manifest) + const name = /NAME\s*=>\s*'([^']+)'/.exec(text)?.[1]?.replaceAll('::', '-') + const version = /VERSION\s*=>\s*'([^']+)'/.exec(text)?.[1] + return { name, version, manifest } + }) + return { distributions, units: [{ unit: 'command', name: 'libtmux-workspace', path: 'packages/workspace/bin/libtmux-workspace', file: true }] } + }, /** `[project] name` and `version`. */ py(repo, { repository, manifest = 'pyproject.toml' }) { const project = section(repo.read(manifest), 'project') @@ -223,7 +233,7 @@ const READERS = { /** Which reader a port uses: a wrapper port reads its parent's repository. */ const READER_FOR = { - py: 'py', ruby: 'ruby', lua: 'lua', powershell: 'powershell', julia: 'julia', ts: 'ts', rs: 'rs', go: 'go', + perl: 'perl', py: 'py', ruby: 'ruby', lua: 'lua', powershell: 'powershell', julia: 'julia', ts: 'ts', rs: 'rs', go: 'go', java: 'java', kotlin: 'java', scala: 'java', csharp: 'dotnet', fsharp: 'dotnet', cxx: 'cxx', swift: 'swift', elixir: 'elixir', } @@ -232,7 +242,7 @@ const READER_FOR = { * @param {string} slug * @param {{ revision: string, files(): string[], read(path: string): string, has(path: string): boolean, tags(): string[] }} repo * @param {{ identity?: string, repository?: string, manifest?: string }} [options] - * @returns {{ distributions: { name: string, version?: string, manifest: string }[], units: { unit: string, name: string, path?: string }[] }} + * @returns {{ distributions: { name: string, version?: string, manifest: string }[], units: { unit: string, name: string, path?: string, file?: boolean }[] }} */ export function readPort(slug, repo, options = {}) { const reader = READERS[READER_FOR[slug]] diff --git a/scripts/lib/tmux-usage-perl.mjs b/scripts/lib/tmux-usage-perl.mjs new file mode 100644 index 000000000..322109f6c --- /dev/null +++ b/scripts/lib/tmux-usage-perl.mjs @@ -0,0 +1,44 @@ +import { createHash } from 'node:crypto' + +/** + * @typedef {{ sha256: string, functions: { name: string, owner?: string, start: number, nameLine: number, end: number, kind: string }[], tokens: { t: string, v: string, line: number, function: number }[], types?: { name?: string, start: number, end: number }[] }} NativePerlInput + */ + +/** Read native PPI locations and tokens; source text is never parsed as JavaScript. */ +/** @param {string} text + * @param {NativePerlInput | undefined} native + * @param {{ commands: ReadonlySet, known: ReadonlySet }} options + */ +export function scanPerl(text, native, { commands, known }) { + if (!text) return { functions: [], types: [], orphans: [] } + const sha = createHash('sha256').update(text).digest('hex') + if (!native || native.sha256 !== sha || !Array.isArray(native.functions) || !Array.isArray(native.tokens)) { + throw new Error('Perl source analysis requires fresh native PPI input for these exact bytes') + } + const functions = native.functions.map((fn) => ({ ...fn, sites: [], calls: new Map(), receivers: new Map(), callList: [] })) + const keyword = new Set(['sub', 'if', 'elsif', 'unless', 'while', 'until', 'for', 'foreach', 'try', 'catch', 'return', 'map', 'grep', 'sort']) + const grouped = Map.groupBy(native.tokens, (token) => token.function) + for (const [index, tokens] of grouped) { + const fn = functions[index] + if (!fn) throw new Error('Perl native token names an unknown function') + for (let at = 0; at < tokens.length; at++) { + const token = tokens[at] + if (token.t === 'id' && !keyword.has(token.v) && tokens[at - 1]?.v !== 'sub' && tokens[at + 1]?.v === '(') { + const receiver = tokens[at - 1]?.v === '->' ? tokens[at - 2]?.v.replace(/^[$@%]/, '').toLowerCase() : undefined + fn.calls.set(token.v, token.line) + const receivers = fn.receivers.get(token.v) ?? new Set() + if (receiver) receivers.add(receiver) + fn.receivers.set(token.v, receivers) + fn.callList.push({ name: token.v, line: token.line, ...(receiver ? { receiver } : {}) }) + } + if (token.t !== 'str') continue + const [command, next] = token.v.split(/\s+/) + if (!known.has(command) || !commands.has(command) || next !== undefined && !next.startsWith('-')) continue + // Operation plans select command vectors dynamically. A literal alone + // proves neither dispatch nor its caller's scope; reviewed claims do. + fn.sites.push({ command, line: token.line, flags: '', dispatch: null, + why: 'PPI literal in a dynamic operation plan; dispatch and scope require reviewed source evidence' }) + } + } + return { functions, types: native.types ?? [], orphans: [] } +} diff --git a/scripts/lib/tmux-usage-scan.mjs b/scripts/lib/tmux-usage-scan.mjs index 6288c77b3..fd1c6703e 100644 --- a/scripts/lib/tmux-usage-scan.mjs +++ b/scripts/lib/tmux-usage-scan.mjs @@ -6,18 +6,19 @@ * innermost named function around it and keeps the flag literals that travel * with the command, because the flags choose the scope tmux lists. */ +import { scanPerl } from './tmux-usage-perl.mjs' import { parserFor } from '../../packages/api-model/src/parser.ts' import { receiverOf, scanElixir, scanFSharp, scanJulia } from './tmux-usage-lexical.mjs' /** Port to the grammar that reads its source. PowerShell cmdlets are C#; Julia, F# and Elixir are read by their text. */ export const GRAMMARS = { - py: 'python', ts: 'typescript', rs: 'rust', go: 'go', java: 'java', kotlin: 'kotlin', scala: 'scala', + perl: 'perl', py: 'python', ts: 'typescript', rs: 'rust', go: 'go', java: 'java', kotlin: 'kotlin', scala: 'scala', csharp: 'csharp', powershell: 'csharp', cxx: 'cpp', swift: 'swift', ruby: 'ruby', lua: 'lua', julia: 'julia', fsharp: 'fsharp', elixir: 'elixir', } /** Source extensions per grammar, minus declaration-only files. */ export const EXTENSIONS = { - python: /\.py$/, typescript: /(?, known: ReadonlySet, dispatch?: ReadonlySet, builders?: ReadonlySet, guards?: { name: string, owner?: string }[], labels?: ReadonlyMap>, trace?: (site: object, context: object) => void }} input + * @param {{ grammar: string, text: string, commands: ReadonlySet, known: ReadonlySet, dispatch?: ReadonlySet, builders?: ReadonlySet, guards?: { name: string, owner?: string }[], labels?: ReadonlyMap>, trace?: (site: object, context: object) => void, native?: import('./tmux-usage-perl.mjs').NativePerlInput }} input * `commands` are the names to find; `known` are all tmux command names, so * a list that holds a different command is not read as this command's flags. * @returns {Promise<{ functions: ScannedFunction[], types: { name?: string, start: number, end: number }[], orphans: Site[] }>} * `types` are the declarations that own functions, so a claim can anchor to * a class; `orphans` are the sites outside any named function. */ -export async function scanSource({ grammar, text, commands, known, dispatch, builders: declared = new Set(), guards = [], labels = new Map(), trace }) { +export async function scanSource({ grammar, text, commands, known, dispatch, builders: declared = new Set(), guards = [], labels = new Map(), trace, native }) { // A guard wraps the command it is handed and hands it on, so it passes a command through as a builder does. const builders = new Set([...declared, ...guards.map((guard) => guard.name)]) const isGuard = (fn) => guards.some((guard) => guard.name === fn?.name && (!guard.owner || guard.owner === fn.owner)) @@ -600,6 +601,7 @@ export async function scanSource({ grammar, text, commands, known, dispatch, bui } return false } + if (grammar === 'perl') return scanPerl(text, native, { commands, known }) if (grammar === 'julia') return scanJulia(text, { commands, known, dispatch }) if (grammar === 'elixir') return scanElixir(text, { commands, known, dispatch }) if (grammar === 'fsharp') return scanFSharp(text) diff --git a/scripts/lib/tmux-usage-sweep.mjs b/scripts/lib/tmux-usage-sweep.mjs index c1bca8201..5ac7b104e 100644 --- a/scripts/lib/tmux-usage-sweep.mjs +++ b/scripts/lib/tmux-usage-sweep.mjs @@ -24,6 +24,7 @@ export const OPTION_SPELLINGS = new Set(['set-window-option', 'show-window-optio /** Where the library itself lives in each port, so a consumer package or a test helper is not swept. */ export const LIBRARY_ROOTS = { + perl: ['packages/core/lib/', 'packages/async/lib/'], py: ['src/libtmux/'], ruby: ['gems/libtmux/', 'gems/libtmux-async/'], lua: ['lua/libtmux/'], diff --git a/scripts/publication-provenance.mjs b/scripts/publication-provenance.mjs index c9bf3fcbd..3903a4ba8 100644 --- a/scripts/publication-provenance.mjs +++ b/scripts/publication-provenance.mjs @@ -11,7 +11,7 @@ import { PORT_BY_SLUG } from '../site/src/lib/ports.ts' export const RECORD = 'build-provenance.json' const SHA = /^[0-9a-f]{40}$/ const DIGEST = /^[0-9a-f]{64}$/ -const NATIVE_GENERATOR_PORTS = new Set(['ruby', 'lua', 'powershell', 'julia']) +const NATIVE_GENERATOR_PORTS = new Set(['ruby', 'lua', 'powershell', 'julia', 'perl']) const segment = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/ const fail = (message) => { throw new Error(`publication-provenance: ${message}`) } const check = (condition, message) => { if (!condition) fail(message) } diff --git a/scripts/stage-port-docs.mjs b/scripts/stage-port-docs.mjs index 6b1dd24e1..6665ba4a0 100644 --- a/scripts/stage-port-docs.mjs +++ b/scripts/stage-port-docs.mjs @@ -33,6 +33,8 @@ const ROUTES = Object.fromEntries(SOURCE_GUIDE_PORTS.map((slug) => [slug, staged const expand = (value) => value.startsWith('~/') ? join(homedir(), value.slice(2)) : value function titleAndBody(content, sourcePath) { + // The shared catalog supplies page metadata; source frontmatter is not article prose. + content = content.replace(/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/, '') content = content.replace(/[\s\S]*?\s*/g, '') // GitHub README headers may center the title and intro in a presentation // wrapper. The site supplies its own heading; later HTML stays intact. @@ -288,10 +290,30 @@ export function artifactFromRevision(port, checkout, revision) { } catch (cause) { throw new Error(`${port.slug}: integrated guides need ${port.repo}@${revision} in ${checkout}. Set LIBTMUX_DOCS_CHECKOUT_${port.slug.toUpperCase()} to a local checkout containing that commit; this check does not fetch.`, { cause }) } + const paths = Object.keys(ROUTES[port.slug]) + const blobs = execFileSync('git', ['-C', checkout, 'cat-file', '--batch'], { + input: paths.map((path) => `${revision}:${path}\n`).join(''), maxBuffer: 16 * 1024 * 1024, + stdio: ['pipe', 'pipe', 'pipe'], + }) + const contents = new Map() + let offset = 0 + for (const path of paths) { + const end = blobs.indexOf(10, offset) + const header = blobs.subarray(offset, end).toString('ascii') + const match = /^[a-f0-9]{40} blob (\d+)$/.exec(header) + const size = match && Number(match[1]) + if (end < offset || size === null || !Number.isSafeInteger(size) || size < 0 || + end + size + 1 >= blobs.length || blobs[end + size + 1] !== 10) { + throw new Error(`${port.slug}: missing or malformed integrated guide ${revision}:${path}`) + } + contents.set(path, blobs.subarray(end + 1, end + size + 1).toString('utf8')) + offset = end + size + 2 + } + if (offset !== blobs.length) throw new Error(`${port.slug}: unexpected trailing Git blob data`) + const readSource = (file) => contents.get(file) ?? git('show', `${revision}:${file}`) return { source: { repository: port.repo, revision }, - guides: Object.keys(ROUTES[port.slug]).map((path) => { - const readSource = (file) => git('show', `${revision}:${file}`) + guides: paths.map((path) => { const content = readSource(path) return { path, content: port.slug === 'julia' ? expandDocumenter(content, path, readSource) : content } }), @@ -336,29 +358,32 @@ export function run() { } if (!check && (refreshCache || selectedSource)) { mkdirSync(cacheRoot, { recursive: true }) - writeFileSync(cachePath, `${JSON.stringify(artifact, null, 2)}\n`) + const content = `${JSON.stringify(artifact, null, 2)}\n` + if (!existsSync(cachePath) || readFileSync(cachePath, 'utf8') !== content) writeFileSync(cachePath, content) } for (const [file, content] of stagedPortGuides(port.slug, artifact)) generated.set(file, content) } - if (check) { - const actual = new Map() - const walk = (directory, prefix = '') => { - if (!existsSync(directory)) return - for (const entry of readdirSync(directory, { withFileTypes: true })) { - const relative = posix.join(prefix, entry.name) - if (entry.isDirectory()) walk(join(directory, entry.name), relative) - else if (selected.some((port) => relative.startsWith(`${port.slug}/`))) actual.set(relative, readFileSync(join(directory, entry.name), 'utf8')) + const actual = new Map() + const allOutputs = !check && !selectedPort && !wrappersOnly + const walk = (directory, prefix = '') => { + if (!existsSync(directory)) return + for (const entry of readdirSync(directory, { withFileTypes: true })) { + const relative = posix.join(prefix, entry.name) + if (entry.isDirectory()) walk(join(directory, entry.name), relative) + else if (allOutputs || selected.some((port) => relative.startsWith(`${port.slug}/`))) { + actual.set(relative, readFileSync(join(directory, entry.name), 'utf8')) } } - walk(output) + } + walk(output) + if (check) { const stale = generated.size !== actual.size || [...generated].some(([file, content]) => actual.get(file) !== content) if (stale) throw new Error('staged port guides are missing or stale; rerun without --check') } else { - if (selectedPort || wrappersOnly) { - for (const port of selected) rmSync(join(output, port.slug), { recursive: true, force: true }) - } else rmSync(output, { recursive: true, force: true }) + for (const file of actual.keys()) if (!generated.has(file)) rmSync(join(output, file), { force: true }) for (const [file, content] of generated) { + if (actual.get(file) === content) continue const destination = join(output, file) mkdirSync(dirname(destination), { recursive: true }) writeFileSync(destination, content) diff --git a/scripts/test-loop.mjs b/scripts/test-loop.mjs index 4327a3785..66293ba5b 100644 --- a/scripts/test-loop.mjs +++ b/scripts/test-loop.mjs @@ -1,5 +1,6 @@ #!/usr/bin/env node import { spawn } from 'node:child_process' +import { existsSync, readFileSync } from 'node:fs' import { fileURLToPath } from 'node:url' const root = fileURLToPath(new URL('../', import.meta.url)) @@ -8,6 +9,13 @@ process.env.NODE_COMPILE_CACHE ??= fileURLToPath(new URL('../node_modules/.cache const loop = process.argv[2] const budget = { inner: 2, medium: 10, outer: 60 }[loop] if (!budget) throw new Error('Usage: test-loop.mjs inner|medium|outer') +const tiers = JSON.parse(readFileSync(new URL('./test-tiers.json', import.meta.url), 'utf8')) +const listed = Object.values(tiers).flatMap((groups) => groups.flatMap((group) => group.files)) +if (new Set(listed).size !== listed.length || listed.some((file) => !existsSync(new URL(`../${file}`, import.meta.url)))) { + throw new Error('test-tiers.json contains duplicate or missing suites') +} +const excluded = (tier, directory) => (tiers[tier] ?? []).flatMap((group) => group.files) + .filter((file) => file.startsWith(`${directory}/`)).map((file) => file.slice(directory.length + 1)) const started = performance.now() const vitest = 'site/node_modules/vitest/vitest.mjs' const children = new Set() @@ -32,6 +40,7 @@ for (const signal of ['SIGINT', 'SIGTERM']) process.on(signal, cancel) function run(command, args) { if (cancelled) throw new Error(`${loop} cancelled or exceeded ${budget}s`) + const taskStarted = performance.now() const promise = new Promise((resolve, reject) => { const child = spawn(command, args, { cwd: root, stdio: 'inherit', detached: true, @@ -44,6 +53,7 @@ function run(command, args) { }) child.on('close', (code, signal) => { children.delete(child) + if (process.env.LIBTMUX_DOCS_LOOP_TIMINGS) console.error(`loop timing ${(performance.now() - taskStarted).toFixed(0)}ms: ${command} ${args.join(' ')}`) if (code === 0) resolve() else reject(new Error(`${command} ${args.join(' ')}: ${signal ?? code}`)) }) @@ -57,8 +67,10 @@ const pnpm = (...args) => { return /\.[cm]?js$/.test(entry) ? node(entry, ...args) : run(entry, args) } const tests = (directory, names = []) => node(vitest, 'run', '--root', directory, - '--maxWorkers', directory === 'site' ? '3' : '2', '--pool', 'threads', '--fsModuleCache', - ...(loop === 'medium' ? ['--exclude', '**/*.outer.test.ts'] : []), + '--maxWorkers', directory === 'site' ? '6' : directory === 'packages/api-model' ? '4' : '2', '--pool', 'threads', '--fsModuleCache', + ...((loop === 'medium' ? ['**/*.outer.test.ts', ...excluded('outer', directory)] : []) + .concat(['**/*.publication.test.ts', ...excluded('publication', directory)]) + .flatMap((pattern) => ['--exclude', pattern])), ...names.map((name) => `test/${name}.test.ts`)) try { @@ -74,19 +86,20 @@ try { node('scripts/check-api-links.mjs'), node('scripts/check-nav.mjs'), node('scripts/check-example-blocks.mjs'), - node('scripts/check-example-blocks.negative.mjs'), node('scripts/gen-mentions.mjs', '--check'), node('scripts/gen-workspace-entities.mjs', '--check'), node('scripts/gen-workspace-showcase.mjs', '--check'), - node('scripts/gen-workspace-showcase.negative.mjs'), node('scripts/gen-product-copy.mjs', '--check'), - node('scripts/gen-product-copy.negative.mjs'), node('scripts/gen-tmux-catalog.mjs', '--check'), node('scripts/gen-tmux-usage.mjs', '--check'), node('scripts/gen-shell-ports.mjs', '--check'), node('scripts/gen-brand-css.mjs', '--check'), ) + // Adversarial CLI fixtures spawn subprocesses and temporary Git repositories; keep them in outer. if (loop === 'outer') checks.push( + node('scripts/check-example-blocks.negative.mjs'), + node('scripts/gen-workspace-showcase.negative.mjs'), + node('scripts/gen-product-copy.negative.mjs'), node('scripts/gen-example-sources.mjs', '--check'), pnpm('run', '--recursive', 'type-check'), pnpm('run', 'type-check:python'), diff --git a/scripts/test-tiers.json b/scripts/test-tiers.json new file mode 100644 index 000000000..8eae73446 --- /dev/null +++ b/scripts/test-tiers.json @@ -0,0 +1,150 @@ +{ + "outer": [ + { + "reason": "Executes real subprocesses or Git repositories.", + "files": [ + "site/test/api-example-verification.test.ts", + "site/test/api-fidelity.test.ts", + "site/test/cargo-features.test.ts", + "site/test/cooldown.test.ts", + "site/test/core-capabilities.test.ts", + "site/test/deploy-workflow.test.ts", + "site/test/enum-variants.test.ts", + "site/test/example-columns.test.ts", + "site/test/example-sources.test.ts", + "site/test/field-table-pages.test.ts", + "site/test/font-audit.test.ts", + "site/test/install-line-width.test.ts", + "site/test/ja-translations.test.ts", + "site/test/just-clean.test.ts", + "site/test/jvm-layout-bundle.test.ts", + "site/test/machine-readable.test.ts", + "site/test/mcp-source-links.test.ts", + "site/test/mcp-tmux-state.test.ts", + "site/test/no-orphan-code-blocks.test.ts", + "site/test/port-docs-identity.test.ts", + "site/test/port-docs-runtime.test.ts", + "site/test/port-landing.test.ts", + "site/test/port-metadata.test.ts", + "site/test/publication-provenance.test.ts", + "site/test/publish-default-versions.test.ts", + "site/test/publish-plan.test.ts", + "site/test/publish-prefixes.test.ts", + "site/test/published-inventory.test.ts", + "site/test/source-links.test.ts", + "site/test/stage-port-docs.test.ts", + "site/test/translation-state.test.ts", + "site/test/versions.test.ts", + "site/test/workspace-mentions.test.ts" + ] + }, + { + "reason": "Compiles or renders real Astro/Tailwind/native interfaces.", + "files": [ + "site/test/api-doc-mentions.test.ts", + "site/test/api-example-languages.test.ts", + "site/test/api-glossary-navigation.test.ts", + "site/test/api-glossary.test.ts", + "site/test/api-headings.test.ts", + "site/test/api-prose.test.ts", + "site/test/api-qualified-name.test.ts", + "site/test/api-sidebar.test.ts", + "site/test/api-signature-scope.test.ts", + "site/test/api-tmux-sections.test.ts", + "site/test/authored-links.test.ts", + "site/test/breadcrumb-font.test.ts", + "site/test/c-layout.test.ts", + "site/test/code-tabs.test.ts", + "site/test/core-player.test.ts", + "site/test/csharp-layout.test.ts", + "site/test/cxx-signature.test.ts", + "site/test/dangling-report.test.ts", + "site/test/documentation-picker-interaction.test.ts", + "site/test/ec-shell-prompt.test.ts", + "site/test/example-excerpt.test.ts", + "site/test/field-members.test.ts", + "site/test/footer-external-links.test.ts", + "site/test/header-escaping.test.ts", + "site/test/header-links-interaction.test.ts", + "site/test/header-links.test.ts", + "site/test/home-description.test.ts", + "site/test/home-launcher.test.ts", + "site/test/inline-reference-appearance.test.ts", + "site/test/install-widgets.test.ts", + "site/test/link-preview-card.test.ts", + "site/test/link-preview.test.ts", + "site/test/mcp-preview.test.ts", + "site/test/mcp-prose-links.test.ts", + "site/test/mcp-protocol-sidebar.test.ts", + "site/test/mcp-replay.test.ts", + "site/test/mcp-schema.test.ts", + "site/test/mcp-showcase.test.ts", + "site/test/mention-density.test.ts", + "site/test/meta-pages.test.ts", + "site/test/native-prose-ownership.test.ts", + "site/test/native-shell-xref-kinds.test.ts", + "site/test/native-signature.test.ts", + "site/test/nuget-install.test.ts", + "site/test/parameter-permalinks.test.ts", + "site/test/port-hero.test.ts", + "site/test/port-landing-page.test.ts", + "site/test/port-links.test.ts", + "site/test/port-prose.test.ts", + "site/test/powershell-layout.test.ts", + "site/test/prerelease-notice.test.ts", + "site/test/product-api-index.test.ts", + "site/test/product-copy.test.ts", + "site/test/product-docs.test.ts", + "site/test/product-reference.test.ts", + "site/test/product-status.test.ts", + "site/test/properties-highlighting.test.ts", + "site/test/prose-text.test.ts", + "site/test/python-layout.test.ts", + "site/test/reference-previews.test.ts", + "site/test/related-labels.test.ts", + "site/test/row-anchors.test.ts", + "site/test/rust-layout.test.ts", + "site/test/sidebar-demo.test.ts", + "site/test/surface-picker-external.test.ts", + "site/test/swift-layout.test.ts", + "site/test/tmux-catalog-links.test.ts", + "site/test/tmux-library-usage.test.ts", + "site/test/tmux-links.test.ts", + "site/test/tmux-manual.test.ts", + "site/test/tmux-mentions.test.ts", + "site/test/tmux-reference.test.ts", + "site/test/tmux-usage.test.ts", + "site/test/type-alias-declaration.test.ts", + "site/test/typescript-members.test.ts", + "site/test/workspace-picker.test.ts", + "site/test/workspace-showcase.test.ts" + ] + }, + { + "reason": "Exercises actual source guides or regenerates a full catalog.", + "files": [ + "site/test/api-prose-fields.test.ts", + "site/test/complete-examples.test.ts", + "site/test/core-home.test.ts", + "site/test/link-preview-payload.test.ts", + "site/test/prose-markdown.test.ts", + "site/test/tmux-catalog.test.ts" + ] + }, + { + "reason": "Extracts a real Python source tree and compares the native inventory.", + "files": [ + "packages/api-model/test/coverage.test.ts" + ] + } + ], + "publication": [ + { + "reason": "Exhaustively audits full catalogs or renders every port, page, symbol and external link; the publication audit retains the complete corpus.", + "files": [ + "site/test/api-links-rendered.test.ts", + "site/test/literal-links.test.ts" + ] + } + ] +} diff --git a/scripts/tmux-usage/claims.json b/scripts/tmux-usage/claims.json index e22e5ab83..abbfc5114 100644 --- a/scripts/tmux-usage/claims.json +++ b/scripts/tmux-usage/claims.json @@ -15193,6 +15193,5878 @@ "in": "server.Server.kill" } ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_session", + "command": "new-session", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:967", + "has": [ + "$self->_run($self->operation('new_session', %args));" + ], + "in": "LibTmux::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:522", + "has": [ + "'new-session', '-d', '-P', '-F', _creation_format('session')," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_session", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:967", + "has": [ + "$self->_run($self->operation('new_session', %args));" + ], + "in": "LibTmux::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_session", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:967", + "has": [ + "$self->_run($self->operation('new_session', %args));" + ], + "in": "LibTmux::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_session", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:967", + "has": [ + "$self->_run($self->operation('new_session', %args));" + ], + "in": "LibTmux::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_session", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:967", + "has": [ + "$self->_run($self->operation('new_session', %args));" + ], + "in": "LibTmux::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_session", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:967", + "has": [ + "$self->_run($self->operation('new_session', %args));" + ], + "in": "LibTmux::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_window", + "command": "new-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:971", + "has": [ + "$self->_run($self->operation('new_window', %args));" + ], + "in": "LibTmux::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:547", + "has": [ + "$split ? 'split-window' : 'new-window'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_window", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:971", + "has": [ + "$self->_run($self->operation('new_window', %args));" + ], + "in": "LibTmux::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_window", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:971", + "has": [ + "$self->_run($self->operation('new_window', %args));" + ], + "in": "LibTmux::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_window", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:971", + "has": [ + "$self->_run($self->operation('new_window', %args));" + ], + "in": "LibTmux::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_window", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:971", + "has": [ + "$self->_run($self->operation('new_window', %args));" + ], + "in": "LibTmux::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::new_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:971", + "has": [ + "$self->_run($self->operation('new_window', %args));" + ], + "in": "LibTmux::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::split_pane", + "command": "split-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:975", + "has": [ + "$self->_run($self->operation('split_pane', %args));" + ], + "in": "LibTmux::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:547", + "has": [ + "$split ? 'split-window' : 'new-window'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::split_pane", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:975", + "has": [ + "$self->_run($self->operation('split_pane', %args));" + ], + "in": "LibTmux::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::split_pane", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:975", + "has": [ + "$self->_run($self->operation('split_pane', %args));" + ], + "in": "LibTmux::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::split_pane", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:975", + "has": [ + "$self->_run($self->operation('split_pane', %args));" + ], + "in": "LibTmux::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::split_pane", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:975", + "has": [ + "$self->_run($self->operation('split_pane', %args));" + ], + "in": "LibTmux::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::split_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:975", + "has": [ + "$self->_run($self->operation('split_pane', %args));" + ], + "in": "LibTmux::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::rename_session", + "command": "rename-session", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:988", + "has": [ + "$self->_run($self->operation('rename_session', %args));" + ], + "in": "LibTmux::Server::rename_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:604", + "has": [ + "['session', 'session', 'rename-session', 'name', 'format']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::rename_session", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:988", + "has": [ + "$self->_run($self->operation('rename_session', %args));" + ], + "in": "LibTmux::Server::rename_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::rename_window", + "command": "rename-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:992", + "has": [ + "$self->_run($self->operation('rename_window', %args));" + ], + "in": "LibTmux::Server::rename_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:606", + "has": [ + "['window', 'window', 'rename-window', 'name', 'format']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::rename_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:992", + "has": [ + "$self->_run($self->operation('rename_window', %args));" + ], + "in": "LibTmux::Server::rename_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::link_window", + "command": "link-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:996", + "has": [ + "$self->_run($self->operation('link_window', %args));" + ], + "in": "LibTmux::Server::link_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:577", + "has": [ + "'link-window', '-s', $window->[0], '-t'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::link_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:996", + "has": [ + "$self->_run($self->operation('link_window', %args));" + ], + "in": "LibTmux::Server::link_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::unlink_window", + "command": "unlink-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1000", + "has": [ + "$self->_run($self->operation('unlink_window', %args));" + ], + "in": "LibTmux::Server::unlink_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:607", + "has": [ + "unlink_window => ['window_link', 'link', 'unlink-window']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::unlink_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1000", + "has": [ + "$self->_run($self->operation('unlink_window', %args));" + ], + "in": "LibTmux::Server::unlink_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::move_window", + "command": "move-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1004", + "has": [ + "$self->_run($self->operation('move_window', %args));" + ], + "in": "LibTmux::Server::move_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:593", + "has": [ + "'move-window', '-s', $link->[0], '-t'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::move_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1004", + "has": [ + "$self->_run($self->operation('move_window', %args));" + ], + "in": "LibTmux::Server::move_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::select_window", + "command": "select-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1008", + "has": [ + "$self->_run($self->operation('select_window', %args));" + ], + "in": "LibTmux::Server::select_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:608", + "has": [ + "select_window => ['window_link', 'link', 'select-window']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::select_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1008", + "has": [ + "$self->_run($self->operation('select_window', %args));" + ], + "in": "LibTmux::Server::select_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::select_pane", + "command": "select-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1012", + "has": [ + "$self->_run($self->operation('select_pane', %args));" + ], + "in": "LibTmux::Server::select_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:609", + "has": [ + "select_pane => ['pane', 'pane', 'select-pane']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::select_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1012", + "has": [ + "$self->_run($self->operation('select_pane', %args));" + ], + "in": "LibTmux::Server::select_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::select_layout", + "command": "select-layout", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1016", + "has": [ + "$self->_run($self->operation('select_layout', %args));" + ], + "in": "LibTmux::Server::select_layout" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:610", + "has": [ + "select_layout => ['window', 'window', 'select-layout', 'layout']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::select_layout", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1016", + "has": [ + "$self->_run($self->operation('select_layout', %args));" + ], + "in": "LibTmux::Server::select_layout" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::resize_pane", + "command": "resize-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1020", + "has": [ + "$self->_run($self->operation('resize_pane', %args));" + ], + "in": "LibTmux::Server::resize_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:646", + "has": [ + "@argv = ('resize-pane', '-t', $target->[0]);" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::resize_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1020", + "has": [ + "$self->_run($self->operation('resize_pane', %args));" + ], + "in": "LibTmux::Server::resize_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::set_title", + "command": "select-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1024", + "has": [ + "$self->_run($self->operation('set_title', %args));" + ], + "in": "LibTmux::Server::set_title" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:609", + "has": [ + "select_pane => ['pane', 'pane', 'select-pane']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::set_title", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1024", + "has": [ + "$self->_run($self->operation('set_title', %args));" + ], + "in": "LibTmux::Server::set_title" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::send_keys", + "command": "send-keys", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1028", + "has": [ + "$self->_run($self->operation('send_keys', %args));" + ], + "in": "LibTmux::Server::send_keys" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:661", + "has": [ + "'send-keys', '-t', $target->[0], '--'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::send_keys", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1028", + "has": [ + "$self->_run($self->operation('send_keys', %args));" + ], + "in": "LibTmux::Server::send_keys" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::send_text", + "command": "send-keys", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1032", + "has": [ + "$self->_run($self->operation('send_text', %args));" + ], + "in": "LibTmux::Server::send_text" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:661", + "has": [ + "'send-keys', '-t', $target->[0], '--'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::send_text", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1032", + "has": [ + "$self->_run($self->operation('send_text', %args));" + ], + "in": "LibTmux::Server::send_text" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::capture_pane", + "command": "capture-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1036", + "has": [ + "$self->_run($self->operation('capture_pane', %args));" + ], + "in": "LibTmux::Server::capture_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:671", + "has": [ + "@argv = ('capture-pane', '-p', '-t', $target->[0]);" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::capture_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1036", + "has": [ + "$self->_run($self->operation('capture_pane', %args));" + ], + "in": "LibTmux::Server::capture_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::kill_pane", + "command": "kill-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1040", + "has": [ + "$self->_run($self->operation('kill_pane', %args));" + ], + "in": "LibTmux::Server::kill_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:611", + "has": [ + "kill_pane => ['pane', 'pane', 'kill-pane']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::kill_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1040", + "has": [ + "$self->_run($self->operation('kill_pane', %args));" + ], + "in": "LibTmux::Server::kill_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::kill_window", + "command": "kill-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1044", + "has": [ + "$self->_run($self->operation('kill_window', %args));" + ], + "in": "LibTmux::Server::kill_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:612", + "has": [ + "kill_window => ['window', 'window', 'kill-window']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::kill_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1044", + "has": [ + "$self->_run($self->operation('kill_window', %args));" + ], + "in": "LibTmux::Server::kill_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::kill_session", + "command": "kill-session", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1048", + "has": [ + "$self->_run($self->operation('kill_session', %args));" + ], + "in": "LibTmux::Server::kill_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:613", + "has": [ + "kill_session => ['session', 'session', 'kill-session']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::kill_session", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1048", + "has": [ + "$self->_run($self->operation('kill_session', %args));" + ], + "in": "LibTmux::Server::kill_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::kill_server", + "command": "kill-server", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1052", + "has": [ + "$self->_run($self->operation('kill_server', %args));" + ], + "in": "LibTmux::Server::kill_server" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:634", + "has": [ + "return $self->_cmd_op(['kill-server'])->then(sub { undef });" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::detach_client", + "command": "detach-client", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1057", + "has": [ + "$self->_run($self->operation('detach_client', %args));" + ], + "in": "LibTmux::Server::detach_client" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:614", + "has": [ + "detach_client => ['client', 'client', 'detach-client']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::detach_client", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1057", + "has": [ + "$self->_run($self->operation('detach_client', %args));" + ], + "in": "LibTmux::Server::detach_client" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::set_option", + "command": "set-option", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1061", + "has": [ + "$self->_run($self->operation('set_option', %args));" + ], + "in": "LibTmux::Server::set_option" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:697", + "has": [ + "my @argv = ($name eq 'get_option' ? 'show-options' : 'set-option');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::get_option", + "command": "show-options", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1065", + "has": [ + "$self->_run($self->operation('get_option', %args));" + ], + "in": "LibTmux::Server::get_option" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:697", + "has": [ + "my @argv = ($name eq 'get_option' ? 'show-options' : 'set-option');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::unset_option", + "command": "set-option", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1069", + "has": [ + "$self->_run($self->operation('unset_option', %args));" + ], + "in": "LibTmux::Server::unset_option" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:697", + "has": [ + "my @argv = ($name eq 'get_option' ? 'show-options' : 'set-option');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::set_hook", + "command": "set-hook", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1071", + "has": [ + "sub set_hook ($self, %args) { $self->_run($self->operation('set_hook', %args)) }" + ], + "in": "LibTmux::Server::set_hook" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:716", + "has": [ + "my @argv = ($name eq 'set_hook' ? 'set-hook' : 'show-hooks');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::show_hooks", + "command": "show-hooks", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1074", + "has": [ + "$self->_run($self->operation('show_hooks', %args));" + ], + "in": "LibTmux::Server::show_hooks" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:716", + "has": [ + "my @argv = ($name eq 'set_hook' ? 'set-hook' : 'show-hooks');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::set_environment", + "command": "set-environment", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1078", + "has": [ + "$self->_run($self->operation('set_environment', %args));" + ], + "in": "LibTmux::Server::set_environment" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:731", + "has": [ + ": 'set-environment'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::get_environment", + "command": "show-environment", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1082", + "has": [ + "$self->_run($self->operation('get_environment', %args));" + ], + "in": "LibTmux::Server::get_environment" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:730", + "has": [ + "? 'show-environment'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::unset_environment", + "command": "set-environment", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1086", + "has": [ + "$self->_run($self->operation('unset_environment', %args));" + ], + "in": "LibTmux::Server::unset_environment" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:731", + "has": [ + ": 'set-environment'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::set_buffer", + "command": "load-buffer", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1090", + "has": [ + "$self->_run($self->operation('set_buffer', %args));" + ], + "in": "LibTmux::Server::set_buffer" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:755", + "has": [ + "$name eq 'set_buffer' ? 'load-buffer'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::show_buffer", + "command": "show-buffer", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1094", + "has": [ + "$self->_run($self->operation('show_buffer', %args));" + ], + "in": "LibTmux::Server::show_buffer" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:756", + "has": [ + ": $name eq 'show_buffer' ? 'show-buffer'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::delete_buffer", + "command": "delete-buffer", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1098", + "has": [ + "$self->_run($self->operation('delete_buffer', %args));" + ], + "in": "LibTmux::Server::delete_buffer" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:757", + "has": [ + ": 'delete-buffer'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::snapshot", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:977", + "has": [ + "sub snapshot ($self, %args) { $self->_run($self->operation('snapshot', %args)) }" + ], + "in": "LibTmux::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::snapshot", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:977", + "has": [ + "sub snapshot ($self, %args) { $self->_run($self->operation('snapshot', %args)) }" + ], + "in": "LibTmux::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::snapshot", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:977", + "has": [ + "sub snapshot ($self, %args) { $self->_run($self->operation('snapshot', %args)) }" + ], + "in": "LibTmux::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::snapshot", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:977", + "has": [ + "sub snapshot ($self, %args) { $self->_run($self->operation('snapshot', %args)) }" + ], + "in": "LibTmux::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::snapshot", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:977", + "has": [ + "sub snapshot ($self, %args) { $self->_run($self->operation('snapshot', %args)) }" + ], + "in": "LibTmux::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::clients", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1054", + "has": [ + "sub clients ($self, %args) { $self->_run($self->operation('clients', %args)) }" + ], + "in": "LibTmux::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::clients", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1054", + "has": [ + "sub clients ($self, %args) { $self->_run($self->operation('clients', %args)) }" + ], + "in": "LibTmux::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::clients", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1054", + "has": [ + "sub clients ($self, %args) { $self->_run($self->operation('clients', %args)) }" + ], + "in": "LibTmux::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::clients", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1054", + "has": [ + "sub clients ($self, %args) { $self->_run($self->operation('clients', %args)) }" + ], + "in": "LibTmux::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::clients", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1054", + "has": [ + "sub clients ($self, %args) { $self->_run($self->operation('clients', %args)) }" + ], + "in": "LibTmux::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::query_panes", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:980", + "has": [ + "$self->_run($self->operation('query_panes', %args));" + ], + "in": "LibTmux::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::query_panes", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:980", + "has": [ + "$self->_run($self->operation('query_panes', %args));" + ], + "in": "LibTmux::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::query_panes", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:980", + "has": [ + "$self->_run($self->operation('query_panes', %args));" + ], + "in": "LibTmux::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::query_panes", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:980", + "has": [ + "$self->_run($self->operation('query_panes', %args));" + ], + "in": "LibTmux::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Server::query_panes", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:980", + "has": [ + "$self->_run($self->operation('query_panes', %args));" + ], + "in": "LibTmux::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::listings", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:948", + "has": [ + "$self->_run($self->operation('listings', kind => $kind));" + ], + "in": "LibTmux::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ], + "when": "kind is session", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::listings", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:948", + "has": [ + "$self->_run($self->operation('listings', kind => $kind));" + ], + "in": "LibTmux::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ], + "when": "kind is window", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::listings", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:948", + "has": [ + "$self->_run($self->operation('listings', kind => $kind));" + ], + "in": "LibTmux::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ], + "when": "kind is pane", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::listings", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:948", + "has": [ + "$self->_run($self->operation('listings', kind => $kind));" + ], + "in": "LibTmux::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ], + "when": "kind is client", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Server::listings", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:932", + "has": [ + "try { $done->(LibTmux::Transport->run(%$request)) }" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:948", + "has": [ + "$self->_run($self->operation('listings', kind => $kind));" + ], + "in": "LibTmux::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_session", + "command": "new-session", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:64", + "has": [ + "sub new_session ($self, %args) { $self->_submit('new_session', %args) }" + ], + "in": "LibTmux::Async::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:522", + "has": [ + "'new-session', '-d', '-P', '-F', _creation_format('session')," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_session", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:64", + "has": [ + "sub new_session ($self, %args) { $self->_submit('new_session', %args) }" + ], + "in": "LibTmux::Async::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_session", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:64", + "has": [ + "sub new_session ($self, %args) { $self->_submit('new_session', %args) }" + ], + "in": "LibTmux::Async::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_session", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:64", + "has": [ + "sub new_session ($self, %args) { $self->_submit('new_session', %args) }" + ], + "in": "LibTmux::Async::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_session", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:64", + "has": [ + "sub new_session ($self, %args) { $self->_submit('new_session', %args) }" + ], + "in": "LibTmux::Async::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_session", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:64", + "has": [ + "sub new_session ($self, %args) { $self->_submit('new_session', %args) }" + ], + "in": "LibTmux::Async::Server::new_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_window", + "command": "new-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:65", + "has": [ + "sub new_window ($self, %args) { $self->_submit('new_window', %args) }" + ], + "in": "LibTmux::Async::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:547", + "has": [ + "$split ? 'split-window' : 'new-window'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_window", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:65", + "has": [ + "sub new_window ($self, %args) { $self->_submit('new_window', %args) }" + ], + "in": "LibTmux::Async::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_window", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:65", + "has": [ + "sub new_window ($self, %args) { $self->_submit('new_window', %args) }" + ], + "in": "LibTmux::Async::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_window", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:65", + "has": [ + "sub new_window ($self, %args) { $self->_submit('new_window', %args) }" + ], + "in": "LibTmux::Async::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_window", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:65", + "has": [ + "sub new_window ($self, %args) { $self->_submit('new_window', %args) }" + ], + "in": "LibTmux::Async::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::new_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:65", + "has": [ + "sub new_window ($self, %args) { $self->_submit('new_window', %args) }" + ], + "in": "LibTmux::Async::Server::new_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::split_pane", + "command": "split-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:66", + "has": [ + "sub split_pane ($self, %args) { $self->_submit('split_pane', %args) }" + ], + "in": "LibTmux::Async::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:547", + "has": [ + "$split ? 'split-window' : 'new-window'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::split_pane", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:66", + "has": [ + "sub split_pane ($self, %args) { $self->_submit('split_pane', %args) }" + ], + "in": "LibTmux::Async::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::split_pane", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:66", + "has": [ + "sub split_pane ($self, %args) { $self->_submit('split_pane', %args) }" + ], + "in": "LibTmux::Async::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::split_pane", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:66", + "has": [ + "sub split_pane ($self, %args) { $self->_submit('split_pane', %args) }" + ], + "in": "LibTmux::Async::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::split_pane", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:66", + "has": [ + "sub split_pane ($self, %args) { $self->_submit('split_pane', %args) }" + ], + "in": "LibTmux::Async::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ], + "when": "after accepted creation", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::split_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:66", + "has": [ + "sub split_pane ($self, %args) { $self->_submit('split_pane', %args) }" + ], + "in": "LibTmux::Async::Server::split_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::rename_session", + "command": "rename-session", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:70", + "has": [ + "sub rename_session ($self, %args) { $self->_submit('rename_session', %args) }" + ], + "in": "LibTmux::Async::Server::rename_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:604", + "has": [ + "['session', 'session', 'rename-session', 'name', 'format']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::rename_session", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:70", + "has": [ + "sub rename_session ($self, %args) { $self->_submit('rename_session', %args) }" + ], + "in": "LibTmux::Async::Server::rename_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::rename_window", + "command": "rename-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:71", + "has": [ + "sub rename_window ($self, %args) { $self->_submit('rename_window', %args) }" + ], + "in": "LibTmux::Async::Server::rename_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:606", + "has": [ + "['window', 'window', 'rename-window', 'name', 'format']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::rename_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:71", + "has": [ + "sub rename_window ($self, %args) { $self->_submit('rename_window', %args) }" + ], + "in": "LibTmux::Async::Server::rename_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::link_window", + "command": "link-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:72", + "has": [ + "sub link_window ($self, %args) { $self->_submit('link_window', %args) }" + ], + "in": "LibTmux::Async::Server::link_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:577", + "has": [ + "'link-window', '-s', $window->[0], '-t'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::link_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:72", + "has": [ + "sub link_window ($self, %args) { $self->_submit('link_window', %args) }" + ], + "in": "LibTmux::Async::Server::link_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::unlink_window", + "command": "unlink-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:73", + "has": [ + "sub unlink_window ($self, %args) { $self->_submit('unlink_window', %args) }" + ], + "in": "LibTmux::Async::Server::unlink_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:607", + "has": [ + "unlink_window => ['window_link', 'link', 'unlink-window']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::unlink_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:73", + "has": [ + "sub unlink_window ($self, %args) { $self->_submit('unlink_window', %args) }" + ], + "in": "LibTmux::Async::Server::unlink_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::move_window", + "command": "move-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:74", + "has": [ + "sub move_window ($self, %args) { $self->_submit('move_window', %args) }" + ], + "in": "LibTmux::Async::Server::move_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:593", + "has": [ + "'move-window', '-s', $link->[0], '-t'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::move_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:74", + "has": [ + "sub move_window ($self, %args) { $self->_submit('move_window', %args) }" + ], + "in": "LibTmux::Async::Server::move_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::select_window", + "command": "select-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:75", + "has": [ + "sub select_window ($self, %args) { $self->_submit('select_window', %args) }" + ], + "in": "LibTmux::Async::Server::select_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:608", + "has": [ + "select_window => ['window_link', 'link', 'select-window']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::select_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:75", + "has": [ + "sub select_window ($self, %args) { $self->_submit('select_window', %args) }" + ], + "in": "LibTmux::Async::Server::select_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::select_pane", + "command": "select-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:76", + "has": [ + "sub select_pane ($self, %args) { $self->_submit('select_pane', %args) }" + ], + "in": "LibTmux::Async::Server::select_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:609", + "has": [ + "select_pane => ['pane', 'pane', 'select-pane']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::select_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:76", + "has": [ + "sub select_pane ($self, %args) { $self->_submit('select_pane', %args) }" + ], + "in": "LibTmux::Async::Server::select_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::select_layout", + "command": "select-layout", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:77", + "has": [ + "sub select_layout ($self, %args) { $self->_submit('select_layout', %args) }" + ], + "in": "LibTmux::Async::Server::select_layout" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:610", + "has": [ + "select_layout => ['window', 'window', 'select-layout', 'layout']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::select_layout", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:77", + "has": [ + "sub select_layout ($self, %args) { $self->_submit('select_layout', %args) }" + ], + "in": "LibTmux::Async::Server::select_layout" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::resize_pane", + "command": "resize-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:78", + "has": [ + "sub resize_pane ($self, %args) { $self->_submit('resize_pane', %args) }" + ], + "in": "LibTmux::Async::Server::resize_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:646", + "has": [ + "@argv = ('resize-pane', '-t', $target->[0]);" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::resize_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:78", + "has": [ + "sub resize_pane ($self, %args) { $self->_submit('resize_pane', %args) }" + ], + "in": "LibTmux::Async::Server::resize_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::set_title", + "command": "select-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:79", + "has": [ + "sub set_title ($self, %args) { $self->_submit('set_title', %args) }" + ], + "in": "LibTmux::Async::Server::set_title" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:609", + "has": [ + "select_pane => ['pane', 'pane', 'select-pane']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::set_title", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:79", + "has": [ + "sub set_title ($self, %args) { $self->_submit('set_title', %args) }" + ], + "in": "LibTmux::Async::Server::set_title" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::send_keys", + "command": "send-keys", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:80", + "has": [ + "sub send_keys ($self, %args) { $self->_submit('send_keys', %args) }" + ], + "in": "LibTmux::Async::Server::send_keys" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:661", + "has": [ + "'send-keys', '-t', $target->[0], '--'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::send_keys", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:80", + "has": [ + "sub send_keys ($self, %args) { $self->_submit('send_keys', %args) }" + ], + "in": "LibTmux::Async::Server::send_keys" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::send_text", + "command": "send-keys", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:81", + "has": [ + "sub send_text ($self, %args) { $self->_submit('send_text', %args) }" + ], + "in": "LibTmux::Async::Server::send_text" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:661", + "has": [ + "'send-keys', '-t', $target->[0], '--'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::send_text", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:81", + "has": [ + "sub send_text ($self, %args) { $self->_submit('send_text', %args) }" + ], + "in": "LibTmux::Async::Server::send_text" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::capture_pane", + "command": "capture-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:82", + "has": [ + "sub capture_pane ($self, %args) { $self->_submit('capture_pane', %args) }" + ], + "in": "LibTmux::Async::Server::capture_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:671", + "has": [ + "@argv = ('capture-pane', '-p', '-t', $target->[0]);" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::capture_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:82", + "has": [ + "sub capture_pane ($self, %args) { $self->_submit('capture_pane', %args) }" + ], + "in": "LibTmux::Async::Server::capture_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::kill_pane", + "command": "kill-pane", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:83", + "has": [ + "sub kill_pane ($self, %args) { $self->_submit('kill_pane', %args) }" + ], + "in": "LibTmux::Async::Server::kill_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:611", + "has": [ + "kill_pane => ['pane', 'pane', 'kill-pane']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::kill_pane", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:83", + "has": [ + "sub kill_pane ($self, %args) { $self->_submit('kill_pane', %args) }" + ], + "in": "LibTmux::Async::Server::kill_pane" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::kill_window", + "command": "kill-window", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:84", + "has": [ + "sub kill_window ($self, %args) { $self->_submit('kill_window', %args) }" + ], + "in": "LibTmux::Async::Server::kill_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:612", + "has": [ + "kill_window => ['window', 'window', 'kill-window']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::kill_window", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:84", + "has": [ + "sub kill_window ($self, %args) { $self->_submit('kill_window', %args) }" + ], + "in": "LibTmux::Async::Server::kill_window" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::kill_session", + "command": "kill-session", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:85", + "has": [ + "sub kill_session ($self, %args) { $self->_submit('kill_session', %args) }" + ], + "in": "LibTmux::Async::Server::kill_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:613", + "has": [ + "kill_session => ['session', 'session', 'kill-session']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::kill_session", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:85", + "has": [ + "sub kill_session ($self, %args) { $self->_submit('kill_session', %args) }" + ], + "in": "LibTmux::Async::Server::kill_session" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::kill_server", + "command": "kill-server", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:86", + "has": [ + "sub kill_server ($self, %args) { $self->_submit('kill_server', %args) }" + ], + "in": "LibTmux::Async::Server::kill_server" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:634", + "has": [ + "return $self->_cmd_op(['kill-server'])->then(sub { undef });" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::detach_client", + "command": "detach-client", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:89", + "has": [ + "sub detach_client ($self, %args) { $self->_submit('detach_client', %args) }" + ], + "in": "LibTmux::Async::Server::detach_client" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:614", + "has": [ + "detach_client => ['client', 'client', 'detach-client']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::detach_client", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:89", + "has": [ + "sub detach_client ($self, %args) { $self->_submit('detach_client', %args) }" + ], + "in": "LibTmux::Async::Server::detach_client" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::set_option", + "command": "set-option", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:90", + "has": [ + "sub set_option ($self, %args) { $self->_submit('set_option', %args) }" + ], + "in": "LibTmux::Async::Server::set_option" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:697", + "has": [ + "my @argv = ($name eq 'get_option' ? 'show-options' : 'set-option');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::get_option", + "command": "show-options", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:91", + "has": [ + "sub get_option ($self, %args) { $self->_submit('get_option', %args) }" + ], + "in": "LibTmux::Async::Server::get_option" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:697", + "has": [ + "my @argv = ($name eq 'get_option' ? 'show-options' : 'set-option');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::unset_option", + "command": "set-option", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:92", + "has": [ + "sub unset_option ($self, %args) { $self->_submit('unset_option', %args) }" + ], + "in": "LibTmux::Async::Server::unset_option" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:697", + "has": [ + "my @argv = ($name eq 'get_option' ? 'show-options' : 'set-option');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::set_hook", + "command": "set-hook", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:93", + "has": [ + "sub set_hook ($self, %args) { $self->_submit('set_hook', %args) }" + ], + "in": "LibTmux::Async::Server::set_hook" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:716", + "has": [ + "my @argv = ($name eq 'set_hook' ? 'set-hook' : 'show-hooks');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::show_hooks", + "command": "show-hooks", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:94", + "has": [ + "sub show_hooks ($self, %args) { $self->_submit('show_hooks', %args) }" + ], + "in": "LibTmux::Async::Server::show_hooks" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:716", + "has": [ + "my @argv = ($name eq 'set_hook' ? 'set-hook' : 'show-hooks');" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::set_environment", + "command": "set-environment", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:95", + "has": [ + "sub set_environment ($self, %args) { $self->_submit('set_environment', %args) }" + ], + "in": "LibTmux::Async::Server::set_environment" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:731", + "has": [ + ": 'set-environment'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::get_environment", + "command": "show-environment", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:96", + "has": [ + "sub get_environment ($self, %args) { $self->_submit('get_environment', %args) }" + ], + "in": "LibTmux::Async::Server::get_environment" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:730", + "has": [ + "? 'show-environment'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::unset_environment", + "command": "set-environment", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:99", + "has": [ + "$self->_submit('unset_environment', %args);" + ], + "in": "LibTmux::Async::Server::unset_environment" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:731", + "has": [ + ": 'set-environment'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::set_buffer", + "command": "load-buffer", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:101", + "has": [ + "sub set_buffer ($self, %args) { $self->_submit('set_buffer', %args) }" + ], + "in": "LibTmux::Async::Server::set_buffer" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:755", + "has": [ + "$name eq 'set_buffer' ? 'load-buffer'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::show_buffer", + "command": "show-buffer", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:102", + "has": [ + "sub show_buffer ($self, %args) { $self->_submit('show_buffer', %args) }" + ], + "in": "LibTmux::Async::Server::show_buffer" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:756", + "has": [ + ": $name eq 'show_buffer' ? 'show-buffer'" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::delete_buffer", + "command": "delete-buffer", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:103", + "has": [ + "sub delete_buffer ($self, %args) { $self->_submit('delete_buffer', %args) }" + ], + "in": "LibTmux::Async::Server::delete_buffer" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:757", + "has": [ + ": 'delete-buffer'," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::snapshot", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:67", + "has": [ + "sub snapshot ($self, %args) { $self->_submit('snapshot', %args) }" + ], + "in": "LibTmux::Async::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::snapshot", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:67", + "has": [ + "sub snapshot ($self, %args) { $self->_submit('snapshot', %args) }" + ], + "in": "LibTmux::Async::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::snapshot", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:67", + "has": [ + "sub snapshot ($self, %args) { $self->_submit('snapshot', %args) }" + ], + "in": "LibTmux::Async::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::snapshot", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:67", + "has": [ + "sub snapshot ($self, %args) { $self->_submit('snapshot', %args) }" + ], + "in": "LibTmux::Async::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::snapshot", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:67", + "has": [ + "sub snapshot ($self, %args) { $self->_submit('snapshot', %args) }" + ], + "in": "LibTmux::Async::Server::snapshot" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::clients", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:87", + "has": [ + "sub clients ($self, %args) { $self->_submit('clients', %args) }" + ], + "in": "LibTmux::Async::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::clients", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:87", + "has": [ + "sub clients ($self, %args) { $self->_submit('clients', %args) }" + ], + "in": "LibTmux::Async::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::clients", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:87", + "has": [ + "sub clients ($self, %args) { $self->_submit('clients', %args) }" + ], + "in": "LibTmux::Async::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::clients", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:87", + "has": [ + "sub clients ($self, %args) { $self->_submit('clients', %args) }" + ], + "in": "LibTmux::Async::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::clients", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:87", + "has": [ + "sub clients ($self, %args) { $self->_submit('clients', %args) }" + ], + "in": "LibTmux::Async::Server::clients" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::query_panes", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:68", + "has": [ + "sub query_panes ($self, %args) { $self->_submit('query_panes', %args) }" + ], + "in": "LibTmux::Async::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::query_panes", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:68", + "has": [ + "sub query_panes ($self, %args) { $self->_submit('query_panes', %args) }" + ], + "in": "LibTmux::Async::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::query_panes", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:68", + "has": [ + "sub query_panes ($self, %args) { $self->_submit('query_panes', %args) }" + ], + "in": "LibTmux::Async::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::query_panes", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:68", + "has": [ + "sub query_panes ($self, %args) { $self->_submit('query_panes', %args) }" + ], + "in": "LibTmux::Async::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ] + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::query_panes", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:68", + "has": [ + "sub query_panes ($self, %args) { $self->_submit('query_panes', %args) }" + ], + "in": "LibTmux::Async::Server::query_panes" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::listings", + "command": "list-sessions", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:61", + "has": [ + "sub listings ($self, $kind) { $self->_submit('listings', kind => $kind) }" + ], + "in": "LibTmux::Async::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:154", + "has": [ + "session => ['list-sessions']," + ] + } + ], + "when": "kind is session", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::listings", + "command": "list-windows", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:61", + "has": [ + "sub listings ($self, $kind) { $self->_submit('listings', kind => $kind) }" + ], + "in": "LibTmux::Async::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:155", + "has": [ + "window => ['list-windows', '-a']," + ] + } + ], + "when": "kind is window", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::listings", + "command": "list-panes", + "scope": "server", + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:61", + "has": [ + "sub listings ($self, $kind) { $self->_submit('listings', kind => $kind) }" + ], + "in": "LibTmux::Async::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:156", + "has": [ + "pane => ['list-panes', '-a']," + ] + } + ], + "when": "kind is pane", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::listings", + "command": "list-clients", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:61", + "has": [ + "sub listings ($self, $kind) { $self->_submit('listings', kind => $kind) }" + ], + "in": "LibTmux::Async::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:157", + "has": [ + "client => ['list-clients']" + ] + } + ], + "when": "kind is client", + "conditional": true + }, + { + "port": "perl", + "symbol": "LibTmux::Async::Server::listings", + "command": "display-message", + "scope": null, + "why": "Reviewed dynamic Operation preparation and the facade executor; the command literal is not treated as dispatch by itself.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:42", + "has": [ + "my $request_future = $self->{transport}->execute(%$request);" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:845", + "has": [ + "my $operation = $self->_prepare($name, %args);" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:61", + "has": [ + "sub listings ($self, $kind) { $self->_submit('listings', kind => $kind) }" + ], + "in": "LibTmux::Async::Server::listings" + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:130", + "has": [ + "return $self->_cmd_op(['display-message', '-p', $format])->then(" + ] + } + ], + "when": "daemon identity or target preflight", + "conditional": true } ] } diff --git a/scripts/tmux-usage/not-senders.json b/scripts/tmux-usage/not-senders.json index 9cd6ced5a..c4968d45c 100644 --- a/scripts/tmux-usage/not-senders.json +++ b/scripts/tmux-usage/not-senders.json @@ -4557,6 +4557,168 @@ ] } ] + }, + { + "port": "perl", + "ownerSuffix": "Selection", + "names": [ + "new" + ], + "kind": "values", + "why": "Concrete Selection constructors bless and validate native array membership. They create no session, window, pane, process, or transport.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Selection.pm:8", + "has": [ + "my $self = bless \\@items, $class;" + ] + }, + { + "at": "packages/core/lib/LibTmux/Selection.pm:9", + "has": [ + "$self->_validate;" + ] + } + ] + }, + { + "port": "perl", + "owner": "Server", + "names": [ + "close" + ], + "in": "packages/async/", + "commands": [ + "kill-server" + ], + "kind": "no-send", + "why": "Async close cancels pending operations and closes its owned transport. It never requests daemon destruction.", + "evidence": [ + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:57", + "has": [ + "$_->cancel for values $self->{operations}->%*;" + ] + }, + { + "at": "packages/async/lib/LibTmux/Async/Server.pm:58", + "has": [ + "return $self->{transport}->close;" + ] + } + ] + }, + { + "port": "perl", + "owner": "Server", + "names": [ + "delete_buffer" + ], + "commands": [ + "kill-server" + ], + "kind": "other-command", + "why": "The selected operation deletes one named buffer; it does not send kill-server.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:757", + "has": [ + ": 'delete-buffer'," + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:1098", + "has": [ + "$self->_run($self->operation('delete_buffer', %args));" + ] + } + ] + }, + { + "port": "perl", + "owner": "Server", + "names": [ + "set_buffer" + ], + "commands": [ + "set-buffer" + ], + "kind": "other-command", + "why": "set_buffer uses load-buffer with stdin bytes. It does not use the distinct native set-buffer argument interface.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Server.pm:755", + "has": [ + "$name eq 'set_buffer' ? 'load-buffer'" + ] + }, + { + "at": "packages/core/lib/LibTmux/Server.pm:762", + "has": [ + "$name eq 'set_buffer' ? (stdin => $args{data}) : ())->then(" + ] + } + ] + }, + { + "port": "perl", + "owner": "Session", + "names": [ + "window_links" + ], + "commands": [ + "link-window" + ], + "kind": "values", + "why": "This accessor reads captured graph membership locally; link_window on Server performs the separate tmux mutation.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Session.pm:10", + "has": [ + "sub window_links ($self) { $self->_read('window_links') }" + ] + } + ] + }, + { + "port": "perl", + "owner": "Snapshot", + "names": [ + "window_links" + ], + "commands": [ + "link-window" + ], + "kind": "values", + "why": "This accessor reads captured graph membership locally; link_window on Server performs the separate tmux mutation.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Snapshot.pm:207", + "has": [ + "sub window_links ($self) { $self->_selection('window_link') }" + ] + } + ] + }, + { + "port": "perl", + "owner": "Window", + "names": [ + "links" + ], + "commands": [ + "link-window" + ], + "kind": "values", + "why": "This accessor reads captured graph membership locally; link_window on Server performs the separate tmux mutation.", + "evidence": [ + { + "at": "packages/core/lib/LibTmux/Window.pm:9", + "has": [ + "sub links ($self) { $self->_read('links') }" + ] + } + ] } ] } diff --git a/site/public/_shell/brand.css b/site/public/_shell/brand.css index cfdcb30bd..a256d21d2 100644 --- a/site/public/_shell/brand.css +++ b/site/public/_shell/brand.css @@ -1999,3 +1999,128 @@ html[data-brand="elixir"][data-theme-mode="dark"], html[data-brand="elixir"][dat --lt-color-code-bg: #1c2229; } } +html[data-brand="perl"] { + color-scheme: light; + --brand-color: #0298C3; + --brand-solid: #045c77; + --brand-on-solid: #ffffff; + --button-bg-primary: #045c77; + --button-text-primary: #ffffff; + --theme-primary: #045c77; + --theme-secondary: #53606d; + --theme-accent: #045c77; + --theme-background: #fafbfc; + --theme-text: #202830; + --background-color: #fafbfc; + --text-color: #202830; + --topnav-background: #fafbfc; + --topnav-text-color: #202830; + --topnav-link-color: #53606d; + --topnav-link-hover-color: #202830; + --color-background-primary: #fafbfc; + --color-background-secondary: #f3f5f7; + --color-background-border: #d6dce3; + --color-api-background-hover: #e9edf1; + --color-foreground-primary: #202830; + --color-foreground-secondary: #53606d; + --color-foreground-muted: #53606d; + --color-link: #045c77; + --color-brand-primary: #045c77; + --color-brand-content: #045c77; + --color-inline-code-background: #f3f5f7; + --lt-color-bg: #fafbfc; + --lt-color-bg-secondary: #f3f5f7; + --lt-color-bg-hover: #e9edf1; + --lt-color-fg: #202830; + --lt-color-fg-secondary: #53606d; + --lt-color-fg-muted: #53606d; + --lt-color-border: #d6dce3; + --lt-color-accent: #045c77; + --lt-color-link: #045c77; + --lt-color-link-visited: #045c77; + --lt-color-code-bg: #f3f5f7; +} +html[data-brand="perl"][data-theme-mode="dark"], html[data-brand="perl"][data-theme="dark"] { + color-scheme: dark; + --brand-color: #0298C3; + --brand-solid: #045c77; + --brand-on-solid: #ffffff; + --button-bg-primary: #045c77; + --button-text-primary: #ffffff; + --theme-primary: #a6def0; + --theme-secondary: #b7c1cd; + --theme-accent: #a6def0; + --theme-background: #15191d; + --theme-text: #e7edf3; + --background-color: #15191d; + --text-color: #e7edf3; + --topnav-background: #15191d; + --topnav-text-color: #e7edf3; + --topnav-link-color: #b7c1cd; + --topnav-link-hover-color: #e7edf3; + --color-background-primary: #15191d; + --color-background-secondary: #1c2229; + --color-background-border: #3e4a57; + --color-api-background-hover: #29323d; + --color-foreground-primary: #e7edf3; + --color-foreground-secondary: #b7c1cd; + --color-foreground-muted: #b7c1cd; + --color-link: #a6def0; + --color-brand-primary: #a6def0; + --color-brand-content: #a6def0; + --color-inline-code-background: #1c2229; + --lt-color-bg: #15191d; + --lt-color-bg-secondary: #1c2229; + --lt-color-bg-hover: #29323d; + --lt-color-fg: #e7edf3; + --lt-color-fg-secondary: #b7c1cd; + --lt-color-fg-muted: #b7c1cd; + --lt-color-border: #3e4a57; + --lt-color-accent: #a6def0; + --lt-color-link: #a6def0; + --lt-color-link-visited: #a6def0; + --lt-color-code-bg: #1c2229; +} +@media (prefers-color-scheme: dark) { + html[data-brand="perl"]:not([data-theme-mode]):not([data-theme="light"]) { + color-scheme: dark; + --brand-color: #0298C3; + --brand-solid: #045c77; + --brand-on-solid: #ffffff; + --button-bg-primary: #045c77; + --button-text-primary: #ffffff; + --theme-primary: #a6def0; + --theme-secondary: #b7c1cd; + --theme-accent: #a6def0; + --theme-background: #15191d; + --theme-text: #e7edf3; + --background-color: #15191d; + --text-color: #e7edf3; + --topnav-background: #15191d; + --topnav-text-color: #e7edf3; + --topnav-link-color: #b7c1cd; + --topnav-link-hover-color: #e7edf3; + --color-background-primary: #15191d; + --color-background-secondary: #1c2229; + --color-background-border: #3e4a57; + --color-api-background-hover: #29323d; + --color-foreground-primary: #e7edf3; + --color-foreground-secondary: #b7c1cd; + --color-foreground-muted: #b7c1cd; + --color-link: #a6def0; + --color-brand-primary: #a6def0; + --color-brand-content: #a6def0; + --color-inline-code-background: #1c2229; + --lt-color-bg: #15191d; + --lt-color-bg-secondary: #1c2229; + --lt-color-bg-hover: #29323d; + --lt-color-fg: #e7edf3; + --lt-color-fg-secondary: #b7c1cd; + --lt-color-fg-muted: #b7c1cd; + --lt-color-border: #3e4a57; + --lt-color-accent: #a6def0; + --lt-color-link: #a6def0; + --lt-color-link-visited: #a6def0; + --lt-color-code-bg: #1c2229; + } +} diff --git a/site/public/_shell/shell.js b/site/public/_shell/shell.js index c9779493e..c49ae27c0 100644 --- a/site/public/_shell/shell.js +++ b/site/public/_shell/shell.js @@ -20,6 +20,7 @@ {"slug":"fsharp","name":"F#","shortName":"F#","logoLanguage":"fsharp","versionedDocs":true,"mcp":false}, {"slug":"cxx","name":"C++","shortName":"C++","logoLanguage":"cpp","versionedDocs":true,"mcp":true}, {"slug":"swift","name":"Swift","shortName":"Sw","logoLanguage":"swift","versionedDocs":true,"mcp":true}, + {"slug":"perl","name":"Perl","shortName":"Pl","logoLanguage":"perl","versionedDocs":true,"mcp":false}, ] // <<< end generated diff --git a/site/public/brand/catalog.json b/site/public/brand/catalog.json index fc11e07b2..d9c24da6b 100644 --- a/site/public/brand/catalog.json +++ b/site/public/brand/catalog.json @@ -99,6 +99,11 @@ "id": "elixir", "label": "Elixir", "githubColor": "#8847B9" + }, + { + "id": "perl", + "label": "Perl", + "githubColor": "#0298C3" } ], "variants": [ @@ -523,7 +528,7 @@ "label": "Python", "variant": "workspace", "githubColor": "#3572A5", - "alt": "libtmux for Python — workspace CLI", + "alt": "libtmux for Python \u2014 workspace CLI", "files": [ { "file": "python/workspace/logo.svg", @@ -934,7 +939,7 @@ "label": "Python", "variant": "mcp", "githubColor": "#3572A5", - "alt": "libtmux for Python — MCP", + "alt": "libtmux for Python \u2014 MCP", "files": [ { "file": "python/mcp/logo.svg", @@ -1756,7 +1761,7 @@ "label": "TypeScript", "variant": "workspace", "githubColor": "#3178C6", - "alt": "libtmux for TypeScript — workspace CLI", + "alt": "libtmux for TypeScript \u2014 workspace CLI", "files": [ { "file": "typescript/workspace/logo.svg", @@ -2167,7 +2172,7 @@ "label": "TypeScript", "variant": "mcp", "githubColor": "#3178C6", - "alt": "libtmux for TypeScript — MCP", + "alt": "libtmux for TypeScript \u2014 MCP", "files": [ { "file": "typescript/mcp/logo.svg", @@ -2989,7 +2994,7 @@ "label": "Rust", "variant": "workspace", "githubColor": "#DEA584", - "alt": "libtmux for Rust — workspace CLI", + "alt": "libtmux for Rust \u2014 workspace CLI", "files": [ { "file": "rust/workspace/logo.svg", @@ -3400,7 +3405,7 @@ "label": "Rust", "variant": "mcp", "githubColor": "#DEA584", - "alt": "libtmux for Rust — MCP", + "alt": "libtmux for Rust \u2014 MCP", "files": [ { "file": "rust/mcp/logo.svg", @@ -4222,7 +4227,7 @@ "label": "Go", "variant": "workspace", "githubColor": "#00ADD8", - "alt": "libtmux for Go — workspace CLI", + "alt": "libtmux for Go \u2014 workspace CLI", "files": [ { "file": "go/workspace/logo.svg", @@ -4633,7 +4638,7 @@ "label": "Go", "variant": "mcp", "githubColor": "#00ADD8", - "alt": "libtmux for Go — MCP", + "alt": "libtmux for Go \u2014 MCP", "files": [ { "file": "go/mcp/logo.svg", @@ -5455,7 +5460,7 @@ "label": "Java", "variant": "workspace", "githubColor": "#B07219", - "alt": "libtmux for Java — workspace CLI", + "alt": "libtmux for Java \u2014 workspace CLI", "files": [ { "file": "java/workspace/logo.svg", @@ -5866,7 +5871,7 @@ "label": "Java", "variant": "mcp", "githubColor": "#B07219", - "alt": "libtmux for Java — MCP", + "alt": "libtmux for Java \u2014 MCP", "files": [ { "file": "java/mcp/logo.svg", @@ -6688,7 +6693,7 @@ "label": "C# / .NET", "variant": "workspace", "githubColor": "#7355DD", - "alt": "libtmux for C# / .NET — workspace CLI", + "alt": "libtmux for C# / .NET \u2014 workspace CLI", "files": [ { "file": "csharp/workspace/logo.svg", @@ -7099,7 +7104,7 @@ "label": "C# / .NET", "variant": "mcp", "githubColor": "#7355DD", - "alt": "libtmux for C# / .NET — MCP", + "alt": "libtmux for C# / .NET \u2014 MCP", "files": [ { "file": "csharp/mcp/logo.svg", @@ -7921,7 +7926,7 @@ "label": "C++", "variant": "workspace", "githubColor": "#F34B7D", - "alt": "libtmux for C++ — workspace CLI", + "alt": "libtmux for C++ \u2014 workspace CLI", "files": [ { "file": "cpp/workspace/logo.svg", @@ -8332,7 +8337,7 @@ "label": "C++", "variant": "mcp", "githubColor": "#F34B7D", - "alt": "libtmux for C++ — MCP", + "alt": "libtmux for C++ \u2014 MCP", "files": [ { "file": "cpp/mcp/logo.svg", @@ -9154,7 +9159,7 @@ "label": "Swift", "variant": "workspace", "githubColor": "#F05138", - "alt": "libtmux for Swift — workspace CLI", + "alt": "libtmux for Swift \u2014 workspace CLI", "files": [ { "file": "swift/workspace/logo.svg", @@ -9565,7 +9570,7 @@ "label": "Swift", "variant": "mcp", "githubColor": "#F05138", - "alt": "libtmux for Swift — MCP", + "alt": "libtmux for Swift \u2014 MCP", "files": [ { "file": "swift/mcp/logo.svg", @@ -10387,7 +10392,7 @@ "label": "Julia", "variant": "workspace", "githubColor": "#A270BA", - "alt": "libtmux for Julia — workspace CLI", + "alt": "libtmux for Julia \u2014 workspace CLI", "files": [ { "file": "julia/workspace/logo.svg", @@ -10798,7 +10803,7 @@ "label": "Julia", "variant": "mcp", "githubColor": "#A270BA", - "alt": "libtmux for Julia — MCP", + "alt": "libtmux for Julia \u2014 MCP", "files": [ { "file": "julia/mcp/logo.svg", @@ -11620,7 +11625,7 @@ "label": "Ruby", "variant": "workspace", "githubColor": "#701516", - "alt": "libtmux for Ruby — workspace CLI", + "alt": "libtmux for Ruby \u2014 workspace CLI", "files": [ { "file": "ruby/workspace/logo.svg", @@ -12031,7 +12036,7 @@ "label": "Ruby", "variant": "mcp", "githubColor": "#701516", - "alt": "libtmux for Ruby — MCP", + "alt": "libtmux for Ruby \u2014 MCP", "files": [ { "file": "ruby/mcp/logo.svg", @@ -12853,7 +12858,7 @@ "label": "Lua", "variant": "workspace", "githubColor": "#000080", - "alt": "libtmux for Lua — workspace CLI", + "alt": "libtmux for Lua \u2014 workspace CLI", "files": [ { "file": "lua/workspace/logo.svg", @@ -13264,7 +13269,7 @@ "label": "Lua", "variant": "mcp", "githubColor": "#000080", - "alt": "libtmux for Lua — MCP", + "alt": "libtmux for Lua \u2014 MCP", "files": [ { "file": "lua/mcp/logo.svg", @@ -14086,7 +14091,7 @@ "label": "PowerShell", "variant": "workspace", "githubColor": "#012456", - "alt": "libtmux for PowerShell — workspace CLI", + "alt": "libtmux for PowerShell \u2014 workspace CLI", "files": [ { "file": "powershell/workspace/logo.svg", @@ -14497,7 +14502,7 @@ "label": "PowerShell", "variant": "mcp", "githubColor": "#012456", - "alt": "libtmux for PowerShell — MCP", + "alt": "libtmux for PowerShell \u2014 MCP", "files": [ { "file": "powershell/mcp/logo.svg", @@ -15319,7 +15324,7 @@ "label": "F#", "variant": "workspace", "githubColor": "#B845FC", - "alt": "libtmux for F# — workspace CLI", + "alt": "libtmux for F# \u2014 workspace CLI", "files": [ { "file": "fsharp/workspace/logo.svg", @@ -15730,7 +15735,7 @@ "label": "F#", "variant": "mcp", "githubColor": "#B845FC", - "alt": "libtmux for F# — MCP", + "alt": "libtmux for F# \u2014 MCP", "files": [ { "file": "fsharp/mcp/logo.svg", @@ -16552,7 +16557,7 @@ "label": "Scala", "variant": "workspace", "githubColor": "#C22D40", - "alt": "libtmux for Scala — workspace CLI", + "alt": "libtmux for Scala \u2014 workspace CLI", "files": [ { "file": "scala/workspace/logo.svg", @@ -16963,7 +16968,7 @@ "label": "Scala", "variant": "mcp", "githubColor": "#C22D40", - "alt": "libtmux for Scala — MCP", + "alt": "libtmux for Scala \u2014 MCP", "files": [ { "file": "scala/mcp/logo.svg", @@ -17785,7 +17790,7 @@ "label": "Kotlin", "variant": "workspace", "githubColor": "#A97BFF", - "alt": "libtmux for Kotlin — workspace CLI", + "alt": "libtmux for Kotlin \u2014 workspace CLI", "files": [ { "file": "kotlin/workspace/logo.svg", @@ -18196,7 +18201,7 @@ "label": "Kotlin", "variant": "mcp", "githubColor": "#A97BFF", - "alt": "libtmux for Kotlin — MCP", + "alt": "libtmux for Kotlin \u2014 MCP", "files": [ { "file": "kotlin/mcp/logo.svg", @@ -19018,7 +19023,7 @@ "label": "Elixir", "variant": "workspace", "githubColor": "#8847B9", - "alt": "libtmux for Elixir — workspace CLI", + "alt": "libtmux for Elixir \u2014 workspace CLI", "files": [ { "file": "elixir/workspace/logo.svg", @@ -19429,7 +19434,7 @@ "label": "Elixir", "variant": "mcp", "githubColor": "#8847B9", - "alt": "libtmux for Elixir — MCP", + "alt": "libtmux for Elixir \u2014 MCP", "files": [ { "file": "elixir/mcp/logo.svg", @@ -19834,7 +19839,869 @@ "format": "xml" } ] + }, + { + "language": "perl", + "label": "Perl", + "variant": "library", + "githubColor": "#0298C3", + "alt": "libtmux for Perl", + "files": [ + { + "file": "perl/library/logo.svg", + "bytes": 5879, + "sha256": "fb883566770f75fb14d24c7ff8d5191ead3eadc5ba33dbcd619ad09dd8cda066", + "format": "svg", + "width": 512, + "height": 512, + "transparent": true + }, + { + "file": "perl/library/logo-16.png", + "bytes": 588, + "sha256": "e90c65b8399355ad7fdf1461e5d11d2d354404478e32e9facdc8fe684f721e52", + "format": "png", + "width": 16, + "height": 16, + "transparent": true + }, + { + "file": "perl/library/logo-24.png", + "bytes": 778, + "sha256": "c28e22e7351e2c9cad303c71dfcd77f8daaa16a16b8263c12bda15cf1cccf019", + "format": "png", + "width": 24, + "height": 24, + "transparent": true + }, + { + "file": "perl/library/logo-32.png", + "bytes": 1038, + "sha256": "d3cf952eb9b610fbc8beea36acb5484463695a9199847f36c7f5eef61ea18c92", + "format": "png", + "width": 32, + "height": 32, + "transparent": true + }, + { + "file": "perl/library/logo-48.png", + "bytes": 1493, + "sha256": "53d122937e065f0efe3b693088314c30dd2e5ae2ed59af33067a3e8e5d42c1b7", + "format": "png", + "width": 48, + "height": 48, + "transparent": true + }, + { + "file": "perl/library/logo-64.png", + "bytes": 1920, + "sha256": "db53345f46e63e02ed400e7c72570039c83222014069ecd16b15236c62ef555a", + "format": "png", + "width": 64, + "height": 64, + "transparent": true + }, + { + "file": "perl/library/logo-96.png", + "bytes": 2761, + "sha256": "0d9ee12fec0255e16b40842724286cb4b20151fff01580fadc946aed0f478649", + "format": "png", + "width": 96, + "height": 96, + "transparent": true + }, + { + "file": "perl/library/logo-128.png", + "bytes": 3699, + "sha256": "7a298092387fdfdffaf8ebc8d745c616236bed2ea38db378d078c89f993f9fde", + "format": "png", + "width": 128, + "height": 128, + "transparent": true + }, + { + "file": "perl/library/logo-144.png", + "bytes": 4159, + "sha256": "e0a960300950f7ad49ca2b41d5775c336500b745c1d800f48b349da8057bb6b2", + "format": "png", + "width": 144, + "height": 144, + "transparent": true + }, + { + "file": "perl/library/logo-152.png", + "bytes": 4303, + "sha256": "dd7dfdf9421f4f7f47a378490bca2a1ba76523ab72dcf7e763668a868fbf60ae", + "format": "png", + "width": 152, + "height": 152, + "transparent": true + }, + { + "file": "perl/library/logo-167.png", + "bytes": 4768, + "sha256": "20cd9d3f63cb1b410b5369211e6d4c660349f173ff50f61706ed3811c268449e", + "format": "png", + "width": 167, + "height": 167, + "transparent": true + }, + { + "file": "perl/library/logo-180.png", + "bytes": 5248, + "sha256": "49e3f35520c0a06b36bb90809b00363557f0d27bc2ef945a2dbf92a7baeccdd8", + "format": "png", + "width": 180, + "height": 180, + "transparent": true + }, + { + "file": "perl/library/logo-192.png", + "bytes": 5586, + "sha256": "cda62e18fb6bdb29ec317c97f60116790f7ca4ea0ac183837fd2a6c511f1f016", + "format": "png", + "width": 192, + "height": 192, + "transparent": true + }, + { + "file": "perl/library/logo-256.png", + "bytes": 7501, + "sha256": "f7e52a0e4c02ca4556b0cbbfd59d2aa765e9c0250def8562c018d8ab4d14a4b5", + "format": "png", + "width": 256, + "height": 256, + "transparent": true + }, + { + "file": "perl/library/logo-384.png", + "bytes": 11621, + "sha256": "0d87ce5d39fe72817625458fdffc63f2b536a7ca3aa9a10cbe7f4be8a19b1e1a", + "format": "png", + "width": 384, + "height": 384, + "transparent": true + }, + { + "file": "perl/library/logo-512.png", + "bytes": 16073, + "sha256": "76b608882d9995577a0a89f8fe3ad61dd8f9e51d0cec2d9fdacbd410fa2cefe0", + "format": "png", + "width": 512, + "height": 512, + "transparent": true + }, + { + "file": "perl/library/logo-1024.png", + "bytes": 36411, + "sha256": "80f6a175f6a6178a08a7a6ca8f2720d5f26359a81394ad682abab8e0050819f7", + "format": "png", + "width": 1024, + "height": 1024, + "transparent": true + }, + { + "file": "perl/library/favicon.ico", + "bytes": 22603, + "sha256": "be83a0dd64de77acc187d04d2f5c511bd641a526673ae083fa3680f14d1fbda9", + "format": "ico", + "sizes": [ + 16, + 32, + 48, + 256 + ] + }, + { + "file": "perl/library/safari-pinned-tab.svg", + "bytes": 5879, + "sha256": "5d5de4a41ea955c85eaf2585d88f45c337a9120afd7c82f9258c6078fc026a42", + "format": "svg", + "width": 512, + "height": 512, + "monochrome": true + }, + { + "file": "perl/library/apple-touch-icon-light.png", + "bytes": 3823, + "sha256": "581a51fcc2767aaaebe9944490c253961b3e41dd457466cde98e3ce052e66bb0", + "format": "png", + "width": 180, + "height": 180, + "transparent": false, + "purpose": "apple-touch" + }, + { + "file": "perl/library/app-icon-1024-light.png", + "bytes": 28089, + "sha256": "2fffddee1e9a25f89725170a00ab7aa437733de215aefd63007367a9487dd42f", + "format": "png", + "width": 1024, + "height": 1024, + "transparent": false, + "purpose": "app-icon" + }, + { + "file": "perl/library/maskable-192-light.png", + "bytes": 3076, + "sha256": "0eee0737a3d52a24948f242d9f35a3e2642921467c1398764d66c91e037f850a", + "format": "png", + "width": 192, + "height": 192, + "transparent": false, + "purpose": "maskable", + "contentFraction": 0.52 + }, + { + "file": "perl/library/maskable-512-light.png", + "bytes": 9235, + "sha256": "b88aa8eea641cc77f40236fb24121e670553041bedef6d7250cecbad50724313", + "format": "png", + "width": 512, + "height": 512, + "transparent": false, + "purpose": "maskable", + "contentFraction": 0.52 + }, + { + "file": "perl/library/mstile-150-light.png", + "bytes": 2992, + "sha256": "95559f1e1c3eb967682b1c7f9cfaa6b031790ae0b3be8a08e31ff05faf5afaa5", + "format": "png", + "width": 150, + "height": 150, + "transparent": false, + "purpose": "windows-tile" + }, + { + "file": "perl/library/mstile-310-light.png", + "bytes": 6457, + "sha256": "19e814f0c662e6f1f54214e8574e8ee68f1663a4d89ee7a0e918d4d2c3cf27f2", + "format": "png", + "width": 310, + "height": 310, + "transparent": false, + "purpose": "windows-tile" + }, + { + "file": "perl/library/opengraph-light.png", + "bytes": 38308, + "sha256": "2da2bd99c2aefd2b3a83dec31cdda8a670123fa83ef3bc95bf18958440a0f9c0", + "format": "png", + "width": 1200, + "height": 630, + "transparent": false, + "purpose": "opengraph" + }, + { + "file": "perl/library/opengraph-light.jpg", + "bytes": 64251, + "sha256": "68961262cdbb8dd29cb3ceb6bf76a51830a5c24449ab159d6b4fcccc53d0c05a", + "format": "jpeg", + "width": 1200, + "height": 630, + "transparent": false, + "purpose": "opengraph-fallback" + }, + { + "file": "perl/library/twitter-light.png", + "bytes": 38109, + "sha256": "09167b7a0c3e98e7970ed38854c93406c225e8adf16d9a379320633387aa61aa", + "format": "png", + "width": 1200, + "height": 600, + "transparent": false, + "purpose": "twitter" + }, + { + "file": "perl/library/social-square-light.png", + "bytes": 43918, + "sha256": "f0706eb421a8c66177c29eba6254601ea445935bc3ec2366878a9ab2cf64aafe", + "format": "png", + "width": 1080, + "height": 1080, + "transparent": false, + "purpose": "social-square" + }, + { + "file": "perl/library/github-social-light.png", + "bytes": 37946, + "sha256": "af21a0cb5c5065f8ab977cbb2cbe46b68cb82d145f457a174b889877b8d4c54d", + "format": "png", + "width": 1280, + "height": 640, + "transparent": false, + "purpose": "github-social" + }, + { + "file": "perl/library/site.webmanifest", + "bytes": 716, + "sha256": "c8bfc76b7161e94069489037b035122a3daa2b6685c2edc3206c7f8ff9a8cfb1", + "format": "webmanifest" + }, + { + "file": "perl/library/browserconfig.xml", + "bytes": 238, + "sha256": "02c90c38c5d78bbcf7c8006d3c8ed22fddc040a1a2e3b43b50064f940d8964d3", + "format": "xml" + }, + { + "file": "perl/library/apple-touch-icon-dark.png", + "bytes": 3853, + "sha256": "955a48a3a216fef71a45a72fa3b8ebdad054f5fedb6a339cad89d3191f896d9b", + "format": "png", + "width": 180, + "height": 180, + "transparent": false, + "purpose": "apple-touch" + }, + { + "file": "perl/library/app-icon-1024-dark.png", + "bytes": 28398, + "sha256": "531a90595b7097fed0ccd443b4271437e548ca384af3aa79b7a07c9fd0581fe2", + "format": "png", + "width": 1024, + "height": 1024, + "transparent": false, + "purpose": "app-icon" + }, + { + "file": "perl/library/maskable-192-dark.png", + "bytes": 3101, + "sha256": "54cc47a05b3470b0902660f21b0e5ac9f142f5bf38ef5acedc76beded94e490f", + "format": "png", + "width": 192, + "height": 192, + "transparent": false, + "purpose": "maskable", + "contentFraction": 0.52 + }, + { + "file": "perl/library/maskable-512-dark.png", + "bytes": 9321, + "sha256": "b36355f3b9a18d5cc1c18077b8c39d2b27dbfc0ae6ef0805a0a9db29c8dfdca4", + "format": "png", + "width": 512, + "height": 512, + "transparent": false, + "purpose": "maskable", + "contentFraction": 0.52 + }, + { + "file": "perl/library/mstile-150-dark.png", + "bytes": 3020, + "sha256": "c6a03537f7c391d70d7a34ab9f199edea2a28dcac155f936003e0673f35716a8", + "format": "png", + "width": 150, + "height": 150, + "transparent": false, + "purpose": "windows-tile" + }, + { + "file": "perl/library/mstile-310-dark.png", + "bytes": 6514, + "sha256": "51a2aba8cb16f8c8658a8b083188187cc12dd0067c8b6a514178b89a9124db72", + "format": "png", + "width": 310, + "height": 310, + "transparent": false, + "purpose": "windows-tile" + }, + { + "file": "perl/library/opengraph-dark.png", + "bytes": 38701, + "sha256": "a4985cfd140c6a37a65148e6596fe69d3fae17cd9dab1a0c8d2a7e5fe617a509", + "format": "png", + "width": 1200, + "height": 630, + "transparent": false, + "purpose": "opengraph" + }, + { + "file": "perl/library/opengraph-dark.jpg", + "bytes": 60448, + "sha256": "68f38dddbb026c27762b238b0741028c8c054df5b09f2c73508b8a8b42f92a89", + "format": "jpeg", + "width": 1200, + "height": 630, + "transparent": false, + "purpose": "opengraph-fallback" + }, + { + "file": "perl/library/twitter-dark.png", + "bytes": 38505, + "sha256": "20f9c5a19f863a7b5921a065f2f799c6656467137b77b6dff29f563bb2565e7f", + "format": "png", + "width": 1200, + "height": 600, + "transparent": false, + "purpose": "twitter" + }, + { + "file": "perl/library/social-square-dark.png", + "bytes": 44221, + "sha256": "d2bda1fb90f4ee86e9faa31af04c694d5ef0c6983a8a812ccb8670abc4f9ff95", + "format": "png", + "width": 1080, + "height": 1080, + "transparent": false, + "purpose": "social-square" + }, + { + "file": "perl/library/github-social-dark.png", + "bytes": 38324, + "sha256": "73de7e034a800769dd94a5d5027e0ebc4bce794f95324da143424e5a3131de23", + "format": "png", + "width": 1280, + "height": 640, + "transparent": false, + "purpose": "github-social" + }, + { + "file": "perl/library/site-dark.webmanifest", + "bytes": 714, + "sha256": "389db0780843aa7fa63163b3952b8d91b9df8c247358c6e04a0b1ccdbeaca269", + "format": "webmanifest" + }, + { + "file": "perl/library/browserconfig-dark.xml", + "bytes": 236, + "sha256": "cec79db2f0bb97ab0d01d38ff8a33ce1ae29f4a17241fd3ef877fb7f26227047", + "format": "xml" + } + ] + }, + { + "language": "perl", + "label": "Perl", + "variant": "workspace", + "githubColor": "#0298C3", + "alt": "libtmux for Perl \u2014 workspace CLI", + "files": [ + { + "file": "perl/workspace/logo.svg", + "bytes": 2402, + "sha256": "afa5d2f90be083a47108fa6bcbd125a8a59dca4bd7bcaa379e1a4d9fb039f12f", + "format": "svg", + "width": 512, + "height": 512, + "transparent": true + }, + { + "file": "perl/workspace/logo-16.png", + "bytes": 291, + "sha256": "351d85c923da736be1bbd54d7d4023f7f57a06c3792fc7fa57f1b5fc1d531e6d", + "format": "png", + "width": 16, + "height": 16, + "transparent": true + }, + { + "file": "perl/workspace/logo-24.png", + "bytes": 324, + "sha256": "57561ca2175b118b0ecf85bd7512f45c2a9e9fde4eb08149e9ff3474a591851b", + "format": "png", + "width": 24, + "height": 24, + "transparent": true + }, + { + "file": "perl/workspace/logo-32.png", + "bytes": 415, + "sha256": "b99a991661a081b19b13668480a87aa0932606dce3a44ac57c8a44ce6d6ec2d1", + "format": "png", + "width": 32, + "height": 32, + "transparent": true + }, + { + "file": "perl/workspace/logo-48.png", + "bytes": 544, + "sha256": "69b06d03259d1fdc4fc2b2916410d6531a98ca8a45c87b0a705e610efe3369f3", + "format": "png", + "width": 48, + "height": 48, + "transparent": true + }, + { + "file": "perl/workspace/logo-64.png", + "bytes": 644, + "sha256": "1417687560faca8157c81db2dc6823d55ae16f568425d1dddf2745358c4a6a1b", + "format": "png", + "width": 64, + "height": 64, + "transparent": true + }, + { + "file": "perl/workspace/logo-96.png", + "bytes": 856, + "sha256": "4e7411400556e2d3d11ef48ae4d4c36172724fbdccdc40b0ad60896bb21c0728", + "format": "png", + "width": 96, + "height": 96, + "transparent": true + }, + { + "file": "perl/workspace/logo-128.png", + "bytes": 1143, + "sha256": "357944c345556c8f3fdb2fe62b95dca6bf09334f4d5202562ec92b0cd311b4b8", + "format": "png", + "width": 128, + "height": 128, + "transparent": true + }, + { + "file": "perl/workspace/logo-144.png", + "bytes": 1296, + "sha256": "d32d9e5df7299d66dc1b6eee8f55d455befaa663ffa0fa5411e2b83a718a08e7", + "format": "png", + "width": 144, + "height": 144, + "transparent": true + }, + { + "file": "perl/workspace/logo-152.png", + "bytes": 1327, + "sha256": "a0b28f7ba46d220b905bf8815f878dae7af6f5891bd5a65b2bd429d10e9ed4e0", + "format": "png", + "width": 152, + "height": 152, + "transparent": true + }, + { + "file": "perl/workspace/logo-167.png", + "bytes": 1504, + "sha256": "e408bc1dd1c93d50ecc7d2bf826f681096f71d8de16b7ebebae75e31c38fc254", + "format": "png", + "width": 167, + "height": 167, + "transparent": true + }, + { + "file": "perl/workspace/logo-180.png", + "bytes": 1629, + "sha256": "db3a057cbcb786785f597683215a99afd38a3f210677e1c82e44b785290a9b98", + "format": "png", + "width": 180, + "height": 180, + "transparent": true + }, + { + "file": "perl/workspace/logo-192.png", + "bytes": 1743, + "sha256": "a125aed5545969265056ba609542aab4b913ce6044855ffb8465e1496ae2b92c", + "format": "png", + "width": 192, + "height": 192, + "transparent": true + }, + { + "file": "perl/workspace/logo-256.png", + "bytes": 2455, + "sha256": "128b7771c2d86d65b1a62eca898e84d0f8f8bfeb1566264b084d9d2057c6937f", + "format": "png", + "width": 256, + "height": 256, + "transparent": true + }, + { + "file": "perl/workspace/logo-384.png", + "bytes": 3781, + "sha256": "1b6d12ab0bdcc631ed3220241a5799f1295aaa17d5797a405cbc1dfaa102ecda", + "format": "png", + "width": 384, + "height": 384, + "transparent": true + }, + { + "file": "perl/workspace/logo-512.png", + "bytes": 5396, + "sha256": "9849bf69cd73c12805c4a5682420eba8efab87e45e3fc22269172c020c163996", + "format": "png", + "width": 512, + "height": 512, + "transparent": true + }, + { + "file": "perl/workspace/logo-1024.png", + "bytes": 13757, + "sha256": "917c6609f28ea1109a47b9c0b58486a491427fccad746ce957e8316893d13142", + "format": "png", + "width": 1024, + "height": 1024, + "transparent": true + }, + { + "file": "perl/workspace/favicon.ico", + "bytes": 17557, + "sha256": "077962c7ae9c06d2e2b92cbd00650b71971963689adf97c89fe9f5601e663177", + "format": "ico", + "sizes": [ + 16, + 32, + 48, + 256 + ] + }, + { + "file": "perl/workspace/safari-pinned-tab.svg", + "bytes": 2402, + "sha256": "af04a311aca571482448a2a87ef8feb694b88bf938ceafed6f5da5227581c498", + "format": "svg", + "width": 512, + "height": 512, + "monochrome": true + }, + { + "file": "perl/workspace/apple-touch-icon-light.png", + "bytes": 1310, + "sha256": "cbb8a5bda92e0afe0ef6f04c507398f082498657ae094e1db2dc5a2f28d315ad", + "format": "png", + "width": 180, + "height": 180, + "transparent": false, + "purpose": "apple-touch" + }, + { + "file": "perl/workspace/app-icon-1024-light.png", + "bytes": 11495, + "sha256": "33dfa8db735483d2fc702340fee9688c3a1ae9bdde9380e45d3d20533a271fa0", + "format": "png", + "width": 1024, + "height": 1024, + "transparent": false, + "purpose": "app-icon" + }, + { + "file": "perl/workspace/maskable-192-light.png", + "bytes": 1137, + "sha256": "17a68e7a1a6187de9fab108a58139132546137c639c4153e9bd8464730c33d99", + "format": "png", + "width": 192, + "height": 192, + "transparent": false, + "purpose": "maskable", + "contentFraction": 0.52 + }, + { + "file": "perl/workspace/maskable-512-light.png", + "bytes": 3815, + "sha256": "3beb8fb175770274f5bae76d16160b6871cb7435d6e99c9e9c5cb0d9f44a0096", + "format": "png", + "width": 512, + "height": 512, + "transparent": false, + "purpose": "maskable", + "contentFraction": 0.52 + }, + { + "file": "perl/workspace/mstile-150-light.png", + "bytes": 988, + "sha256": "c60c3238bdb6d8d39690d41511dcadcc86e413ae1aa9d5dac9fc19cecc5f5ed4", + "format": "png", + "width": 150, + "height": 150, + "transparent": false, + "purpose": "windows-tile" + }, + { + "file": "perl/workspace/mstile-310-light.png", + "bytes": 2228, + "sha256": "a838968067aec3f7ec59483e4ee45db9af430f89d92487c4f82c2c9185e62b82", + "format": "png", + "width": 310, + "height": 310, + "transparent": false, + "purpose": "windows-tile" + }, + { + "file": "perl/workspace/opengraph-light.png", + "bytes": 22570, + "sha256": "40f2389a44e88daef178544c74cdb1ae1e5746bd0942618cc3e893bb12e6bef0", + "format": "png", + "width": 1200, + "height": 630, + "transparent": false, + "purpose": "opengraph" + }, + { + "file": "perl/workspace/opengraph-light.jpg", + "bytes": 43736, + "sha256": "9567ec65b895b45a0d6f4220ab75cd0808a6d3ea86a0d579f8bf456bec220f00", + "format": "jpeg", + "width": 1200, + "height": 630, + "transparent": false, + "purpose": "opengraph-fallback" + }, + { + "file": "perl/workspace/twitter-light.png", + "bytes": 22424, + "sha256": "ddba10518d5c265c59b33cce25bbac8da2d5b8b4758fb5f9a1d65b0b0a83feb6", + "format": "png", + "width": 1200, + "height": 600, + "transparent": false, + "purpose": "twitter" + }, + { + "file": "perl/workspace/social-square-light.png", + "bytes": 25292, + "sha256": "06c1d550d8b9bf5039cf496eb118673fbda119f51282df171abeaa32a247aaf9", + "format": "png", + "width": 1080, + "height": 1080, + "transparent": false, + "purpose": "social-square" + }, + { + "file": "perl/workspace/github-social-light.png", + "bytes": 22840, + "sha256": "686b3879f5fa3ebb626400f795375a542ff25408d3c0f46e0b3cbcd6628f0dbc", + "format": "png", + "width": 1280, + "height": 640, + "transparent": false, + "purpose": "github-social" + }, + { + "file": "perl/workspace/site.webmanifest", + "bytes": 734, + "sha256": "7702f7480f9f4428f1dd2888345786fb30994b6d582641476f17212aae8cc5fc", + "format": "webmanifest" + }, + { + "file": "perl/workspace/browserconfig.xml", + "bytes": 238, + "sha256": "02c90c38c5d78bbcf7c8006d3c8ed22fddc040a1a2e3b43b50064f940d8964d3", + "format": "xml" + }, + { + "file": "perl/workspace/apple-touch-icon-dark.png", + "bytes": 1285, + "sha256": "11542afad338f2df4a2653ec500b48e0abfefdba49c9c3fe636373542869316c", + "format": "png", + "width": 180, + "height": 180, + "transparent": false, + "purpose": "apple-touch" + }, + { + "file": "perl/workspace/app-icon-1024-dark.png", + "bytes": 11359, + "sha256": "2b518209191b7a13928874d8199c53fccc071a9ff85bbc65fdda36d34b3c6cc7", + "format": "png", + "width": 1024, + "height": 1024, + "transparent": false, + "purpose": "app-icon" + }, + { + "file": "perl/workspace/maskable-192-dark.png", + "bytes": 1122, + "sha256": "5c3a82918066e5801a2ff9b85a462da91f7a009cea2e46b0fd15dfd72a007739", + "format": "png", + "width": 192, + "height": 192, + "transparent": false, + "purpose": "maskable", + "contentFraction": 0.52 + }, + { + "file": "perl/workspace/maskable-512-dark.png", + "bytes": 3776, + "sha256": "1e2e85d141e8548509746c8d81badea9afa47f56d20855485d7cdfc40a975b1a", + "format": "png", + "width": 512, + "height": 512, + "transparent": false, + "purpose": "maskable", + "contentFraction": 0.52 + }, + { + "file": "perl/workspace/mstile-150-dark.png", + "bytes": 976, + "sha256": "02d2eebd8081a664ff565e823e54fbad0df05d06c61dcfc62a1a8c05495b951d", + "format": "png", + "width": 150, + "height": 150, + "transparent": false, + "purpose": "windows-tile" + }, + { + "file": "perl/workspace/mstile-310-dark.png", + "bytes": 2180, + "sha256": "96bce44c4ed378fbc84773042aed91eb96d656113a978866e16eba51a23e309b", + "format": "png", + "width": 310, + "height": 310, + "transparent": false, + "purpose": "windows-tile" + }, + { + "file": "perl/workspace/opengraph-dark.png", + "bytes": 22680, + "sha256": "ac664f292a1a811c5dd00b8b6a1487bdbfceb91f043bc4c0199466b382a2c55a", + "format": "png", + "width": 1200, + "height": 630, + "transparent": false, + "purpose": "opengraph" + }, + { + "file": "perl/workspace/opengraph-dark.jpg", + "bytes": 41101, + "sha256": "e450a2d141bb4c80089d91f9ded4c8261feecaf8fa0c41e5b99a6bdcca4317ea", + "format": "jpeg", + "width": 1200, + "height": 630, + "transparent": false, + "purpose": "opengraph-fallback" + }, + { + "file": "perl/workspace/twitter-dark.png", + "bytes": 22533, + "sha256": "afd27fef68ab9ab2fa363269b94ac485556981ee54958db1db6d20ba24a5fd59", + "format": "png", + "width": 1200, + "height": 600, + "transparent": false, + "purpose": "twitter" + }, + { + "file": "perl/workspace/social-square-dark.png", + "bytes": 25379, + "sha256": "2c080e2560394fd5e9836bdb9eecda4a40c035c8b440d35fdf450a1b575a6cbe", + "format": "png", + "width": 1080, + "height": 1080, + "transparent": false, + "purpose": "social-square" + }, + { + "file": "perl/workspace/github-social-dark.png", + "bytes": 22972, + "sha256": "fe670a178af2d1750132d552ab91f67fbde4b71b2a586f674250514f69f20cfa", + "format": "png", + "width": 1280, + "height": 640, + "transparent": false, + "purpose": "github-social" + }, + { + "file": "perl/workspace/site-dark.webmanifest", + "bytes": 732, + "sha256": "cf54e6f78e7e30152e6fe277a24628514aa798055e4a64d4467ac5644445a53e", + "format": "webmanifest" + }, + { + "file": "perl/workspace/browserconfig-dark.xml", + "bytes": 236, + "sha256": "cec79db2f0bb97ab0d01d38ff8a33ce1ae29f4a17241fd3ef877fb7f26227047", + "format": "xml" + } + ] } ], - "fileCount": 2064 + "fileCount": 2154 } diff --git a/site/public/brand/languages/perl/LICENSE.txt b/site/public/brand/languages/perl/LICENSE.txt new file mode 100644 index 000000000..fcc9b6677 --- /dev/null +++ b/site/public/brand/languages/perl/LICENSE.txt @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015 konpa + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/site/public/brand/languages/perl/icon.svg b/site/public/brand/languages/perl/icon.svg new file mode 100644 index 000000000..49f367388 --- /dev/null +++ b/site/public/brand/languages/perl/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/site/public/brand/languages/perl/provenance.json b/site/public/brand/languages/perl/provenance.json new file mode 100644 index 000000000..5563bf9b4 --- /dev/null +++ b/site/public/brand/languages/perl/provenance.json @@ -0,0 +1,25 @@ +{ + "name": "Perl", + "asset": "icon.svg", + "sourceUrl": "https://raw.githubusercontent.com/devicons/devicon/7330accdbc47e2dc0c19789a48533c4a3c50fe58/icons/perl/perl-original.svg", + "resolvedUrl": "https://raw.githubusercontent.com/devicons/devicon/7330accdbc47e2dc0c19789a48533c4a3c50fe58/icons/perl/perl-original.svg", + "sourcePage": "https://github.com/devicons/devicon/tree/7330accdbc47e2dc0c19789a48533c4a3c50fe58/icons/perl", + "retrievedAt": "2026-11-07T20:44:02.680269+00:00", + "sha256": "f6cd4249349b4681ba273699aa31cf4df43f8c63dafdc640803b91cf239b8c8b", + "copyright": "Devicon collection: Copyright (c) 2015 konpa. The language marks belong to their respective projects.", + "license": { + "name": "MIT (Devicon collection)", + "urls": [ + "https://raw.githubusercontent.com/devicons/devicon/7330accdbc47e2dc0c19789a48533c4a3c50fe58/LICENSE" + ], + "notes": "Used to identify the language and its package destination. No endorsement is implied.", + "localCopy": { + "file": "LICENSE.txt", + "sourceUrl": "https://raw.githubusercontent.com/devicons/devicon/7330accdbc47e2dc0c19789a48533c4a3c50fe58/LICENSE", + "retrievedAt": "2026-10-10T18:04:46.645136+00:00", + "sha256": "121194741d4a915b9f5890fdd6dd95121f9b1f816517c792358d72d7c838d664" + } + }, + "modifications": "None. The downloaded SVG bytes are preserved.", + "upstreamRevision": "7330accdbc47e2dc0c19789a48533c4a3c50fe58" +} diff --git a/site/public/brand/perl/library/app-icon-1024-dark.png b/site/public/brand/perl/library/app-icon-1024-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..3c28867e2b670d9e02f9e3e42498d353643d4d21 GIT binary patch literal 28398 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 $Z?*Mk{ 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 J%)hK2{TD2nPyGM@ literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/apple-touch-icon-dark.png b/site/public/brand/perl/library/apple-touch-icon-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..5dbaa271419e89659dde89d823fa69ca8ec1859e GIT binary patch literal 3853 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/browserconfig-dark.xml b/site/public/brand/perl/library/browserconfig-dark.xml new file mode 100644 index 000000000..c626bbd8d --- /dev/null +++ b/site/public/brand/perl/library/browserconfig-dark.xml @@ -0,0 +1 @@ +#0298C3 diff --git a/site/public/brand/perl/library/browserconfig.xml b/site/public/brand/perl/library/browserconfig.xml new file mode 100644 index 000000000..d7b3336ca --- /dev/null +++ b/site/public/brand/perl/library/browserconfig.xml @@ -0,0 +1 @@ +#0298C3 diff --git a/site/public/brand/perl/library/favicon.ico b/site/public/brand/perl/library/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bbcf6aec3ef350e6cdf4996b066b66a8c11d9727 GIT binary patch literal 22603 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/github-social-dark.png b/site/public/brand/perl/library/github-social-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f7abbc1d3c17077e728d5211daff263821ffe7d5 GIT binary patch literal 38324 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 S5(_-yl)=;0&t;ucLK6Vq0JwJm literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/logo-1024.png b/site/public/brand/perl/library/logo-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..22842d47ee23e7183c567799936b8a4a521a8edd GIT binary patch literal 36411 zcmaI82RPO5{|EdzMpi~<*-F_Gp@?%zl57!Wr9ovJvNO)1P-H}rJtNA>-ZGLhl0A=+ zk$ud=;hg6_>RbK(&vQLpR~J5?`@Y}%^?u*)`#$HHuC^LIEhjAmLG)`T=(YlY9mt-pqCKz z{c&6?PWSTn6C%hf@cS1q?~8s?U5+~)SxQq_ckqe$OT>W-pQR62VHOISOLE1(-VjHw zN{`B`M@h6qxDN)XvA{hS2TO)>MUa)mSk3udo3BIKrg8V@pJ|$#jP4k$&tNW*LE;(n zQ9W=&SNzPVepJ1q(efG}{uai95;E4bnDvkx9@yxnLwU@#bBgW^uTj9yQeV^k5o%v-TQqRZ6Sy_e1rvcWrKdK@lCSuS!k@}t{!#1EovY{-dqTR z&_5{1l9ZHrlxwz}aVwvq9GtYe*7W%EXL{#8=?ojV{lL&tL_HLz>x(ihsumL65lfZW zMcvk;LFiFJ92d~ffpH@|o{tp@Wi;?DEYXzq^3ruKp)XHfeIX%l#J4va_>L20tY`jI zZvdNNBa`zrReo=cJpy8Nftbn(4Q`_XBo=N&c`JC$tvHnB5E}a)qv=w4$gC%ik;@y( z5?@|W!lY$yc&3%^C56!vYfI1+$p&QTzG2rHx)+SV>G;Ph$sQ%qCEZV?E=Ahoqxi?> zE$bYL6vv$S1|4uzY|BP&HN+gfK0!%oEq_y5-MjJ)96FF4|oEF>K;5_w>I9T zH920=mUEJW!fP>VF5}az1#!Bgw8%6sx%RmX!SQzO+Z9y1-y!sO2Iyg;=b~CvwF(ej z_4{clS~6vids1_UzU}gyM@SxgYj0XsUh%V?czs}gnd&ql=3N&g3on7j z>f4~dUZ88L>|`tL<~`Qrhc?OPs%7Rm^tLuDcWN<+7!(QTlz855%uN zBkOADs$ur!myzh`1!`R2Y{yB0ebZ=PX4Wv|SJT6Nnlz&lRdmaHEExNBROJZtS0#=H=Ut7eKobhux z4Gyog9r$3Qk%qHyo3K!&OFk8h0N@k7P~JDX$+64|L5Ko5Dz6h>&L+*r{UMGW^3y!T zu}@K@Y+I2iyCFt3Bq1puBJt#rY6e}sTZ&qeAcG)b?WAR&&4()J8T+jJgyIRWIiq49 zq`_|3ja?W&WbArZ*~{8(K+CP_JP@Mk{`JkDD=%{Fq7RXsu3_S#Gv2ObQ_2%bwI^oQ z48@?JvM>L~5I-H!Z-wgYHiRUVC_Zl-xMxdDdZneB&ysIBR@`^zM%ayY7=o7!O(%f3 zL|Wflu`W=q#Pk|9)8c{GwZ+r@Izl^^D6Nc~K|e-l^)U3~5!tXuAW5Bl)?pn_Oil_x zW#2f)mQ&$Go1=W|eNm-^k|tj02ON5uOXVf7dY+`mJh+0x(kdXL2&;Lx7Vv3^*>%KX zUNIFKLyB)gH&2nFO{rJj%(|kte%Uo;d3&WG;HnWbSryX=)5^~~=f>Zen7i3!Y!vzP zLgH3X_}Z`y5+Cdaf-?DX9GR;Uk8%|jHx&qR><)ZS!k!T$ z?eYeONXK5)*mBN0v%NICNbD0|g_5OUb^dX%r3J~#pP};mOzaVIm&E9xht059&2N!@x zmhFI}L1)qbXx{+`nmwzTqnr$hGaRVTSPwiZzt8+_sm z5I+qJAxVMLcUG+1hn+i*k{J0027L?#5Y94nqaT=Zucwz1?HF%#!w?Z<==d4?GVg&Q zN&rx%%3bGtUcnIWx4VK@HftxfNCpj2<$(kxA?iMi&rCB3#_m)@JBf?{11l?_bc(f z-}J3aA*;1~a()I_tQ9g_aWy~;6{JQSzbCL(%I*a5Lrf4Z3J?IEDW0gqeI_~y0`dJ-zNffq?@B2VSsMOZ2KJ7b!Rb|}gJboQ=ws1D z3dZr+dsKCW><|B2d;0>i#-1Gah+5Zkz1DP;rK)N%Q+xu*#t#s;Y0Fdb!!{lCfYWm# zdMDbEP`h!J-SNMv`0f|uRg_RcoZM;evF{zk=+dR)r~lE#B$b~0Aqzd_B-^xDm4s%9 zuwP4(ZNO$dm4|N(#rHAsug>QY)^iu!BPqE7ERxJ}2G}@p21+j2VCIBM2=RYk)Dqow zYTTeFjCS|Dw#1M`iy_yzzi&~_4*bioy0#vz;=Ex5u`if{P#~U z=o{`8&@`!D`b~6)8qrOaT!Jt70bd}uXb|9yu?WGzE)?avASnU12W3;#oX z8%oCVeYsFZf_f5tjirx?nf0qnYvTnAw#I!*JP$swq{t~UP#W@hFHLk{ZjU%wdUUXi z`;KOM!$m?Mer7XD+%*`q?{KWGUzYs8h4avaR6kCcZ@qb#my2<2ZEgISP$K$bY+M|j zO4{v|`32oGoZj}Os!13&J>x07W&tJCsRa@Besd5!{UTAQA#}mvjK?D>O-*ePVUZ(~ zERiWnJEqOPy^lL*hPM(LsUR*+l-lnZ9xgh|g`FnfJHL6_3yX`33$u%O%yc9%W(Hn* zXxZo8IfFTexZnou7W|fa^_G^i58S7V4;gcfHR4)fVPQ%!ivRswqWsD5x6oKr?5E1# z%5*T49{Bm~NWx4Q#!nO)kEA_sdhpf-tx(Mh3CXF+*py^JpHJ zAU|{uAPva_>h3=4IMY1xEnzuOg9GF0_}-0w7_;`= zoZ@c|yn^N02sc|!Z_&UgpkP;uF}~mOtz8b3P}Tk zcRyAfwt0VgNVm4Pi@Z<1tf{3HNadL*jr#lAqoVy0p0R2AA_l#!0cQL%jYjDy#oX6^ zN2@sJOm2z(SG0Vv1GLp#svdYOr7DqCS{k|8K zc=nzX`j3^m;2|Ov+ZEkZhBF8DL4`D-E;!&)Gb?zg%^3Q6W*`4ZD2aQw;?NOUK~$kJ zF*c^&+EBKs`NPiTO1ptWs?0CT26G+P68T)pK$V{8( zpOx<$4k@Kb`MrGmlnlO>_=kxHc@VeZ;qzCz?`**K(VnEP%Q+(>DzwKgKLdRKGxi40 z(h&nNcH!CoEOAA4lNREaU|1&!K=vzX=+7Ht(Dl^%M@O-@NB=4!i)GIhLfqh9WZOqh zK#B=UzZM5U`f2L>f9$(JxH*sYFd1~elbL7x)IV|=%p6e!gl^y$!L;9gbvb9@I_cq{ z4&6W0-vRHpq!8&8_-9}q0o35>szybV%~gL)9Ig-GlJ!zJ^T@s_VZRVPOIAuc8|Z5G zUpD*3KEDPMO{|YS_0R##?)wyf&ZSSE*uZ@20Fvx~=F6QT>H3WPxd;D9{|?)t?tdt~ z@!Ra{e^(%3AXowWg6|()UukP?6@AWs{FBg$e~lg)YT%2r5L4G`we`9_#s_Mm3*S?>|zAtl#X23_5x_ z=AOA6@vnEat@1W8rMFdkcf=6?*!#QH-BK=y-;Q_IdvN!!cIDm`I?;j^0@Kpq)A0Xd z7yVLXInj{m{FnE$%1FXrHsV}Hx=5o9M{>zn{}?!7V?dqqPWT$-^$5(z4;&Uq$@$n441=p^8G{Y%fceB0T6CsmiN@ZYWtWdKoTQ& zA$E!25vi(d+jQL5Ml- zpa1%4`?DGtAf%ZFboHN?dJpOh0WwbSNtAyBZMXuDH3gv3jHmp^bGuwzFQ2Cn=^BLJ z{MRx|P9)Ning2#!!YB*`l-A4>{g3^ve0-O3ViC-C+!hbyZboskw z4-gLDY=LKR3;)sW(XDmmcZdC0Zx|a(QPKVprG;EcMN50h9BL|qZ|s3Qc_Y1?3?j(bV>c5 z(z|P4t^uXwq$;a|W zB_xE-dfB2a2Butdt)$ua&t%BQ#?$l6sGHo@HD!@40i^9B1N=G(Lee$vx?T~W5Ghtr zwBC0J$e6oNO}V7fTYYrXqP_YvHW$5xv>{2MZ>h4Cet}v)y9(s*U+O@WF4!`XAG@tu zEEV(^os><2nJXq*uBN0Fb3F%t4}-&Rba66VO27rXII{BT^}BwMuPV+q17RYpzAzz>u>MoYQnz^Qgbg`z$VH#T zB6)dn`G^7a`74Wa>|hp%KGW1v!{UIN^GL?q_%t3Sd4nR71yyH~LB6&r1#$t51QnRv8JC5H}VVc~66mF<48OkY_OT(`h_}qx{4#O@shM$st!# znLZCDfQ}on=W`+#Eyk!v6xg2C|F$=IO=-A(pyvYk6C``xU5jGe%=%-l8$ccCM#WAf z6_no7X$~eMAkf!^pFD7>xnA)B2^R0zD3Xx<0ZICO+H2PCw&!-;L%`5*(|y>xCh^At zU~br_6DJxfxybBXV zjHy>*Hijr5@vM(8PGQt8XLUV3_Dh=xtWHWi9Hl&by;23LivX~?W%lHyf}-GmYqJhF z41uc6nE5sfOU>hO{h0u@U(t`ANP44NzV#GB`^CMEU)_8BGRW;e7i@xSq%Y|ff>*Jz ziP(|HFF6nWQg9F|s<(ZbW!$9{Wey?Ex3;$LjGn&|qN5%A%Xh)VMO_nX_Xf2Ze&}Xr zTU*<9`}r$c+FHMS8?C=llHKdz+Mj@FO2ytW!e!RtRbf!DXiez%E&A{GA6fmzIQKOj z{UR&RhB%*PN$~#D*1_*KK0Y6RIkhlBJ;Ih4v(g)e5rg=bmzKPH-45z6EhSpF1(I+T zZATPTUmkE8w@WJ1fe_{+82s~Pj`ZQxM4{GS1LTQ|d z^C$K*E>P-G`jF57)LKj+CG=y+EE4dvxOprrQcBPPa zCjV6I&Vk?b!SZ`c(-yd0POv|_YrU1f%#vsuk@F+q^JKv#p}DdZc(1&X6bW zjqYaR7TdharaB+MplG{W55KrkQ>#5X(E4m&5%NUV;O*^g2mEc&x0M_K3h;JA=V7E| ztjzbzE>c!3C zqEKqc{VZ4EWX-WUxBea_+fY`hu?b~tY@AOH0fiU*oS&a(g;o;!hyw&huT1Q-mSF~g zwL6c<(O*>T$|vB2b0Ai1@tJ2-(4$QCKy|mkRuCJ~#8X!~be{w9fE>N^X><5gJqMhQ z41$mZ5&gZrz1#Hk^m%O1x9<5xxPxO?mkem^Shq%t&_N}o&OXi7=K-#@!BrO)1`4|* zBqZ`!p!B}I&Qu>)*Y+)#yQ-t^y>?9A>+$v3c@i5VSI##4Il(vv#4IWsDt$a18F4 z|1{(3o#E>hoX0W}%Ol&zejZx+`4-2=l~gu?DTYX1#W}jt+Fs+Z`lAKT3bAI=>tW#> z)o<3WA7H+mY1cLT3*>0{NH6z^6GC}&ZsMf$6PYT1u2UP`K?4P8n7N+Ys$4sA zfOg#0`HAD*Ex&DfOITgPkjd&peDFSrFS$N*v$Ftbbh%yK7>70)#nmm)?t}s^{v)tD zGewisNv}eW?GezUVkM?aQJis^>*jjxR%x}*{tI|NCjKvZ+h#dQ%%Cv*WcRXRrWrJ9+RlO7m~Os(^JeN1tZt%0Y;dmj zXZK}$v78PbUD1iu4bvjURqRrV18P}j8ZSl-$;l^}u45wikq0-u*J0hEeMz8ho&wt5 zGIo{Y4lZfc*3!YhhaHz#y8GS3O3HSD*X`BV@dHq$PQ2*nWzggW(d-rM>+74D$~2Zl z1LclZcMcKk2K114-|irljx)Q?7ssZ&1!*CM5^K6m{C;{JS6uet<=lDK-rinH4drSM zAD+KRylK7++;;OA8HfF$!}MG06{=&ZAqh&9drJE-6c`K;pt2f-KR6Ga9#0f<>cchB z7kK$V=G*MPpro4&gD|WFz^d^(mE3Edb z#fG^GEVQz#y#`3ZN<=8fk_XrgylCVgIO=xx&vU}j`f^gzoUW>r+bY4_+IhkC0h4+i zuYbnGq;3xY$7zCx%U90?)X&+jR-DdTF#jyO8SKe{Q-Yto6}-s-qmHSh?0RJXW8B5VN2;drs!{>-lKNc~2396MR6|rA~}c`!JF!j;d`cT4DR=&is#tKD-7; z1)p@$_k*NVWMNOfuuYU~-s@QBxYB!9QskXZEAImaeS;%%ihOV4ii{9}U?@Kaf{ zRG>af#u@FZT;AbncZ|%yX-;>(RUs1YW!6o0mVdSD9B54#X(&hW5IvhyonB|QADn7O zwu3Tq07fcEzRYX{$@e*kXH6S zZ&wDwdWr&KVy;JmxFx-FQR!aK^F%bG_Vsn#Zn5Bf3%Juk0U<>2ErY#Mpmit>fB^>S zehJ-5ka_Wo)?N9BzWv87 zioKqn(m^c&h`lu9h)Ik&b^kYqM90FlU-q~%n#Ao)_&wpB-Mp;juOTi%JMA%2ztmNc zf~8>r*^s1?TG&lX%a2cfuUhTsUD*QC7?2^$(^@O;zu)oYTEOzgnxsRxt5>gDdU>5Y z$jBI2Xx$MoIy(BTr-w~JL81N`i_irpC#N%BIEQw^9=@T*8(+UPQrXa+py*U$Ke9s~ zCuc{yv9Xai+eE|!1Oy;=-OdqkljX$G{*RBT8amU|oQRbSVxZR;c|Sul;J)aRkxcNW>&9?5~`akDJKG+U?szF#(})#Ab2Gw@Y2oo z3k&aQSkR3@d8xr2bIq#erVApQ9>ph~I100(%qK?4y1Ke*)WB%-gV2QHGp*N<;8d%R z7nS$$>yx8PJV{hW-4BZ=Ci$rtxT$$~cr5SSX_SNkw*tExTuu;J`3;l2TX0@raED7X za;q=TBJbuK{z{4o6F%+uGcV}khn0c%U)F-Y4Guo2r%1ku#7+7U`wMQTq@hRRS4ePJ`_g)_V@yODMa3W0&0kON9|tUS$rvg{9ZP(sNAH1HwmvB#R;4 zoMM0XT|XgMI;(W-$TG`fDDK7D$)71eAMB~rpaFtK55V`H;4O~1xL z2D&3;P#XlhViSx~Q&YQl@1Cx~`9ncr(_kwqw7#)%_9(EpF_24{?g1I4u=(T1kIN+p zj)kXGSziW#2zOZMFOWKQ$}$n0H~%;Z<-0UD1UghZYz@T>FLATgV?X zjlp2}N|2b`*Rb3<_qr67!1~XhpOzbvAlY0A>d&`)JS`1Titmyvo}m@TdJl`0cE*yslD0k&!4AS$b@%&nX5147Z>-0f)od4 zPrs4|U?kf~W_n?q&*I~o6{;XdHH4a4APP%fPlJ%Ww~d)r9G$-EV+D{s`$ z{J>=CXP~Ec{rLhQwZu8VYV7UpCAk${HJ#weKWvA~PPy6CfrE;+EwD-mxV~0Vq3}F3 zG}hVIAh_epCu^(8n+7S+%MWdF^7B;3K{t{Us&c<%d+SzxBVD?7)$x+TLK%5R(SzvI z1LaQEhdDV{#epbIEYRth4X@Ws(B;UoBM){@XbRM+8s;+Eyqm9&4H>GxZQ>eeNKaLt zrWp1_jStE2bt{pYk#83KUt(b7U8G~=RpeNLD@Qn44BaWq^Ohd=e0XBG>nz98*QQnJF)crbQ5FjXmb7wW2vuB%e_$$cB#^<{iO4OMib`bbgd6R4ls>@w z&L(YP^B>(-5zZSuEd469$iWf6xkv|gHi@9i!~b(Mq8Z}9W?{jXk(sGghfojpOlm~d zi0^iZNCxzE+ta?2U#1mvP;ueYYPYgX!?ClW4VEsfhu`On#M3ExX@3{8cYpNb^9xgQgAN)1Il9Q4 zd+m7gn_r_OPN0$nwY0SS8v+>v0U};siOyf8FSc~q+suE6|7hxn|MnvBZ9X5vmTPN3 zWkr%?R;o{Dz28D)=aT==mAZnD!yU-&ni65bGcWPwQARzu_*eO5j8}#kRnriFP$R_O zRV5rrEU_CRrJ-ksg<}q&K(k5#AAREmUv+_xv(asL+*sCZ$mUJ^$~_K^g&gl&i^Ow#NL zFGIb8TA4ntlS_$7Llqc&)zP!B5A9+7AuHL$;z^AE)H3LG|QLRGc32k@hZfJv@d%$=wMHC zJkNXnJnZ26(9m>)_k|j7nLsYQ0D!AT4W#hl4D0!KGNevrgQo#L140!MTu{nc(*+DFUEI^{}S_VExd@>OOm;W3yePtnSlN z0`^rpdvCCt1Sb35kh51PaVb}b_4&&x+}uYshQuJwYfJ4T29~_W@h5z-1$vdBa;iI8 zmURmsp}B-r8p3j&Ws%D_o|x9hj&!kiZ!3Sbh_e~psw;pYx7GKS&^S*f6yJo2cq`*} zvB%o96!3QsQ17q)6q2TjK0O{1=NMDu>jgTU4#gIUIa$chW*wOxe5Qg2N%xX5(yY8A zJ+J9nTDi7O#DFUX`ukIM$OE5el)rPMAv@^JP<@Hd-VP~0vdD*XIEKA&H!pCgdGt&5w#b4&FYN1A=hT{mHimZF#9W^lQ)|JD_@}MNR{3I!>Kk4bbML=Mn))<-4!D_p8Er*{6u6OJ~NcoNMRoQGq^7oZ>}OviR(YnJoSu90A95FhD_)|~JW&Q-!u9-T=_yEodChKw z%iE|gCQq^<*R1lPTHQGgN^os(C$Y6aH!-}Ws-|Z24nx)ZG8SjA1E*`QbWd!3kK0yq zP8V{!8*_^;VsYu}j8mI@-zA>cA+r`t$ zW^VGR$6379HuenOHL7|4U%2W=ySMzPCyl?y~ zKUyLIo@ijJ^-iK?X>1TI^6t+%_Cy2t&A=gnlhS$ddlsX&O?W$G8M?kPelHUn`)P^{ zljY(Gu6XT@-+c2xC<}thZq*tV9CM7sfqkSu6n-=zA%SzRdU%MCJvY4Jz2)30>W7ZU z>pXvANZ+X~;xzqrRFW-_)H5(z*=fZ(Agxp;PGCVvR#nkJEkdMvn@tvHB&@qr3 zzqjy}z4c7ZNWwZMuWoR)#+}r=emy4W7{ITw?5bl0Q|lioK{k z2GU*731OHcG7Rh;uD|}|k8-X-ZIAXkxb?Bna`4xdQWa@EF&yH~3nEoa>zm-j6U-;R zx=$-6D#~)!7r>oJa`IDCVPF* zNb`jZ=@GR&*MQ$Kx--doHXIi%aFl>vhAs6Ui5p2lXva`t|+(bEJa&uaygG%U!R_wU|a#gVhN zg`$P7a#1XdRx5%lqa=l{$ATkn_onGa`|+T-V37*`BNGW{v0KuH{;0)_+2_O~sua3p zN@R)DVw*+jx!1?QMx_47k8~iHs{BQPIzFRrp-rE@@o~#04)KCWA)Sou0nFfB#mdTy z(b*896D?Kp4?nb;n{3A1PTkzx9N6FUgHx!^d1;~gOc^c~#rwc9MC%cSwW>zuhCIB= z-^LX{F+4JKisPC+JUn*0`ojllXE!&{{54-U)1zLQVQZ=Ss#tT|>(;Fc=MPY_CdCbd zVpo(s02|d`X0vHFq9b+?ZBU+Pcl7;em4*|k*t&#CILjMl*e$qe-&ck&t3SwY!ChuI zSd_KS@wl@f07u`il*!IYhR7a4c?rG`%{`-~LhUg7EoGPiqy)qdt(YhWH&vHgD(Ig- z?^AM$Kg=Y$_i1IFg!qP5-OEb7ztr=MaV0V`s>&z6L<;X&BdQwg?Cn7!VDfaDHZGHo zY@NR)ha5G1X;gtY^)wIjJPsM<{J6HFP0yNG$i4${R4Pc#J&veU$ZzDL{ABY*aFhwC zD5`PGI<{T~NW1zDB-w&2308p5xu%in5lS-_hAh0w!#RcUy5kj@PLl5*2rq)Ju#1bO zt*s`Yi~lH0VQgNYTwqcf;pIaYv>02fuRKEp#qapiLL~b-Wb|D)zY$N~sECPh)=CC@ zQhj*DS3@tvw0O2e$b7AA&1-;#>pp@oQ9{bx`PIN}VoQvd6cpjB99fmIewW2T!@qb&CK6F9=Bo*2g~4-lSsWZDo@QQYbr3x`2;u<~#Xuk?_j0X>@Wt zcgb438^*q7j2OCTd=;Y`A@C6F@F0kPGq?4lZsIqlvDwZvTE#L7NAkACq0;D4S7Hc# zrz=sN&Ix_tXSIVke__qKec1g6;8qFL=yReFeutTp?6jPm=*k$IrjAY^NF6V)xe@P; zZ?B}}4sRRKJwzWr!~SjKV(!3$EPp7FkrX_?g`te&Bx{bnUrVhzE{@XJ@Y8k=#6UuSOGQqO)<>$7 zr%s(ZBxgTtEKT>p-FLeVYe{F1ep3E!W+4BTj)uA{jre-bRY0zQVA7P^sNJhRJ3*^1 zB`3%Jz{Wy~_mUO?iWn7?s_>ItYSS0(NGx--A4Y)far!9o+QQ`pLrHK9NQ=<7 z*zN1?e%We5#D|6%8TV_ksCxb9)0oB>MdgGZ zrsig6(}GS2t%|U*iTEGO-O)hb zwaISC%j@SHt@Yx9L^e`h#nq?9d`Yc2>adRt=|fyVd^)xkaZQjX{2|urXV0FcN)Wz^ z_4@0ayJkI3htTFefGN*#$M=J-mJIlS2q5OXk0+%^V+>S($U_1^hm)L0N^b9 zrI^o2xw$m8CBsoDNOGx^Z-kjQsD9$sLD=Tf2p0f>lc3MAXczM-|6Gay!pk1q*fF@!g%Pi99Zm<84QLjlqnS(lED9En-+nK9R1nNMu8>CC3sMG29?=M@$R@(IC zR>cqbHL+3|I^Hz2rAzVbz2;9WxD`w(0YxvSy_;*et@qT_wxcFZEevF((ZsXN*9-*< zzs`dOd+vj;?BW@?!Xs3MP32Ppsh;KInWZ{1jbAL>^#lxmY8ZVLMxSccN%7UeLZ1~&)P!Iavs+^uHhQH{?k3Jb4x zs;6=*dzHOqS7f{x66Z6oXF`B|t_@=wkbuqi=Fovi0tFW+()sKTX`55)UcY_>l2n^ zyE2_B^@1$*3Xc{l?`p5heez>PUw9`t@eN?${#^ik<87B`!+JXpA3S(a-`MyBBxv#& zvuDG(vS-e`J^W^D;+U|Zp`mKQ>+;en(cJ(s0%UxlGdi3 zjauKMyUN*eFYR7RuBlPR(nXiySC@0MOUEeq9lc@7wN@&6PaxovZDwoWAWNT*Z1_fJ z_*)tU$A5Z7SpO>vl z1RwY<&Cg#=|L~T9PdOgv|3#(qm4>{+G9%(pncZD);{p+b3)grfhGbN6~zHvJ^dTKYdp#k2`c^k2k?W#6?mv_nn z#aU5=JlH6vl$6MQL=t2=)KE2<;+)GU=lM#^*5}^Z(x(*3uj9x^3ls+0V3SsLz_C7a z$uu|2$n(r2+oTQ-Ny}@7P~Jtc7sn;!`h$ z&QO3YpVvs7jKp|i(3_E(p5ERJ^i(#Fg0pZ-6EW*8j#%>{`bcN}&#UZV5Njo4-tfzQ zE;0%TI*E>QzB}V__-uup9bcUvxafvb$~UOD^M@) z9~6rcrf|o`vX^m3Mn2^SzLA}!*++G?rS25TtQXLV z*ZKgoMJ&M$xP|)@azV9Y(Em^!9Q`%yY|KYq+l8B5zrNjd*Moc6qGp2}l)8o_av%AW zu5n2N3GaC7SRv1!mOkZywuU22aZUY z7rbN4f)!4ILe9kZtJniOJFUSI;)}OK#Gx+-8>9|4l)XQsq=J&Lj|VY)IUn=3Uj(|T ze(>PIC$rDJBZ7z@-!gt=G_F4qV0rixTOdS~U1bEkQ{Z!gc!H%*Ef1CIqc zs#SGSg6A>J?VnbM!Du5MvRyCd_$4H8G#VGP9}R3ntIDV3L51e(aozFE%VZg%P#PR_ zuVsJq_K{Au3V3P102&0Vs43s}Ju3}!p=q2~>8)sFUuWlwba^6=m{IPoy@o7_>(6*? zbdp&ssUmQAWgdB-p0C69%TVJm*pQ7)nSdsHz-+v?{^+ioD1jb~Pdh`ZYY@D{;b#vm zz5U#guyE|yu^{srOK_tXe0#$2Q`Q8M(mN#DNIFS-FC0cXRb2hy0<0Dj6k;SR(mXQK zkp$0Mnc^aylf9mR?|9X;M6?1{q=Mv00r;bn3&drI*n>QGeS2_Fw7yF3?d`2DLcp^U zfjR>8N?4m=qb%DdfR78+r@EMHboHE6BOd}BtdEY5iHXs@dNuNi3~{fgr-#_eyuWgk ztx(;`iyc2|K~*l;9S4p$mDqZsl|+)1y>DPO+7p#LBUYwSwi|Oj$l`Trz{>OE7@8Ha z7bn5)ih0fx@KX~+AAL>$3HIB4D_U3$BO@c`AmYI6v@hR>ANvzPVj(K6vXPkbMrE8m zXQ1bz&a&!DPQ_aL1k^C5hl?7Uh!?sSiGdQuB;6cy6sT)^vF}-P76zyNr`Ym*0zJXW z8`+tu2`+xurQ!1KCSqad^#;Du#$OZyAQV5zw@R%;pBS>e;z)QtKR0JeRJ&(mV=@vUW_=QwgQ}fT9m%r=VF4hQ|8<;5*u-% zHO1c)AO3iH^vu-Y&`|WwFtJ%8W#8_&ODZZ2E}c$ZnSh6s+>W9E_}6Zq+ebr7eZ>5_ zMmB1*vmb~A6BQ+r_J_MS9}7FTs*^h70X{RwpCwOzhqECz$i)(z;0BGoH2IQC#Fm`@ zdV=Jy!eahD5b`ygZUg?tpzn1O=0aj3xW7sSZvtwM|gNS zK=S3ni~EDVb5Bi8)iNn9*NOwdpYmnd)6sSIAZf>)=N1>uvgL^#YE3|xkbPl_)SRoA zk*Xbg93&2PJyO*K;`K?OR8rz9LI%Dng`K?ij`|%^X#YH{2dz+oY|QN0P*EbKB$IYn zI}045zHwjUtA&*f=zk{J=ex`W>b{E|MDWQ1^zrop@=Vrx5m^NVPEj$j=!r$5#f<|b zP`R{o$;D-3K9vI|1ccE@N8P)4D*nPuS|Vd-v8M)h6Q#C$ppJQe!7tw*$<%FKoc9F< zBEolXuGh86;fjm1vv^Y+vF7uiCB zNO~GesBVjBCh_q9j9-@oN`KwUyLv+1yXZM@K+9~7X<4kOml=RS-uV0ZT8#yO-7zr)SxwStF zVNjX$T_Sd`GEHqx7VyHn8XHt1C9Ryoubpy1o)A1rfE&D(eF8yHt~7*;+4BE@B94Mj zutCRvG*l|GHHdVB(sFj9_AD)TF1Tbv`o5t8H~^ZLPbc?gSQ|xT6cxF^=8^6Q)T$bC zptdx;nHo$E&xFP@QB&{k5(!2=THvzNk5Rp@s7i8ky?9B|@fQdSZV$JVN*VwW{76OU z7RqFE8MSQ&7(9B-NBkYXb_^Da1^nSZ>zfJ*LZH8P0D58Jk-A`3i&G(ua`w(JT&rar ztaL*PbnNAsWaFQZ=q`g(aE6u9j~|lUF>ruatTAzJB|xKA4i5R@O(@r?FR%8$!sH3~ z!WAW$_RH!$BP5W9^+lSJHEUDup2_z-?uS4-Ws9o55nVILY8BDX`eC52em5~NJAL}}VzrISRxze#t7iG#-mo`AL~wXY zfRlED!pv10Z}xS*9F+0K!XAF9I%&oVoG>@rjdtFVlH`AO@u*k>@pH6=U5K&_E*bDe z$qcoZjdgVXgrb2#&dz;M-w2o>`#w6#`{m0QY31G8l`l5qKP;5DZ|a5a0zHKLLn~24 zafLOmOpx5qzJ0KLjQ`=sTGj;D(VKvSKrg|> z|EH?!j)(gH=j(mUc6PrR2k4qwTRG2!2|k}BP&x<=LF`=< zuc?IaArW|bgMybsLgGnz8q59I8GYf{= zL)ZXP;#?8o7Qm3b*E$X8mHxVd>7c&CO%iT!5tQ0ybTwr{02k^v=rIoPL%0BaV>DktJqU2Z%>T@Rf%GaRoVh_G>mWrDUEYfo`lutGO zy=iM}jc3BsEg$jb=yQfi&vT~tm?%mhfNpz{lOwyQiqg{UJG;u0c&=@Inx`%O2V_AO zVd>BE{sUQXit9bfN~R=t$s}~HNggXXM^B1MX!*hi`_D}Cwte?9)82ds)&cVFq^_>+ znLr9&dEsPOAfShVc}6tMo2h(s&4#sx!R%M_OCBCFUSL*Far9@+Drd5ZH%|lG*t;+N z_(nPT@OV#FLc;DnsJ>KVrS5_Cg=lvDNAKEus4XS)MV@L>FXJAx=tMj>}Jd*ls3@bI-k_l(2r&onT|Y^Q=p8UP`W9zTBRMhYN5ZmXf@YisFjN5`Aaryn?{nsz_rAp~Mm|iWD8~do zfL?6SM&O1rspk4bfZfHb*Bu-bmLsHXT2ph_DEaqEDtbYy0)+SDnZ5|bFkceV+;>+quieKF2YBh^TBVpqmFi`itLfp%#^ebX z;Nz;4VMdQ5R_AsvoBhm|lJIVJxQb!hTS!s4cI{e6ASKz@TaMqmSf@Fsw*$Ami_)f0N%ZzsHE4Mdnm)zCIoIoAu)jj|;EGcG;+^;Fetzgx^nmDMlh>Ig@@ zn@gR1wA#sYj@=!+9SMYv(7DFxdP;CeNQ=j4Z}%Q)`3-)Aqwr$qZ;xvjMe{Z%%cgD) zNlflcQE))(d&mYox!yjvgU^;cZ|`w@+U(39#c1x6X%e0CXs~9MNlYHA6B%aQbAa_~ zP3Za06BIq-Yy9eUMsx@<;c9|Izp+j`cdPyPCmjr3Qk(8v1MrTO&mtvJ#Hg0EVHQ|+ zU*Wj3cAimPIbRyt@7VQ}c!8!Hdy8`_JBCCE`WOL={;t)2Q~cglY!mh^$(ow# zNP#DDC>6ctROyhC&zMK8K~|sJ7OREYQ=U9|0+!x2NC+_ZbtM(6R)enNU_&FkdV9@O z+ttOP7B%-0PWj@Rl!h?vpj(2lr-0dHFQo+#A9w7GTcl@_b?X11%ud;3c8zc=>o(H& zlX^K+?W_0KW?z_AS=>T9VxeKv%4?DGvOV?d;vS^H3-0GavWX#AM^vUIGM4GP-+4~< z!w8zy#_UY0ny}xj8h34k!}-_jX?Avjyz!mYVM4uw$ixp)s?tdK#vGZVuf))Hzkf5r z1Az4F86;4Ck@S1XEa1$*Xu}yWPYr~Q9y^AX#fE)tZJj%U_=;ayQ5bo+F+jLv*fddS z=sAQg%4kZ%2USXaO8^SHx?Y0q>mM?~kJn=Pvl4>1HrVN&k{3@r~FAjX^#Jz}@ zrY&>(Z?QItf=&4GlJO7X$U@uocT*jPFoJzmZ*5?C7qw_NPjUEYG3sWw9qB4T!K+rT z^Zzl@vo_iQW8gL8`%!`H<3Ik4Y~|{Gt@Jzvr>wSjyWbY1H%zm0kayoY-~}nsszL2wz#_PFi}kh{WO~1r=H}+)WC|wue8>3Fjh7dPv=T?E zz6@1&BlI&Lv#)*jR$8t}NT%TLL1Ji)XKDk(+I&VhWvBrUyCEc9-%3>5Ayh>@A1tbo zsp`{66_n@Dl32W}yL%waVZ?+RFq5N$Rlxw}&9`61!Q}bim5kUa>>sLKZAv#*UF!OE z=+w~AkW>lcmuK?+CcNn~@NPrcN&Q8S8M%bT4;?z>Ew>zYKa5T2{ywUQrz+DU_ML4( zPg<|sVrjJO%y$@{ZJ~VbzuawBX`8num1B&W26ELA$7x1b?97GP;9TmkoDv4@DagdjcCn2K?R=&+Zn1=Oa_m1h zG&w;zS+dvnK;Eeh3GrSra=4CaPDo1=hxl$@5i#J2X-=8_Gj4^0#S&TQY}mIH?fKzZ zP)p7Y;aI^&#bc1JW@1aUw@N8q!UmnfR`|*VkiR5A@#6Lt}=J%1(mq~ys2VolY4RL*cLe6gsr}YG&$fSyNuzL9G~XhzpkQ1zk&~{qb0C-IO^W+@9!66 zz&TV~Ft00^IBabeo~T9J?jkoOQ2r3Epekr2URR*cO7D1CLAxL&Ja+(DJ}$2;Zu4~A zT!&sQ4KgFx-t*6-U#g<|X4?7J`JMeMpAKnMtxG%wODtAeF6Wj+2YuMSJ|;6#fz5_Y ztf0~gMa}kKXhB&Qy)c64Ha9jlCL&T|^2Tcm1D@6C~%$e@Jj8?(9lq-AN`F;$zIvBraiDCR#`p;`_Z`xiuv-awgt-T2i3-%6( z=jmt<3Kv)kECLHbzd7tc-To_-0@-o0Gs5-p?YjD+s1mCM2hPTgga(W6SYyH__+t`pZDn<&Z-U}lA}0Dr ziKqmAFK`+_(N}~GME*4hFE1|)@+G)o8_giX`UQ>z{~(G^iQ+&F+{Z&l-C2ae{a-OO zEbT=muqC@~{u=z5lxd|ueZ_o#3(erQ^Lr4@yY=fLTBS}HK>MBJ6O?~vRwztYH`8(? z8?XSQ3P{&ZzL;-+F)&px*SZ|l7vcGsN&*i4fj{)!5&P8V_>j<$Z|gQj2UJQm0!Z5d zUq$&m8IkHwq0xe~moI-)rmv73xcaV)R@gY`R~nT;40vPUj#30hrb+>;d_YvR(-KkK zRfb)&kgf0scO(7XI~N%IwWpKf-p{?1bx%X(3-v7L$A~ljcxdSwnqz&(qeH?ipfRb# z5+RxTzNI04!32VsB~~Q4<|hsD;q2S*eE=G3u7=Puk%@&%qHBaI(9~X9E4Gri{1RKr zh|}-qSl>>lT2addDKsB6!u4Up_fYu~F1cSLwxA7hw6(oKOGiRNLcdZK#RfLhv$psC z`X(o5MhVqN(D5oyH>JbHD6AP-Gn{Q)GBPN}LNNzu_*K@PYtv>#U!h?3ZOy=N)L?-a z0uJc69Kzol#)qtXb6}QL9vsu=St(i9=_^#0oanLZ4s8=6T;B@m{WxU8v!tY#)^AvS zZEq*VA&xG#H))AXdhvn)ME_CNg84MN&|b#HzVvHM4ioOMS2EKkpUb?df0gyvlH%xX0Da<(Ba@4 zNK2tbM~)RdtPxtzK{IPF1ThPSB8b@bzdnprbZUTYyhM>db`Py}$?_`LcL7&)MrUJn zX?#Lb6SOVOZ^Gegs@GLP<;s&S$e*omP4!Zy zrluxNmdFnNWiqlB|2>`1DKVgZ{R*H8{CQGng^7P4a7?~y2cA~NmH8m|P_SG1GVQza zrUsRDC#Y_NdM`lb?TIuJD=iVt0HWvUI*R`5UFcq_ z68YN~Si%h>>_OF>v>a*Z(b3^!`}CgHXYz{c#MajR^+~UL`ZU0dA_S8Z)v@LBOW z+CjAcZKKtivY3{Fzm&DD!0FvzL|6@K&`xLwwLe8!+P$dfSn1A(g_LAoR3-$|vv_le$ z^YZ2#FNm$5Sk~0(SQ@SSF7asl?-~si#Nw%aaGw+npU^8M+v3-QY}njW?KaU0uIE^( z^k2glCkrXS1&eEES=dqc4UA~72S#g}0I87uwCV?m;4ML1w3a&WFQrB+$@w6KD}S+t zGp&ajfWXSvmSkgPhi0Okgz_bw)=!NqNqao|i%<3gdbFbI{$ePu+sg#M8nAkJgUF_Q zls=rACj>e+AhiQj9-t=rRuC@@#bpNeK53}yPcX>m?*mMTm z;-WY8)0jNC!DnNE;s~59K3C8sb!Q&_W5~i$bQMnzUu6}=b|@XqKk;Yem&n$z8oN!* zNrv73*J$d!^6{a?;EFeE5Nyr*Sq+DJWUvKkd39a}_~TJ`%HhvYmyiPz5^Mn2 zrw;XrGhqQDVspU`=OUvXJ47Cdlz_hizf)E|Hx&LDbS{$qAX9aDu2)In-2p95?x;nMv z9zO3V(d%5d7Ak*|hKH>|4di2_CwOq{CUsT?rY!d_g+xM(H|dkhG}$Ssz19 z$(%RJ(_0fE&H#<5LE`xZG`2&kM@>B^qc$jH-RNt-BjMETzp=U54AN7?S3DcLOYIN% z2GV(rJw5h!QQm15-@G@dQbI}uQ2gx7GgknttC%gjks?WF!X-fvdj}vsJQg@39_0-! z!rj=4L_jvjmX&$tQ-`?z`sCaPP{LL-LrtcD0fD?-%@@9?bsaT{--OGr$73+AkYKjP z+4C8f|FgcD8=OeQt8>q`16ac<6IJvwH%;7E5ei7Fx@{53CS3mcr&7D9&C@vg(YEZ_m<E+Xkq3g^g|w#x|M8u*Ndsmq+0?gzW0?TTp>k~kHD}A{spGWnfN|$| zb{IdMh1VffCI#o&OvsEie*bR8e3NcI=KCMMKhpfbIjfI&&ex$p`&ppu3h9x{TXA$b z7N6zUMIiknUT63H;3(p$O`ge+R*{0P5Gkl>WJ2~7x*eZ-Yf-yKLE;B6H0;efsoRv}*WUidMv7vw`XdZ?3XM^6~Be4W&w1 zxD6GmCrNXPXUFXAU*8%_G0Ixs?{Vh}#g%tS(qSd|Aa+)+`jDg+Imf#nv^HuB2Mec| zr{>eM*4M9}y>pM)xow<{L(L)R9$@IlH*?e}h(wrHGTtY?4IP@s2OKio$gS@8l~k?| zH>!wOk}O&IdFtA=A92`+_c_M>UHX439tNPVRK8z8_PQBcdHiD=cjA$MRM%ap!iOf>+EJ*d7xFFEV+-Wh z+zp-G%gRR9%=<+4YVK;!v5JI>*gl2($MZLKW&qD~#MqMdT0%xKS(#-*9%~wtXPdh| z{x5ff)apL9FVAGH{)O{tlxYEWAARG!AM5)7()=sFmLsbT{hSyJhXuHQ;R?Oe4c>R= zkN>=Hl-g0Drg2DI91Un>nXO#$b914N=5IFWcROpV<|(hd`pm(D+fZA+e*VMYq|SYl zhpP4;DLoR;e8E#sud{O7zW+~L)ufLE+>PRvulv=28r^)s^NfVfddvrF;*K$G+?#y) z(xux^o^S$gz^bEA)Hg|S!}%N);8(w`+W&*`ymJS1M6IT#YZ!=iUh7d9lGM3*l3|xc z?cN%3-Ruu02H0qi(+;Q)8@aEf&icuFf#;mb<~TT?LyiBJIBsDhhCG`e_JK1fdEgp# zbkJDeEf+30pmI+6z~vyTVQ;v5%?Inslu5H&`;XWyO#OgDwse1n2%z%U60)*O?zTm{ zB4g#Lz7}j=QDSSco_-YpR=<`{54UGJolMuYjn5Jm`K_&uFO;Pgev$!t|5uX?!t`wS z#5b3RYIDoh=>jn7MM?^k@ecqEIf0tW7Y`zdcN89$UoO} z(oDta#`o>dkx4>~AmA||q|N>{kae1nN4mXL=5DiQ^?jbmMfolh1D(LIG-$hl2NtX1 zNtKQ%Td|n$Z~?@Nf{L7+yud{N$(&Wv8;t|2tt+2TI$dNwApbN%?wv)w^bW50PhM~_ zB&a%8!k5?aV(OveJ0)e}Bb@f_+xOz-%a0cfOdxQp)MZ~j0fPYJ9@Nuu5L_k~2&$8H zrl-!aR#@PYw7Y`=BupJ6U2vDDY01&9Z9+n4JdfdI4@pXDDs7YB!4(%{ln!S!Akw)z z=&E|9Qx*fkX7U-qXVQvL)J~jucU|Va&%k3s6Y1#?$IUh^e<1+{(#a25w?-Q}a&6Eb z7_R$hxhRgd64vHXKDKuYv(PjY4tMqP^(LLzu`4}TQ_U|s+*QTaY}oZy(lN7vN~OsxLfgey zPht7}Ke9X*;?5qHRzAA(pivgeto)g>U(t;MZ0T{k^i^JBDNMnoAMbfE2ImiaD5Lw> z>11Yn1Dx~Z7i?C(;=@Pds&dfx%y*aN0yUucO{Svwun5xL7Q=zRuVH&O@ZO$1un%zb zQz$VUmdkSIV)^jTgST^4TipJ9)#1)v<5NCISi?@LNR-ZIIucHT!_sSSJOEPzkYT@{ z)Y0FBcF*&}5ANVqFZR9kXQhK^=uPr_#{SBg7A`Px>Rh!we2n)Too95b&QIPmy;QPy zWLtbzR+E%Ly!$CWI{)Q7h{37P4TVJtehKSg^*j_(qpa~%>b;af#hHe;fF%N9#h3H* zm+lPjQti9fKB9XMfsDT_02%Izu5B0RMqm@&mU|x5FAzYe_q{}7Q4XF5n0!0W< z_-<}i*Umr-l>jt-?e!!0d*ZAauLxQ=1{O|koSK)j!Q(&k`g6y03?diw^Z;C-U4gEE zR)avv<1+~x57;Pg*WYe*H)`ex9RMGBaB8~cUh1Uwv?@?8YG{fxZ~;rg(^rgSlnYX; z&=pCKz8DB^EV^GGk$g!I$3a}e?XUI=j>y{gA?jSy1?PIVtU5n71PX{!%h{^aUknNO zF<-q6y7y6bJZElfL&9@ltFDst5wkK7U@KJH`1)Y^J#8pX4v^WXZmaZw0 zdfE1vZ?LF~7fpwLC@rD7b_zizYF!L>%hg*faDcgFG$x&rW7E zTNBJ{83PFgHUJ{5na%g#laug0H7*&-HU`Lj>drr34fanj?LZRt^s*L?wo$8AaF`R? zVDh4uOod2)#{5xa@Al0q5=>NxKyTA4+#p~ES1o3xkjKRLOa?u6#xEZgWe>fZivh6y zIp`Ths3sSW_Z7=iyg&TI0tXl12I_lfA2iWsCO{@(ZF!i&!}3|$D3hjy(~SDw=1}Qy zSWjsnD@0N|oevV8dmfdzg2eqHscz5YlpqssD8^nzTnQ|k+}l)#MExPCZzSs()OI22 zKit?Xddy>N*%+Kb&Fc5D?%(RckmXkl#kPT3LirTV5Z|QKGpMD9-oyr!G6)PyV8jI! zkv?Vm{`Ll+(MeVEL}cspar^L>npB|z@C|Fqhzs-kku7D@r0??&jIBFYM@pE`QwX92 z2XCPlv&wS*@d+-WMz)9|{JvjKzcBxFUum8m=Ejh8ZGH3Uux@U-gvU9$Wxfk=jSI46 z4^lFo>JTVmb}hg~QWz?Dw>XNu_L}(lmA-$R^J{eU99g3qJU5oigwqcSJ12k!B8a%4 z{;N=q16+r_6rG4b>0_>hIKr6!nC7&^RFf{)uz=f=^Q6NTQydv#( zypM8j@AeviONIxa`eH}ySz_|X+eege2-2v@b}w|3uY|HU9tAZ|hQQ0x`@M^a0jIY0 zMS|3bnuy|LF^28Ii2UgEBKWVFM8Fw9c?wEt@~+NcOYP2 zj)NbE{q=9vLEU%2(xbpDMhird$ifxGBgazg2K7Q@@jK>&O_j|!H(51IP@rQz+eXy9 zIe4dNHONIOldfW^VbS7sYV`NtBc-rjdi#(EP}%`xqq*?Dk%+-f3bL{#z}kw6%}C;* z>iHpWSQHWWA}jjq1Z8m~!)H;m{0werI+BW2tzAK+`oA@Q&DBQ`Zk+$ll$qa{6)5z{ z!11Yf7szLf5yuoKv=gEoZ{O!YoAZaTnzkA1T|urPJtr5&PwjSk4&o`~LdJZ}%!lsY z^m9m`1g&5rojnen#+~+XJjuz+Bfo@{B{e{G7D2j}C$vfh$-q7Si-n$dUPQ(MZe?n4 z$OV@H;%lU!`i7STH{1DjiNZ!YWQloprFQ^rAgm8P1G9tI9fC8!o*F^O&G=p}xV~)B z*O1DxCf%LtC)I6IPDIA$K{b*hAfV|L3Y2|kN4R>NHK$riatvCi5}OK3txEn^_^)c_|WJdNt( zQ|Nx&N(E;PF$JADMiyzclfED=3q8Zf~ zmt&BoK_r=~rDV82u8qnBe@Dk8?~i))d%fO?RItbK&mMy`RCpN@Ubp&og41jYI+XZ5 z202D?Ui2$>p=Uy@n2~3z3>15FmYZCsdA|Nw70>(wR}Ln`j~R(t9@XZd;uCRVo^}@# zPdr>E^P9A#Puy9;yX|2@N|}+~@}>M2fJ6~(vju-}>r88^l<>b>-A`+ZmjRs4{wE+L z?L9rIxSiULS=fMT!WUb(b z>?kQ;nslflGUTrK8&V(XTb`VKgKlK?oiK{D9*TQ zDvHB-s@+@ZE^O5(@;TLBaLq=;Fa*|Y1i&64_fbeu-4bliw)0V3h|(-Ryh%92@5hb7 z%FtIoV~g29+@+4ABeSOZ?+8NPiC!R!*&t)bTg+IaqTy$4C!xbg!{`dIg`Pj@J#}}J8F*D}y2+$s z$;7pz-bTyvRk~fFFZ@^*QuHhHI?17{;A0=7mHgF}7VA~ctCkE`Z^y;DcZOVhQCjL( zVQ3i=N~&{+4lN+(+XeNK`h?iaCkX+^MqjCtM>6#TDL*pxgP3q9-9I!02EFaL{epGz zs!K)xlp{&OpBXvwV}Q$Gn~|6h7q}uuqFmn4)Ay=ONRLhPhkJpChg9LpRJN*6%zN)m zSPjLMM_MYsD?3nrcEE?Z1haE@P^``saAK-zD_`C@vK?6&ZVr)Pi;=hIpJ=;`Li!BP zlpg=o$8aQ9vLfAaCCuN}k1pQ0Yc|9fau82S3SL1xJwDM@Yl$`pzXf4k)i~bg%TWew zE5FZ7_{8w*i}Z6ofG#${#PO3)Sx+CX;v}ZS{ZMxzF~|OkX270#KDp2k1iq@In0g(} z!=-?gn3A`};SKT*9XljSN!#HEX?P|ZFr*XhMQ%1mMk)+QeBVlc=rLA`RK?x~BY)ES zpj1;NY4$NCInGzw?Ll4JNHTP#?1B)L`?U!!THeiCak5|_)e@Ph8^m}xKb5i6 z=rLA+p-c?@eq8o4^n7t4)i__-U@9#n)drdQ4e_6h;NjqH%HdbcScyZ*Kx>4BYGXy>a=7J|7-n&H44VR$`lCnj13OV3i!pYtayW z*|ALxg&a7*73bl9-P&6EzzM<5>}%>dx2DM3L=l`%Lyl(}*F889sd_?J0X0=+m*2$;q0JaC^qAb~FW9A0m8$zrYyz9# z%lK5*$xQLrZH}}T2>sVOya4BZji-HY%0b4_R$9q=T{i?fx0j+Fe_z(tRYfsA#dmw# zfU2a}K=x%vbk^gm;-gr6593osQ!~ZyAc!O5sVy4p-(=n@&2jP36f`iuSb^Y~-;D&mI5EG9`}t z4+=_tM)j4iOrZ)#6Idi>1h}PyQ;o}&yIiZ#t@b$jg6TmFJH(LgziY?zZ79!K5y}s) zt+khpDW9~f;HEtBjtX4%>pXb_SHhiEC!9yXAflRTPrSNf$<8uWQ#0dhmtRyGwks3OOaK}!tY#|0mYA7BSGcN0* zLle^gy>^>vth_gxo%oVybzr`C-UjdV^QQ>n)+C6iYR-pjA>M2d^zenF;2Q?s1I#Jf z8EpAoo{_UcwR|4EUY6|zPKk2L9`qGoiF`-{=^BGGK`yK4bcom&?0eljTipV3kq{K@ z=v&hidSip5TW4Ywb{B5$(_Cq$TUmMA9{b%z>=X8cjjb&!W*Z$2MSR6)fA;h_8xn4E zV2A^E!g%I0%S<#S$D+80 zBnN69yc4D$J?*Ty16soiiJ_ei^KU5#9M1etU7WHUihoZDGQKX{c_!+K-hC9C38?p* zWV>`eY=Gk2&@Mt;@i-e?K9akieH4vQa)*B7uM6R<%e%1hr8E5@oL2$2JC?daN(>7e z2ofAPN@srU*3TdzUn#01$h4Gsn7oi7n8* z#c7Na(}mlexF^4A5nM$4Tiux32dG{w(a8S@b-U2h)ww|$p5KJiQeOGRuIhkVPR6hb zKi4?6@aSvcWq5tm#>#4Q9b?x0HY><{~nBM zV;@_9BG%Z@y)OUvewOe72L`a0uuL*0JgM2!+nt12gIf`TrmT+!|IOisT( zPnjQ=M0TJBTxa%>@8ZhNmKha6#Xm%%0(p3R-lwbGiRwt51a6^-(V`h!zR6hJhU+_Q zczmWWG~MtIWE1diKYWXk5`;MrpC1=6HqU8*LmgV!YUCS?b$Yc09nKVicM^Y_hAv{!M;@PzvnUvu8L)0aSIu>A|c*W90Hq35t!rg$r(w|S)uES znp)m*<6xvn&`7}Yz*nb?^nh?>5kVh=f|b0^%KwIk8=K9z0=!oiDbuHwR(L?~lf!si zXUdmUHWi5$Zhml@D?Zb#A_odY4=|-CSaC-G_?x-Z{LT-0CS%FFs1_73GTA~=@UTQIpeqLuuOr(DQ#=}iKINk;PKy&e()*S@}XB)66QEK)nM@a1LHoi-ys zxm3NvW@R;VZxZEmj6<21`^BRmWM%J17!woYv7%`W7D=SL@C16KErb2>&c}qnA*~xk ziNW+lVx$&kzHs6*xFUcSylF67?v6Yy$@y}`a-#3O5bx2UAvf~t8>PCLCO1xV;fw?% z3kvL=NGtCe0v!w;U)UU?pL$&;Wawjf;GhJXsM3#QN-Fi|r!HJP8W8AjG32DegeFH~ zT>H9@wRMy*;#}MF?DSm|&bfIGy=T&j`CRlRB1D4xGr!X1Vvb(U^^11{B?5|P=3_1g z1Xs39o_Q@K`Cvg7Dp#iYdMs;NM z#;Fqf^t{|I?hi;FHL-_-YBME!H8TtMA<~X3~ zaQ1oHSjRa{-yb2ytn=MI4zIbjwn6^yr>8Pw1jEH0D<&7^{WTN`x5Lf^NTrDLUTFVv z^!LnH4jvXMq)@mJ)w$?4QhEO^&ztGi4AOh{s(UqpgVE^ONmj7Qe9_~WK63rmzvu}XxP0|)C&iD0^KP093i;{_ST zi@Xk7cHpMV=W-p#yXTVvSME5JY|FF%-v5GO!AzAHd3t5iWjX$YN`ex~UEe%js&sDH zhSL;bB*xIyaeyJS-#;kH&W<5nC|K@{3gie?YMu4N9hoI+RcfXeOC0C>_?#H{ur84l zt8q$jgt{XJ?U)^G=zD)FEVO4+yD92sWUfxabwdUT+yfppNqA&+?q62y9cP_uZ^Z@4dS zsrT&gg?A<=xH0wy!`y|cg5C$Zdh7M38#Q_lXZjZ#29g7 zYHUSyrA!eHjr$UkJEwnsVTlwu&z7kE4;&i(+Hw3u*6buIkutgcTI+2=>34%)SOigda3-Iu%r^w=kR8hUV6W$0guir}w+o87FAP(FOeTE~Z@zy^+2t@NWz;fWCHEloAkZ zU?>~zAIQq%?7IWi%J)bZ<2RrES-cTaSVkiW`LPvbY0@S|A*4ojWz zS1XIVeuEKyPxJUJ#bu^}3-0{IT#{`J2o*R^l1<)(^z}1-snc%6> z!Ih>?1QWs-6d-f_eT7H&H*Nh)cwn9k9Yf<=cJW_&l!1XeTUWjwz7^`fi&vQZc`E~b z8yqGo6VQ+s3FxO_b~mU}$aM)P7mko?2PovH?{5i(m{pYXy)r@U={y%a#QGq0xbmKY zNeEEBeBlY)tCX`wFM`UW59zkP@gkx|{tp-?D%aaZtc#({f9r zq^bkMheYlP5qeHyo@AVh{m|%WPCPwQ;j_})#6hWRdgveZV^)Fui*#hFb`QIN^!3Kv zra=_PY9No+5062a41Rge=>Zp!j_jlaJRl$0wKypEQ04qw>5^A(V`8Ac#NxR=u7__A zFfTVvFcfY>tDSaZH9l%{5 z;3^_#f9KMaG<`QWx%cM&?#y?F{*jR1?|kn0z0U6(g~Ibms=M*BB;(c@NrpC}vojbY z1dC>_W11DKR?Sk3@qE(!mGzV6|3EP4OM&Fe@?| zW<^AQBsTz1|EwQ?m-gx|ELUqcD!ko(Fu(aD0EpahVOGS32)O}(dbgq-ma8jKn}!7ShlBP;h_5`6Fv%nEC4`76*X~QV41qo6&)Qt z1IPa}6ae`E@OG))Jq!Tx0#7OAV0;R|CB1XVF$BQ!^vXmEfQ$iHmac820PqArs<{j5 zS{%^Pc?^2{`k=3`pC|Qk-`Uve0F9-SXAht~MFH>;fKSP;TlEnK3=9keM2$8lY_y)@ z#{;Of=O_R^0-$XQoblbNYjyJD0f;C7J^+wlJq}-f`DMTXK;e)>0T38~a;rlSKtKmaVzfUtjhS3T=y}g%QBsoPZtZRl)wf_LXiI|W8#5A3v z0NkfBLOWR#kJU+C-97MJuE{R|;Bl>x0Bp9Nls5qP662$RC+evFSY>-|_`uvc~tEG(~-$!7BhlodmkI(>fqe0PdTj@!dLc;smT_vUmaDv*y!+8Xv`) zd*lbebdB%n2|m>np7IrdWJ{0W02EuCJ^>K9r|M^goQ&`32^t$4vwQ)-K+fZZ2B7m; z7i^m1O27@kE1D{3YPCxzB#bZPd&*+59GDIOndT0`$A7o*L~`pCCW8pT>lszh(snVH zK_OS;dq7Y#Spc?M20-83CK}^=?s-&@*u=?93O_8jf!*mE`m93E#&@f^x!JmL8~|{< zuO%VhVl(_`^BarZ$%T(&w6b?Q5-t7U>Nq;=GYYvI->p`M>!&31r4u&XWXU(TLtA@? zsEt0}{6N?2fLzjsJhKZ-1mMy3Efm!FBhT5f^ThtP^Cd+vZ1PYA5dhTqG6sMeU&a9Z zVJ|hlYyrUF4Vy$~+Y|sE^iD}FHHMr4IAm_2#*i}rX1g`z2*`+*hxyt%bb2Jii)!JQ(Wh>wS((6a@h9u^KpV;D96yk4LZ7)zy%m zo-T;ty_J@h#?2?Xr+G&~6acJcG+bkFLL}xl9^E{4_>>Kmk_w4?vS3$E3B(taLtLR2 zV)yGIwxkAj?yrW}!V1`xUkVA?MX+0w3rtGdwB`)>`=;so{z>vkQp0W0J2>x=ls++xg@uLC zGl`o^q5$AJMhA&(@~{RNjYdI@Z?oB8&z?Qwb~3v3ExI=U8GS4fkFrJQfP|d=z$Pb; zJ3qiBsU!}A9%uHCXuwol8J}TQRaI4xJXXgNSB!7_XLWs|Nc|c^en)Jvj?5dz9wKm0 zVyplcQ5^^Wg((>J!_f#bhK37FK8%Sl|#;LfF}V*+OqtzxoA zOlbJr0v)H6VEOr!@+4u0f4%eK=2Wh?(=~W&LMCv;bHtAi2kII(L>sM z4*~vLNdbVmfvtj8AD4r8?CfFubEG4lR><%nZGV!q{YOawaKEO;XV>pF?nfzP{E+r9 zkrV(~MvG6gey@-%wP$Bs9=^^xGyHuBcFlM;vPW^x!W%AC4ws1Wf0b!r@~c(?wc3b6_fkBPjqu z1OQ$odx70Y0gx*IX0sXYX3Ho5as>dBC;f)x9H0Qm6aa&%cFNVmDF8tPKv}hk0w8Aq z_8aOc0CEPPq`rv)AZGv$TWu5oIRjAJVy6Je8GtrY9FYPbV*oG~aTaT$0Lb|?@JY6A3fd=3MlG9HtRX=*krPHgEDF6Wn054=<&V4al5qrC&mI4q+ z06bH>YBUUf00HnfCg0~$XqX-z%d%ls zP^_BiizmU)KA1rP2p9lLRy!gywXeckKE5Q7I7o_9Qvd>(AK*ncpZ5ZZIH&N%3*5U| zO#uj8h7bc+`h`zVfWv|>^Mo=}0|g+^If6pj3Rq4qXyVEshE0df>=zJAZtSAG%fwAa zzSI*$FR*wsO92pLmauC`O@M1iHt=g1JzURJak`nUgau3~yuoG-c@n(v>C1%B?sUP` zD?g?Hh&@f*h-_obK~nAFqQ}4`r7z3Eoumva1wdi|pzyArdqv<=ktnj7cxq$PF$#dh z0Kj2l7x4mE>0>fAamSOx)&8?qtG$i_ut-`3Bf^=BMJ4&DAxLfzcToT&2Ea{BB?kas z^#e(5;sQAX@W6^Ur3CO%s+91yEsj)>&OXCXq# zoK7b!`SS}P=Kh&T4?Xb52@lXj3&66a;eHDfo66)cJ}w@@LP8~H{B`fW2i@J>6Sh&5 z0N|VF>vk{Sna5XzhfBiniynUhDh^M+zOq6!d(Ig#HDK{G&p=mKmuQUdIYBHfErmr- zJSj@U-+T80$jQ!`Qs^9M(-{PyO*HgA_BakNZyc2$It0%@^Q?tY5bdZk;@myGd8t4>x_SO`(Cy#}|3-Qt)22@4J7jGjdbVDoVphVK95$&

q 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/logo-180.png b/site/public/brand/perl/library/logo-180.png new file mode 100644 index 0000000000000000000000000000000000000000..bc1aa34efb414a2203dd6f2941cad3b2a10b202f GIT binary patch literal 5248 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 bzah$;C~Nj6FwDUJQY6rMY@k)C;Q;?XgQ*(= literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/logo-192.png b/site/public/brand/perl/library/logo-192.png new file mode 100644 index 0000000000000000000000000000000000000000..eb8b62ff43b0dd4aa2ce3ea62903da12be1bd8ea GIT binary patch literal 5586 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 VPSer74F|;UhPJ`AN==8T{{fQK8>;{S literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/logo-24.png b/site/public/brand/perl/library/logo-24.png new file mode 100644 index 0000000000000000000000000000000000000000..f90fca70f055486e48c1db337dfde454047a96cb GIT binary patch literal 778 zcmV+l1NHogP)qt3sIOMK6?~ z5V;7+LR0f%C^W3KGv}03v$oO;-IjAM+s?*vJKHjcdr`7&Z0pSz6uRix{I%zhCy$=J z*zn?Wb)M(@d4A9Dd7gvi;UtldlZkxX3Tcs=e-&J97Ph(nlW~QHaOm94N1k71Rz-#{OG? zR=+tMF&zkQPf*lt1+~ou-QyE$d#*Rh)&(+Wm{$;(nay5+!Y!UDcCy7mt+Z1=wWIBN6DLqKu%^;QWGR8_sTlKR|!<1$e{PLA^m^B1u_F!GPVJHe@5QSd4-1TS|e! z?o1o%^?E_C*8@QifcGdtq3i{fN(Dxv5rV;BX2GTIL71A_x<#mLtyT+N>LC!n^+Fr< zoo(tvM;tmv-SAZP8cZe=Q&mbqAx?s*N6lFc3V*5A{H&E}{1;_fdphpmFXpsbT_Wu% z+KpR)n*3MAkWNQmZs{y9u4y}2e52)5Chm4VuHzN#O`f3rN)jpuZ0v3I`FwEpUWZ{< zb%Rt;-2mB;S5_J12vF$kr#arH_8Z36&`sW!;IwdwBRH?Ir93rN&qsgnsNjfVY;{Kk zhx#mZ&VqAlYf8ZdwI%m0I;t=+mn#$sK{y=dy!V8~nR}DbxxXpzhjw`%gOYg0h>+lO zQhHbT94u^xc;byZL&Xkn{-#mn{qGHYM@vI~ty98Exprnsa zqEz%`{Hc&6x!NU>EQ@Z{&);usT)<_rWtYoE|NTEClH+>+0Ja?JSX$E{m;e9(07*qo IM6N<$f> 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 O0B~PkMXp%Z$oqdZuCxdM literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/logo-48.png b/site/public/brand/perl/library/logo-48.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9b9d40d0a5881eb50e33207e6a9fa89b6097af GIT binary patch literal 1493 zcmV;`1uFW9P)q&Jw9Qc9sMwB>$@Bn;WZaFf8# zbB<|4T?;+sbd)CFmp1+Xzn}l*cYeR$p->Rb-p3d^c?3hd6v5B|8QO89bvZhdcASEK z3XBVh1*QccOILdD-2JZI)tezyC1c}L{xeUGaSuRQD@2{nzZa8{_cYl6Zhb8`-#f`| zJ47LK<-GthX%Kbla$=|ea@6B<8JxCO3fblZ1t>PoLTj%T^k)D1-82a7o-v;Q-|Hr4 zPjXa?TLN&^G!IVK2+YpTZm8+$X<+(*zyLBhD%cVLwjnU{ZndF16;=RzgOd<|wlB;8 zMBT%L0CbN6U^hz-m*kyrM%oEc8vxW9hyiq&LkzILS_d|VbIpob;EA(^egVXWAwmG% z7F*~5F!Oe&>!C>vW(%Yi(U157ko8yz0hnz=J^?bh?JJZ}n0L!&voBTYt?#X!_*dgp zz#(+4nv6C){JO`<*N**ZG+Q1}LS^19hr{uJ-{SCni9RUg*Xi z8w}cqR+J*h4q;1ukv+pM5Kcblf~!i z%VaWmEBhK=4}=up;L+6$0Yo|@OifJ%o-vM(Lmt9|=r3rG0$}}1oG#H5e$rx({^aso zo|1A)0g9A=5C)JbT3}b1GF$*|69&ky|IMo_vF!jp
ZfLE&8w>Q9xXqesB0Pl)4 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/logo-64.png b/site/public/brand/perl/library/logo-64.png new file mode 100644 index 0000000000000000000000000000000000000000..d0b2e95e5443e0b3fa9c5eef73a578e17392e06a GIT binary patch literal 1920 zcmV-`2Y>j9P)1RCwCunt4otV|^lb~Y7LZy5DG-j9vj_CH9EBoRIGyvzmT9KQ`0aUK ztpTM6ec!fpH2MBR$oo9s&+~hp=lA@chrvKUFQ#n6ET&91izywMMaaO}^4@zUk1_5S zr@u9X1kThk-OaJ1>OZa@kaVJEp^V->2~JR3lPrkxT1yl!|jfJ>S-N&w2V9v%UB1gQYP3#i)xcq8pE zR=_!_2BJzE;8~X3ZUCiPY7rpTwz?O94@U}eL+gZ2sax9M<)~!40F-N~MS!)f(CGlM zd1dqD2AYg*uylX?HCq70I%)uH09FN{Z9ZmUDgPFeSP#sz*Nke)!p4a znx(w*C+<|Dc9;zNp59(s%#WAB*bYLq3C?Qz$@4=0zySGohC9uV7ak2NX|JPV&}F`{ z+351lPa6O=x@M0wPYZw`q1S3_}eF%%ROfIuJsp->1# zMMY3nRt9KCf#&9B7#tjQ9e@q|$|*HCRnsU}fZW_%V6j+sDX37)z;QdG|uKgia-Pji6VXrv#&(}WaaSUj>3JO`YSlyUQv5Gi#>|lDl9A{*9BV7 z0)B)9&agOSsNs;dWxl<=9kQ~rfFOvm$W-p_z{Cr%-pSgWlm`jS2Ww18NeTVO;nxW< zq#y_?mC9!B&*$^8c|0OJ)+Y&;uTK=5a)mY}3z8CB5kF%IQ9(gon zb~4=XL(^_HYG3OV00HN%?*>gxP38sZDDI5+w&;Ui+oDdnPLT;-tG9+^W@h?21wg(+ zXVE-fcye-b;6QxJ-PqXJStNjOqlb{dm3r#4kUNa!Yu=?Dz=~Ws3_L70OeU>X3rXn& zEQ~nzyEz=)0w5p+7$2+|ni7B)*)j+%kioI?MpB6q6(m}1(c6P!kRwg{R=Qqy-P@yqU&h>GsypFi^#Knk5 z0O;uKq70z0NCZAaoo52*?x9|(JPC*#J6Gg?B~+z=t3o&I|^C^<|z11E3=lOhAVxj|HGmYbgUz z7+O3RKq@a6IyyQiUwka#$~_anK^C8^_To#)ii!$S5{ZPoti+N^rR1FezR$A;AqCYB zJQBbvR&SwItrv(*rN0R^76nO{Dm)K> zH9b$%!wcw~?@QD`5K#bZG*x=7Jaob}!}otly8gcb@VIud1U4^9ReHm}=qA|ve+d9z zk=dFC4=cnncLMNP8SK2LvU087uC1}LvGJTc0L)&y1&XTboC6@fQaPnF!f}579aoxP zusa3{s~$Y)U@QpQDfbNyQ_T<+T_tp0Wr6-g)b7+Khh{7)WNSleBk_ zvDnXFN40_P!gtaBR1T-q7{rQ?K6bcY;XA`XTq(BLHx#WJ#?n_81yTjj+S=;02a>q+ z3WWmFQd8lZjhkTE8*f_d2Zpt8&(DyL?jP~%6Fa^gL}p@3{QZN`2egh%ho%0Doc2)C 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 P00000NkvXXu0mjfg`Oxo literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/logo.svg b/site/public/brand/perl/library/logo.svg new file mode 100644 index 000000000..334116345 --- /dev/null +++ b/site/public/brand/perl/library/logo.svg @@ -0,0 +1,2 @@ + + diff --git a/site/public/brand/perl/library/maskable-192-dark.png b/site/public/brand/perl/library/maskable-192-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..13930cd89c056151db6317bb60e2c3938573adc3 GIT binary patch literal 3101 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 WKN?X~d6ka!Kwk%=U3&3)_&)%dnP$rX literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/maskable-512-dark.png b/site/public/brand/perl/library/maskable-512-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..c94ab1d256b5909690d61cf8be46712e931d5f4d GIT binary patch literal 9321 zcmch72T)V%*60phkfNxlfN=CENH0o<#4Cb|fJhS|ARr)8g7ltP08s&jL$4|jmEJ+B zfC3`D*APWo0z^VjLjIkEbKd{v%|CD6y)!Q}ne6QETfKa1t-T{}8t8I!p5z1ofcx52 z?OOoA1YR-$9JHUHla~v?p93COExZ7Ld4cwYR0Q2}0RU0pn)W3V|MBIi2qfHxvi%Ur zBx6Fr-Sy^R%@)@aclZQrICzD%P2gzuY0+=77MG5=KI*sC(`&0=bWd5S*G(zErt9m} zU+z4>YEF5MX~b?lvODh_cg}64zGhwn8Z+M#!E2JOyiD@xQO)$~*4@MD!GULQVzxN| z765<%FaY2K{;kXZ6ub!y$_{YQbcCX*;s5>e-+}pWq(lKN*8fNYpyK|!0!1|qR(%&g zRBi2!{(NE>s!Gj%#06FJ?9%1W5vq!z%>M2PDe=NVsjC{JwT4~Phm(7ED60Y^=sL_r|%Nl8W{oHD`7V*nEXAU zoNGhu)QyJ$D$jd-v{rxeZeH9SID#?`rOfwO{T7C_zfF|H1O)db1bvmNUF0qDu35N_ zoMlB((}=38{lks&0fL-w1Jl-8$r}Ft_ z_f6n&Ce$l%go{$i&Ab5@h$RPYRG1 zaOYMhi_Rp>v!&2(V^yI#WkBnsVi

yQmP0_tKtE%O&9LYWAfUQI3#jHPFIoFMr^% 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/maskable-512-light.png b/site/public/brand/perl/library/maskable-512-light.png new file mode 100644 index 0000000000000000000000000000000000000000..be61a10e4850234db72c25060857089b8b2561c3 GIT binary patch literal 9235 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 aidH>y?#SDm#1{bgcjKD=)x66#|NIYmu*HY~ literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/mstile-150-dark.png b/site/public/brand/perl/library/mstile-150-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..34ecc26c493fc6c2e85fe426856349e7a6bd916f GIT binary patch literal 3020 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 LtxbwiSD*Y3QtG{F literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/mstile-150-light.png b/site/public/brand/perl/library/mstile-150-light.png new file mode 100644 index 0000000000000000000000000000000000000000..e3685d2d4395621d69f9df3d25acda5fb862e1f7 GIT binary patch literal 2992 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/mstile-310-light.png b/site/public/brand/perl/library/mstile-310-light.png new file mode 100644 index 0000000000000000000000000000000000000000..d4e4f761380ecf0976100b70df6737f7ec6b30c6 GIT binary patch literal 6457 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 AW&i*H literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/opengraph-dark.png b/site/public/brand/perl/library/opengraph-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..19dd72ab8fa4f44adbc1bd9390ee90a70f28e4d1 GIT binary patch literal 38701 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%0DAl1Xyga7?l*jplVunqSQjSu$l)e`$tx%*(k@=f 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 U1=bW;Q(#SjH3j}Z1tbIi0W$tlYybcN literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/opengraph-light.png b/site/public/brand/perl/library/opengraph-light.png new file mode 100644 index 0000000000000000000000000000000000000000..00912398edae92dba03e82413532e5fdd8ad9136 GIT binary patch literal 38308 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

vrN{7kdG2X6 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 MboFyt=akR{0Q*aItN;K2 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/safari-pinned-tab.svg b/site/public/brand/perl/library/safari-pinned-tab.svg new file mode 100644 index 000000000..783fb5d30 --- /dev/null +++ b/site/public/brand/perl/library/safari-pinned-tab.svg @@ -0,0 +1,2 @@ + + diff --git a/site/public/brand/perl/library/site-dark.webmanifest b/site/public/brand/perl/library/site-dark.webmanifest new file mode 100644 index 000000000..ead59833a --- /dev/null +++ b/site/public/brand/perl/library/site-dark.webmanifest @@ -0,0 +1,36 @@ +{ + "name": "libtmux for Perl", + "short_name": "libtmux", + "id": "/", + "start_url": "/", + "scope": "/", + "display": "standalone", + "background_color": "#12161D", + "theme_color": "#0298C3", + "icons": [ + { + "src": "logo-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "maskable-192-dark.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "logo-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + }, + { + "src": "maskable-512-dark.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/site/public/brand/perl/library/site.webmanifest b/site/public/brand/perl/library/site.webmanifest new file mode 100644 index 000000000..a11a4b6a5 --- /dev/null +++ b/site/public/brand/perl/library/site.webmanifest @@ -0,0 +1,36 @@ +{ + "name": "libtmux for Perl", + "short_name": "libtmux", + "id": "/", + "start_url": "/", + "scope": "/", + "display": "standalone", + "background_color": "#F4F4F1", + "theme_color": "#0298C3", + "icons": [ + { + "src": "logo-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "maskable-192-light.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "logo-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + }, + { + "src": "maskable-512-light.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/site/public/brand/perl/library/social-square-dark.png b/site/public/brand/perl/library/social-square-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..86126d1403dff3952da968c9f5bb4e3d957bd86a GIT binary patch literal 44221 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

S3Xc^!h>GPW8~mUH6+Hjm3|)*hxJW#x+%?{Q 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 z

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 H>J<5JSal7# literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/twitter-dark.png b/site/public/brand/perl/library/twitter-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..2f701311b4a7ea0eba6f9eb164d9509009048197 GIT binary patch literal 38505 zcmeFYbx>SQw>}z$K{I#=K_+SEc9pS_wL=pl9YI>bno7y(tGzF zXn-C7-`v1H%K{&0_7a+o_wHffA^+dMmyq=I-aU$Yl5d4o+-A0uUE@^76H3fh+v9o9 z1~Aw9Skpgz_R9sKe1FyYD)2r&4$gg1Mb>w36e&L&D?qtOi?6v?p-tu#FTfXG@LS${wchYRW#drludF|OG7Quapv83)afBg_& zGRJRkUfZ$oW<-EdjHz+y0-M0D_Naw9_dDlfq^kiV+K*CWb+6VYbni^|>9?6sZini( z?&_MEpm8dEg}j$P&sCjgd??wMdyp~f9>@T3euh%y!)?#2M-&FWO}{|BtFdH+u}oL$ zSMSA_^^&i1JYxK#J{XHF6YbraS~6?>BalJRle?)x{|7}NgK~Gfoiai^HBOSMZ*sG8 zzAfKy)rpZ~zX2I74>IznJAT1MD9cTKyYY=K@B>pPo=tj>d;JVF&5RYCa8;@+uzH{V zCo;iUVq_F`n988Ew`1$$clEh1pmEmon$Ee?aV8E3nhFP|0?hy`EacD>Fd}hf(d?N$ zLG8d^DjiTqi{My&-^B_TVSF^Q&4>$Kf)Nxq#rOX6G7e3U-~v{JbR;;?w_p?mk>Mh@ zzRtebph!0#^X<7$e`>I8aD|9|3q(VfB+RaGZ>L^ z(c9Et$^&D0=w{X7!vM=r+G(g=M?Sj;)p+FVQN>Ic05-jsjNa_IYCVzbRyzw~;zK_D z048iD=kpEifWYE~gU||+g%Q1$6D#!(kq*`t$#6< z7n<$qXbTf0-f?Kez&U$8#F7tJX}P6dSWziZ4C>|nGdKujaEZ1U5|S#v5`?&Y7;twW zbT`Ffk8H}_f3K+PqxoD|>Uc#uun%T2@}&Arpry}-+B=h||;L`4OA;`0>_egQ+y41z#4HevP> z^R10G{9$AQ9xop2@t$nqCAmV6LJL>M9>Zt*X?=77ghQ{LP<%YT1wnt3cwQx zQea@IG3XGTvyM=_jeS0+bNfBN5yn)bcA0g; zh4kHnT<>A@=xc4{Z%!^a=@!i{o0>4FFjYZwZCVZ!wyee)PiD3()pJ!iKT4~;wECDG zQMHf3)EqoZ|91;tz|6X&on-hNL-DdlP@`tElwQAe5b}icVUM4m29=*Q}H4a5rn0&K4jxsxC z6kgt)kCqHj-Cc&=%~hE#oPSZ)5?oLtUn0c#YYOQIUnkqN?u`A6~gnPFc-Ll=2+<@Wj`#T`jr>

23{esKO+I?+=g9)#b0a%`bKq+*8Sb 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 z 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 Pow4ib>gTe~DWM4fqCqI! literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/library/twitter-light.png b/site/public/brand/perl/library/twitter-light.png new file mode 100644 index 0000000000000000000000000000000000000000..28eaee685ae57989e769297f01ec4453a46e1f0f GIT binary patch literal 38109 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 LS3j3^P64HDo)Kej4&9nsyrA^0k5}qQLS!E9 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 C*vA|I literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/app-icon-1024-light.png b/site/public/brand/perl/workspace/app-icon-1024-light.png new file mode 100644 index 0000000000000000000000000000000000000000..aae9a92e7bd1b5cf5fb452e950763aac270ada9d GIT binary patch literal 11495 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 T{n+;d%QXg1S3j3^P6Ji&`Rm&l+a?ZkI`I^8BXs zfkn`XeTs|6bA!^^lf2lTHC{jd}%wt-Tc7L_m^dIac4}}klpFeF|b^mqo$G`0F zet&;x#j~^UvAkxk^B<;ziWV&G4+LbIoC`SkfE*Q6E=&6qPMN*ee_vBMXS;cI@sDNO z7QT*Nd{4aH{(iN}+jf(=JGU8Kl>QjDrCi^-?BU{T_GNQ_{4Me~x@6H;8Y{Q;>2iq~ zJ6MnJ{XFfx#k3C1zJJrUtBcoN-nsB=N_oD&NFj^l_u5JmKcl=yJC>*2{F}cv%eq$W znnjTAo#Ib(mnrWriR}^VE0}d8=ll*<_ZJskSNoTj9+f@b)i>|fH2K&2e*Js$bH8#+ za_;k;KTZNwtSE{NzEjvTP0sFn)#HP|a@+M)CI=oA%v(@+JaA*#X@vtDA60Cs`n>Q# z^4*2!Ry?TKu#mT}BV_kp-3Kf3Yzh=_%5ut-um8^o6x;v#d4uwn<)62EJm^^3bFl02 z>u(}`{@=DAW^}KT@h;nP2t+^hjy8QQg?dgvr^5gk| zGJzi>A8%N-v`}Yv)y1n%LMGz-$vAV(uP*;81(fMm-mv#LveDgoK6%M4JEGdP_b1 zyu5Moy%RG(%UADwHc`@)|7?YE)YNeP`8K+t7r%6UpRV(6{fndFZT?!_-u(VrvW7cL zz639g6z*2vW0Dg6K7YQv;L6pjZcOgU zhuwlZos#EE+^v6@k#|pwQ|9_Q)%m)bhO@0>!ouS2)u($^R#wKx`>PbRSXtdV-h0+; zp>;%_pP!doVd2M>!Rl-&YnYprr@XL;i~6)h@$SDv*@ounG5_Zo1{kpkxohO4&XzV0 zJvT3QN_;}v_Jc=WOk7;FY4c&#l2=zY6)@*!W=c)CtfFjTaspOhAW9ETQ2Bx29#s7L aT|YG8N=x#0298C3 diff --git a/site/public/brand/perl/workspace/browserconfig.xml b/site/public/brand/perl/workspace/browserconfig.xml new file mode 100644 index 000000000..d7b3336ca --- /dev/null +++ b/site/public/brand/perl/workspace/browserconfig.xml @@ -0,0 +1 @@ +#0298C3 diff --git a/site/public/brand/perl/workspace/favicon.ico b/site/public/brand/perl/workspace/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2fdf6e73ac7dc466d1ece570812c02fa3533ed3e GIT binary patch literal 17557 zcmeHP3pi9;8(uSJ6eqVzDVLcfm0J@b$)$@>L<*5>LZwp)8Mll&G}HsMNS6rA$aJVfMc^>Gv1o5a*nEo>`CATI*Yv@7>@2*0=Xw_67h3;DE3& zfH@It#R0Gi06--6)h|MM5|oihpX+k~un>hEU_$$!;sb!S1b}(44!c50pB!cYPWw$F zN=X+I3A2%rf*>W`tst*h;l62dk%!IXhhBCfWn>4DDqlz8I={`rZ})8x`e?U$>OEua zDUUa-5Jm>VY`JjTT5XY9Lrsw~dK4BJ3a31A_xIZ1(!FhP$Y5|W!9E&lEGp-YXK%l4 zrr4t4>=zxVw*34-UEjg*Yw!y9;l|e%_$Acl`_v4EvK#LC!;NR&4@ze~*pCbbMy~hW z?;4-ueee6m?;X~D?D>_j|A6i#w-8p=n8lgIDpLH0S~ zJiM(ThKR$%$=7ILhK%uC{X<{>P}^|r&-Fj<`s2nQj*h>Y7`FFm?5+X*@z28=5XiPX zD@O_+8y-CyJur=(4t8z*`Y(l=^Cg5DU4Y0KDUu^h;@Rn7*VeDUI@ibbMV4pTC{Uh# z-r*BF9qiir^*27)?=jdt_+OFH5X9hKMGD+^X#38+hcD0n z<2lbPq6}-^-1%L~%F0(&RaH^$*Tz%dc+D*@uYjP(0O#ijyMJwmxw7+7{v632Jr>zH z^AHUcB9a!4d!Kd;_vuDB4jC(44Z$Nmwi6I1<4KzKhLbeiH}WE54QFFKQ*RL%^?l}0 z@eh^Le&#^}H{%h12fU)UHN+_Q!Pt%4X3EpVpxuo8L7_h@Ot!(hj5S=%uny=}7CRoJZ5znHf4l7WV)9hd(<8h>8hjI(Wm@7c7C_Bm^) zaeqhrtjh6zlM!b}qeo#Im&;ZBmSeW9iRAk#s8Aj9Un7(vDL^u4Q8OnFqY?m zcATdxa5Jwdy7w^F{NX!F&CfGE@8A5*P7R%(g8us7n@VWytAxI|gr?dJt~QveVA0U*S5t-b*NOn%rTU}&(?tnXxCz(igsvDtIc1!jD^4Xiu> z_+bhP42X^qgEB+ImCH7epEW*r+i}trlheFnQ@x_g!dqKHo~E}7W-cqnM2N&JiE<~2 z%`z^cQZdSl9t3QpZnfd{T4gN5ldGq6SY9D|S-FP#@flipDs`>Ca?I(q0u{d=IGS?M zc#G5F6Xo@P*yLZg)eCJ62sCLi>C6vqkEw6hF80$%DAf#&jcqACl&i5`t*z3Qy3K*q z>i;yJRa?F5!jY@VI!&k6M82>(MayY^9FY8@pdPJ*_BLVm!@KrUOMD8eg4B1tuRsdV z5PWEUotYU)>8xNLf>BSoetGQSri0cZvR%ujxV3CxU6))}@TYm#`Zd|zjvznV+)qf~ z{z+%6X+8Bt#kQ<>o$TtA8P4Kefv(Gq*8;}%%Za6o($KU_0=ToaZh@el zdLvo7;fb|>y3^aFiUnf(TLg|Rm|wBD>Cl};Z!iBMCaimMapc_vuk;z-Z9M0$ zxjTf0Kv&C8t=QMr^#O<_kn7WXklVGHvO@5qX*yGEX@?qkmNv~^Cxd_DbYM?%hyEF* zE!X|BdYuLMZLgwMCbnra+P8ATfv}a5h^J=Lb9`=A;e#C*BMAVAx4al>et-O!6XLvy zR|k>+#2^sE;8j4szYaGAd5XEosMO#ce;gTYr(D36yhwu+0^L2B4(Qf^l8-g@7x*mD z>=oGI-W`F3zE3RyI+ZT`!W#!L&bwtlo?@F_Hy41Md?2>U;eMN!tjSH`8`WJpcmQP8&=oN4^3&$HJ5$b0OY(EL z*u#*9Q=~kk#@A<7ANk-BF;`pBy1go-joB-Af1#!G$+V-UJNIRXNwta=3~@%}BKwL> z8i9>%bXgOBYyaXE!2nSBj^W=@i(|4~y3U}|mb1ZuP@xgoCY4ry?dQjoni8+K?~}0r z9F-A@;03(!;CTR+f&rKu7+4*kK}aA@2AJ-nPgl2m-tn73^L*70>%CD!8pwgvB<+)T zi{JJ-rxEydgCn!jOr_oqY5>HaLD3Pj&UAfx_9oQYG9na5+$%{V(WETs=RkKd2CnR- zQ)p8^S9UU)rGHS@^md&LyHe4Tfdcr@E&b)x^%ZjR;q{XUCPJFykU_0PR5dh7UjeNQ zk_M0($AvUteGJ0kvq%MYyUO?JN25a!Y_bGGrH+kZcMx6DZE~#pV$DxG!4v*?uB^>#9jYLzSPeOvkNqT%>>VAVC6_$gWG5IMwhR>zaEk45Es9EMeWzJv z8E+<9ZJm=U7(MmacKO6x6EbIGiF4KpScy?z2XP=8K9?-~Kp^getUq8-8d3-ZItsdc@%)XT z!TAw5GI26vgFe!+s8!oQCfrHB1IiN<#{wR0g_Wc1?PR%D^0Z@?RSN z?@j*O@&3mq|FekyU6cQpS^bwL|H(r9Z1VHzKN)3r760QVKNtRgZxR6tJOu2{e=PX_ zKT>?xlmDAHeKdHpWPOC`@GXv6Pb)-ZzzEu1R$JNJ5{$fu##HvL?%~?-y7l1L5M`9s zc!gR?=m-AkZ^_zF>ce;^4aVXt_>M1X#apzVTv7Z$cgMfdi1C$m@F#88mb|!=i&YsBS;|YzfDr=^ zpJ6Kc=1JJBzWwBJ7%a*N8wwjLB3gh@C-k&d`)C#r#t0r?=H$zchcx=Tu=>QQ7Y9$)k@`ij%(I(+GKK1%0DTr*knmYqv0(Q; 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 A;s5{u literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/logo-128.png b/site/public/brand/perl/workspace/logo-128.png new file mode 100644 index 0000000000000000000000000000000000000000..95a6467653ce3866df8f717d2ac4c74b89255217 GIT binary patch literal 1143 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSoCO|{#S9GG!XV7ZFl&wk0|Seu zr;B4q#jUq@y>om5Wg0%-zUXyim36;C@%g#o@j`Pq$%^rMs>*eW&Yh*Fqaz^H?_$-l z#G}I`<7UYOHILTTwi#_NSR8M=*p??9WLlf#75~g)``TG66E*LAp8Ldm*12WH=kot8 zpLw(=F=gGc-Nm1!Cb!4-%KC>euUodH#OtT^tX;jm(%e1w*ZjS^ckb`qzn2K#x_(tV zng1T&`&SiL_wQW$yefB3?MlVec^{WQwVJx7(6qFs@Y2F`#v64p&)i=}T?sy0Y}K&x zt>3;$7pL9U&zdFdT_j(ZZ1m_#^Ldtl0O`rB7jMMfWw`Nn=XbX}i)v%pPIW$s;N$xy z$N${Vuwt#ZxXbHByBIgzE_>YCbL95hSL*YB+?f0R!{PI624<{Qr7RoPzuwz3Z?~%Q z+0K%$Go>GPeq8_WA#;Nm!yB{McT%&Nu73RXd}G9!)cgN68D20ac;9|3f4w0jIAP|( z!w;Dsq(`r}oy#JSnP<<)(90NNuKteM;Wg)k3U-FM>JB!BJV2@e6lHV=AHFlj)K6n_ z;A7C1*2|45{BnqW`Swo{+53OZs9<>V>)8fT_jB^WvsLEaTh(^W|J7+F27}U@_ZJ42 zesNmO#}Q^8Q^ngLll^vLxA7IWyB8S`&Uzef#W;c6@y(+ztA0&$I$r)MOOc@@9^$Wt z%-7{5&(`19oI7vzs&7j-YS?fy>|%YVKO)Q8~(*Mdct)}7^O|ID~RpP^c4 z4qL-HhBtH%6>JuMn9dlHcTwNwnfpUQ`BqIk&da~ncyT`5DlIVWefNex@o#;!4Kkws zDPES|AZ=EAQ1I%Cm-@fbes#aSl(xX--{i{X%&*(~)%Pe*yM1~3%wKm`RQXtGmX-z0 zUAU#iJa^_auO)v~Q=3~wA1>r!kn{W%5)`81yl?_fo7m}@3zsrn5Is;K%5Xv2!9(iM zThEP#R*V|wSSD;@v`I|gzx`V8GFq-QJ7-}3!lz|uO~mXPHvz7>*}dUjP6A literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/logo-144.png b/site/public/brand/perl/workspace/logo-144.png new file mode 100644 index 0000000000000000000000000000000000000000..e6331ec56672d95d910c05e45dacef50e735d93f GIT binary patch literal 1296 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$a>caTa()7Bet#3xhBt!>l+}p=^bH~!9{%5{ElYLz=BP{z#rtzF* zyX$K&efhg$#^<|#Ki_&W1Dk%o9o%5 zae?o+x4gHjwY5#OSd}*~oIz;iRk!vu2{DGFWgGH6LbkEGxJH+6SoZbXp&8cwrz##X zwhCUAs%DrHad+x_6@|_d;x8_>cy#8-=WpP3*x2waT>3cUlo`9r4VXN_UcT1j=2!c3 zi%Fni(u)(@>s=V9{@(Rodg1!2(0Q*Ie$}tqRbbrZVfV4yNw;-?0|SQx1JFzc76k^z!NZJ`cCbCq zn8Gw+_0G%hvcCNfyLCq|B=5BN^_vc946S}IIqMr`9tmF+%>7#C%XETefx)7*|G)M6 z>w{7q^!$Hs&P~tjVFU_uEc(_Ta^GpG-2eO5(fg$sCvZAEw4Qi8UeUfYZ|d!mMVlEN z)EEonKb6|eNR2iU%STfY88;Sykw zr7?28UHfP;1JeZ^hN&FB`s^Z(Ae_~B=O+u@TBzx-V;x7@tyzi0V&j?hy-KFo;NQCYra%_Q0BIXAaG zda0{*t4Q;5sOprrd%HT%OnU3D%PQ@b%<%MC1Z&`?wNY!kRewn(G78K*x$~B0Nv!zk zuS^q{u4fmR$!sFpkTI=c)7r;8ZIgV<|8*aKS<;vNP3AR2^TL!wi<1!8|wF zVv5gcnV%mU&SmheE|opJFePedlB>-E(}(eqPsMhfX~(#dadY4A__BOy*2Q=zFAF;h_E%d?1ew%r2_S5iNkw2|o zKkr$`tNPD5Brx!?q6eC^?YVo9K$N%vj5Jqs-J;H9D}E;pUXO@geCwp CuUg?fWkumL1;Dv*!Pv^(z#hapSQ8l)t0VV z-&l^mo>k6lR(t#Rc{XW2zP>A4%eP-GtNZ<6%MPxn-&W~XYfc{6t)S5PTj7Ca`qh8>7cBhj5pe&a@Re=fP3}pAR4lBQUX|JCI(v=ahUo1J zvlB!je(aFpdY@9f-d@h%fi*%V*Y4A6jSYb*Z|~0UVa$HJn?p3AaLd~pFQpH>x?Syd zZOd01k=zY3Aq___M%(|jGJ+Jb2ZQ^DqPb|0K|=hXN8zqo;VQ#ao{B)a>XJVSQT>ThLp*>uV>cac zBYHfdDmUhgsC=p1DB>>qRMasu%`;$1B-e~b`Eikv6a1Dpt6!S=;Nh3cj*e-P30?9x zzKSiI&*XEGvAe6`DUUlR<7w9edJ=t)GU_T$o@Xx8V+pG|R3PHc{mkBq^Twm2-Tm$d z%0SYAp`msgo?Y2=r*ZI@0J{2CHD0G z{%t;gJ_QDZMg7|7_;UZ20>@Olb$us7{ypE?ls!A=#)XpI{YUqlH7&_4zT5Kp*h-C+ zGi04^%UzSt+gi-FlJn`a))kAc3x-aedi{OO^F#OlZOADtE%n^Dyq-aDji%*;&gTe~DWM4f!^)V`Md#AoCO|{#S9GG!XV7ZFl&wk0|V;76a)yCyQ-YO`81hP0VMb z_9n@dUuK>PN&EPwl$TZ3zv%C}M}J=Zdi)`^*H~l5%p9#1Q9*3!&#QjUW#~nVM$WdBk89t? z_wi7nU`0V$=J~we4=3F<-n^D~d9ja$@`XA2-~aa;PyMHE!@gIUO=eEui>2%9_LV&6 zxos)zXR)}`c}@@nz7Ki_WH^y>R_yX=e>V|R<=`+sNd_dIQ8>KC=oGC*wYjjDBz4$Bri zV@f|=RdQ7QyKl_4m-;_8WqYi!lzE<`d$t$c*c@`nycN8 zf6trhoU7ZE3!ZVLzvkOjbJ^>|ruQGO&Nn|WQ+dwG6r=h_x25xg%X*`?JuR~+Zn?ax zkyQrh<;;VifQu7N-=4{R|3%ow1&)y>x&Qv{`8YNHxLf}_zI48Vvh@)W(qbCBKOGNc z+4#v&8WaT<$JsU>xuIHcNYZ!C)8yIC3yguHT^7++(%wDN-0E`zkKDW@50nj^WA~?l zP%Pk$KRQJbJkb;&B6-hAi|W0b9tEu5xw`JH>HFrzw$ImF-Yq_OYk#%g8qO<)weuZxXH;l)jVJ{cBhMOpmM_IMO$A?iCv_u$GGk90J9%q9DF z?NV%J+kX6K`kMH}i;jl_!_7-hO!#KO-(vCDv~BUaydNJPzAaqGIp6XzKTz=|#=pPg zKkkW)i?iGHb^W#v?2^tw;icy{B)%=o+yBG9z(!7=E51jH*K23qg}co9&64--`L|rJ zn_jyjASl9Ol}cR6p#xJ^v+?a%{kN}j&zdzkDem%@j{FiAo3`WV>$LEw5E(gH-mLw} z?<5S9TngVrY1epG8Q3JP;w!(ze9rOe%dW0j-re3!j7$GU2X5Olv)y#7jCkwySKa#d cZ?ElVXY-KJo-_M6u*hccboFyt=akR{0P{1%)&Kwi literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/logo-180.png b/site/public/brand/perl/workspace/logo-180.png new file mode 100644 index 0000000000000000000000000000000000000000..72f047e1d97335e527e9b52efa1fe5b9b4850406 GIT binary patch literal 1629 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD4M^IaWitX&oCO|{#S9GG!XV7ZFl&wk0|Ohs zr;B4q#jUruvNNWZ${hHZo-M_(?IpLfqj_moRzjY#*6Y?KVScV%dAm%lC#9L|>l(i4Hduu6i?#`#sTG!IMyZJ+|_wF$`qy4?)WYol4Ea}>g{;?7Z;|g@r zU;Pnu*zW&1==UMb?6S6}p(nSW3d?_6_)eDZ@EVR{-5I&8cW)d#*O|`Fc-PK$Z+3me z#;WRwxY+N}H&^lJWfeBhKE`99&-)@{Ufc%r8CLJJ7TjKbGkQPg;)}|?zxqF!Pc}E- z&oFDIzUGT#axoj2UwqqTBF8119jqQ8KWo#gzxS5=J%75=y&;GFLMJPGL*D+hz28ff zUmRQYYLdG7_Kz23COD)=oUi$FS@S}mXz0mH!s=h_6dKPR*|_+T$%TuP```MCJH^jp zm^*W+{KL6Y){}TeL#?@(BpT0M5z4l+Nq*BYi_heOA=BI#UXu$O8D-C2oX^BtQsWS= z&d&g(-TGGTTI|3qt9;=k+k(cv%fWpD84DW4E;uj)l{;`l*dU5cDq{gFL;wEec{Bvo6FO6!T#QALf9V2(k%k6tXFd5X0aU%zTj1 zAZuQHZtz=kKh}2VuDs<@@sXu>(F*gyG??S;EQ%RE>!aE$LCc5Qm`|2Z=cuKmu(0@QeJrp@(&B|}V<;Ta9fibCm;Xf#19hNskt%ODoDE2@xh9165uz*DmQDP$wWQ19=&< zoQSx`yIC)4+MagPO!j-8&9>bn&!+I#Z=*=TS5dQ<_T5`>NG$!iZ|33jJ&e~jr=Qom z$XdAAH~9Ebn*~b)AHRK(KD~JF%^6os>SnCGTBwz=i$zRyuA#AcuVm!GpJBfi-B`aM zq3X+dGxz1+`1jRZ{2z0;Vc%aV|0mh)Jid=}|6Ede)&6Di&KKV^)%6?F*VZ%sn9s@C URK>*$tS=ZmUHx3vIVCg!0GwXL{Qv*} literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/logo-192.png b/site/public/brand/perl/workspace/logo-192.png new file mode 100644 index 0000000000000000000000000000000000000000..ecbfebfc9e7282ca150d1f41480e77f2d9b14d37 GIT binary patch literal 1743 zcmb7EcTf{{6#j*fFe7?YR#?SWhCpP95LOgo87C@&QUnqzI2e*Jf)WBz+*+k76h&$- z$Pko-2nb;Wi-4>EGNKWTG(Z?8lqD-lL;vy*uGQb&`+axcyZ7C@_q}^p_WS&VP}Wff z03bX)++TmlzcFR5iZ|E{AU6_&G!VK@7JHHAv2+He(?PPz10GV{a%6ksd8kfaUW>OCCV zcH)P>ZV;KU;brQdss>&w@#^=RY)#NDRL;SN`87#}fqE;wvrAUfTt)xk62_N~( zj8@!hQiotes_mkUZX6qqA!n#Tx@rdn@rE_yBYG$0qo4Bf^q-(duqNn_!+o~8)@8v; zhHUkA23wCRiC$Xi7#f(5xwMHIj|z9+n6osAh~hynqmxGmMtD$}PSyO=TtJ^Na3%71 zQJfb{5|X-|LyxclgUR3Vm)z_{W5I^#4IN1?JH{7_SIrufF(rv@`T4>rIkM<6MfBL! zAO)GIeF((XR##Anx>Ub_x{8$U13-XWgV8}5DHB~b} z9ILwyCN!Y{69u`$@UB$^zzV)!AP)c$-lYn_GzA`zy{rwuFRHXUgbbt>`^{uoAPYGF zAb<)01^`0Hq#SKV47scn{j=NOPCjyoh#_=4x5nfST^y%biT#Qr| zqXD(Qi1!!kB&6_Mt4ejK<_h?PY3sr-<~b(-FSi{*7aV`{>QWzUkkHmjTjYm;Fe|E* zm6ttxd{Dh;cG6*_zu(ZI&Qh^xMpk+eoKi{a7UniN%M7xDZ_Ln5bOhjqcKwjynfWjP zE*s1GYcf#wY7SmASib89-awYu#Gun;C*zw^G@3Z6?;fyoVUt7Z7Ni(65uo%$3QxN1zzMR?qRVWwf}8$hEzrWoNXftqmT zX*;xDa|j%SZ^_QNn&*1pPG+W^0`|g{U^|bhcg*kItOp^aJwVyu>8{p!OZ!y!e8>8R zZX3){0P=EjPH?c~|w* zAlOiru#Xeoo@Ldr@3cA*Z$vygch)XDKM1{i=ekb9%-_$jhgZk7am^MISA5{ybB*kR z)lV6mLKEE`vBNFRf8e~lypF+A%jv?dCF~~^LD`jMT;}Dv8C|Cz%q_+VAI{`9l!_Sr zH21&gV?&GGV-M`GQ$;%+^-aAay>a3m2Ku1^Y1L`w;Z28*?#}!%(U#^qaSQV^7-g2( T_u({t literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/logo-24.png b/site/public/brand/perl/workspace/logo-24.png new file mode 100644 index 0000000000000000000000000000000000000000..6453bb5d2a3efac17adb95f3b59dbc61654f98e0 GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-#WznE z#}JR>$q91`GZZiPIM>fillj*#?r-~Hvgt~@MK9mnUg`V%-e2_=>2rH3XYG3xVZMxtY=r}moWI{a znOpD9!cvv{%eJy^_t>V8`n2=JgO{`W1)C42<=T2}V&&QRwCK^xvwV*-d;3~8)TB*T zJ1J&xe2RZ+r{;fup0twAJ)Y6rbCmD(M;T-t4A{`HwEnmLG*0V(!bkQ-*A==k zkz{1VjCGb8Z6ahGipkLA)L`ed@2Km$_K)2^zU%sWuIqX4-*Z3r_1wSre(v9s?dk4> zRNSHn06@Ap+j{{3gCGpZ%Rwgi)a@w9C?q%sBm(e-s&v9YX_*$}b8)e^^C1qudlegZ zH5$fTI2gn+j@s1`kv-I~jB2uD!3sB)?JGWMru8Mhmqvr_Hh-FSn07Q+F4+;UFVo^+ zl4EF8YBy+Qae1>1f<|+9+Fe%SjvV>vd~VGJd_;K8l|jyf;I_IDhrH#qbdN=kwYIF4 zGR}%EE5)j+-#V|ne6c^X#majxe=LM{EYxf{b*NJOdg8>bi}$KA^Vi&pMgy+VnF}w{ zs*j@_=&SVEsvXaI2;29a=^W3nIPrc&(s^Cy3_WG7sgc?s&XUo=i3Xhp%X8*01a3qN z>{MeHeZ+OzhuVMl6?nTbgkhkK;hUoDM0mNj?8%{xHV)UTTb~G!yls>$bu%VvHb-t1 zq(>jXy90LJuatgve_nl)4(L8QWr}jJct_OZz6?xl2%n{nm}>p7h`eOFbHs8!v)g*8;7DsYg z?3icD=`jmBo!-Mt5~h<#6(R(y|OTu z*yJI8Y(OR^v`;&+PxECe?w<_J%a#G4t#;%bU$6wUs)(Ehk)-Q&6IvMnl~$hC{?)x; zxL$*RX;hTg1O&5_0Fa7p4TNtd4*7wfzc;pNg3o^^jUC%?KHpwjl4L#q3enQs`7{oO z+XjGcM>4xU<-u`gc4Uwo1|k7;Ge8+z&PW!51)ktH!AYy z_7rRtYHL7hgL|eTKRK+|9Y5$DY5WtTjRi$@oYYC-G6e_2J?sK>ZGvcO}59x9vkS1!x4K4 zBSBW_@A$1~kJP|a*1;^O85AxdW@)T4MwH;X)Vp{iD;-LRBL>&fIro2jL7MDKo_${p z2Ow8pxlj(sK{p};;3OD;F#!pLLIp7cWPRXyu2s{*|JCZx&I>!gUGhFHEu^ynsHNIo z?P1NXHzyAKizfXJ_2SNj0ALnJVf&|7$~c*G&NL`k3hQk zoADP?pHWDE(Z}C#_~b%M)ed0L{7CBmr|M-4(De^UGxPTqcv0y*Pg$6aAb!+c^SH-E*~ZzeQ)p<;eiI#HC`Org*_HlK?2a z5h%;UUP>#HyLZEHhzLrFjJQ?xzB@^L^afmxe;yJUUM`C6Ev{LfvmW=a^irP)WY(fe z)h@*tQaVNinCAlne&^WAb`iBhMfcP#r^j6i8@X{NbE2RQ`1s-5$NCB96@U>+(o%5# z8$7#o>-COO;lcknycX;GMDDX;?7m^e#kv;0?;Y!ZX*pejF%oJ1g5G_qAvlqEVBP|C z$J~Xwnq?zdE-Ko!A`CYXbPCeCxJhTv97aBR3*0nk0x++*u`x%tefXX*<41Tn$e25> zDHK0Bq(MW}w(e-992A8`&X;Na`<8^YiIG%UO`)PZR`J@+eS>GuPF_1Qr;uJ@Xv5wb gs9l=Ix0P7F)*0nTU~^e#6r}y=;^1yiJrMfCpBaNkE&u=k literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/logo-32.png b/site/public/brand/perl/workspace/logo-32.png new file mode 100644 index 0000000000000000000000000000000000000000..90ff6ba722d80fb5877699de560289474eaab3c6 GIT binary patch literal 415 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DX&fq^m5 z)5S3);&5`ptV)f^nZFkL`xx{6S7$ZezNX^*#4!EqCGT?|HB{{r*3V+vV>A z?ljq6;sGkFRk>QUfqB-nzv-T9wAGF?8qC@8g>i*)$^qy*dwa`%a(O_|!Hsc{TecH8cN|Gdc55&$zjN%C?dk?c|qV9FN_4 zx_C?P@AAmt+uONLWvM^Cx;5WZdd7eCj;}udPrQ(-pLErzLUH}V-(i8Vue(=FJj=|c zYWcJO)F-b0>`c;95;aKylct}SU~vC)?b3xGi8(oQ_!vB<@Q0apBsBm-oWax8&t;uc GLK6TH(X|Qy literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/logo-384.png b/site/public/brand/perl/workspace/logo-384.png new file mode 100644 index 0000000000000000000000000000000000000000..32d4360ef9d409bd67056a732f0cdabd0113e578 GIT binary patch literal 3781 zcmeHKcT`hZ8owzN1EGwF5D*A1DyT>sXFwrAV4`3I6=hHa3^M|Xh9c5K5GjH{W*9}9 zAlRr;MyiA;s30RoT0#>DH6R@+(lReucXzg(o#Wa4W6s&!^WJ^mci;W}?(cs0`_9W% zn?nRN3WEXwpbzXfKLP-ZD!9Z&AGPmjJbawSm2m5XKHzOUbBp%D5ev&sI8oHV3vo|{RyW|<$^qS-!h>1DL^@d3v zR|_Ro&uDyeQq@kYzQy9jjp^4zG9QnMRmUhc4e^c&i zK{vNM5%sQe?1RqK#w*fX`S9pn+Q2GHr8p-+D%GoX1dcaJS>^`JHm!)vZD(UlE+&JtB-9yZbM|~a7LKo48tjN`)JVXoHk1Xq8x%Ym{HTd8 zNK&aV4iB)3mxu~TL2s%!1CAVC=xFEf?IYye0W{W;bKNo8fu5(L@#hQ*Zu|Q9GfoHA z{76@+OgSRcWx5vY_L1DSz0BKtcJ!9m zB8^pl_4Fc>+(wgt@oe@49U!suYecBQ3$fSf-xT}pBofpZgsFZ0o4lMO`IUo-)lnXK zre=pkGDEC;D_a=con1sw#}|KWp+B)Qt1au+Zd81GFxOnp_m_!>)~hknl8WBCV8l4A zr4^1>cBonzbPMe7vsR~dE4iVDMdRBR{8kI{5;Pw;RXw9(?;~j4>&t9Fba;mG((4JB z_`TgF`I542r9Py>d8`whHf{`uB(R6l{Wv-T{?09SX6*vC<3R-?f1B{4Q zcDe+feE?_+!-(Sy4DpG}^ey$Nx0+TrF7ms+3jX@T&o7;^bU4jKu7y1tmD3Fc;0Z6m zdIAf$o;GE%ZKa_kMQXfw8ZPJ_piLG!w3ZA5gOUpw-phStU&yad`rZ|@O`Hm7Vo_nond|_7If2V( z6xp{d`BW`3Ux)BqGFgiN7mN>}B; ze&N7Pk<51=B5MgK03kis0Y@<>T*W^7A?s;BxQO!)fO6EK6vg|YzB5Z$kW zcX{svr$QU^s0-m1a102jZv_Fegb-j>`RQ)qB!5Ry%sPQf96;NpCRhd)d~Sm#3#LO* zLPP1Yd9DUc@=9U7Bw{;{BV#(8Y$FxSi0686$%Z z&Y~f4{ma%b&nw|vDai6a1qVPUTP+pb*{s7SAtD?M%GXZA@StcNo`4)p8NzHE$eLs= zCqe}6NVV&h8?Mn)Lz!Xw3X^s28!kO7NPyx(Ye;e6bm<3Y9#_;Fa6nQx%IQ9x>H-k^ z#0$Z_ZBt=^&up;6>N*QmZuR2{P^QotFkiWvzA7^$k}+BXDOY_aJ9Ue1TL2kq{vj0W zJVr%ZI)r6|lBhEK?<5z>8|s~aFC-)({|h|^N5{AR=H0=)CcuFZJu z+;bheB-MeYf(BRQsQ$tkZk~cGVds z?wZg9;&^!&k1}yr|A}?^j>`^5b=Fo&%v*T^u}Er}Nbfbp!&!l2`d90{7{WTzCr?dz zG%ovX3U7J5Mnq6qAkRhQgd}B=AwX9ARER*8}50a2LuBK^DuffQJNq{a-*X zBD;w#X(u#{H^TLk6g^BP1dtUOex6RLn5LhOGuew()cYc5ETU_Jkr_n%_=M~L3G ze^7?=>nJl7oThli-pT-9&fEyTMIpHJ#1s z^Q2@F8WbSY4m3qZ%7_EJB;xHM0Fclh5`YJwt{MC!x8ZzoBbYI>2si^%*zM8AHg_-L zomWDuS6%srxZ-|JFcm^Y!P&xG5?e|yk+Z4KMlZn-6qQJsx- zEIADG9^{f0aZB9mQ-Ka7a-Ko5^0Aa1YfmFZcpdf2bF9T8mh*S&i5m)0M$Jd}!78S_ z`15%by|VYEt2r6mx!2FD@~a|3wp_stgeYM$^U^!WWTNP?*-8BfW;y6!hOz{e+55;(2xKC literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/logo-48.png b/site/public/brand/perl/workspace/logo-48.png new file mode 100644 index 0000000000000000000000000000000000000000..d216000ea7b320429262868243acaec047378416 GIT binary patch literal 544 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 F`~@TiD186` literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/logo-64.png b/site/public/brand/perl/workspace/logo-64.png new file mode 100644 index 0000000000000000000000000000000000000000..8e3f3b5b7d51bd4a294aab2e55a9c02df8122b06 GIT binary patch literal 644 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wk0|S$p zr;B4q#jUqj{5>WY${ha~e>-pPoyGTx`uj!KIy|mS<4D|{(`sQZ(`s@%NA`?{flJkb z=7>0zq^p@u?Yc_Q3)}q!qnEC8p7lCFz;(JpTSTS@+fVlWw&(d0zkj>!y#KuTz2(n8 zRPS5=oIm;4jmba#qK)D=sHR`bO|H}`@B1hH{pPlvzp8d-xIBI1m6(}b@$U5X#y9QT zKYj_hJ^%3AlP?AOm;Pt6sPC0YZ!4L{a9g_KQ=RgxQ@vC8^lg87F&t^{n#yEwzwO7} z=OW(rwx=rgehXtVu>So))iwC0d(ZbzVT>DFC zZVAs;Ty|yWwWBNzQX6%{Y^!AhmPAvz7KBit> z>!8>%$1yjGo!4tw*@T%dmh74`SBrz6^{K0RNV`Dk|9Q_>&aB+}?TzGp`5OP-Hh=8? z|36$jOT~3r`l|^Gtu0c%_~@SKobl$_1^(c@)$6z9t@GEnc z-TU~ssv^(p`SC{ISfqRBJ@7iCXLpHrzeh>wncP*m-k13g%#UiCe`p>1~&S#9j$?Wc_P-5 z+9JiUg?Ym1cov7?1|~)_{Q}pvL9k)TwrcsaZ@;IXmEE`gS>HX^&sXgPH=EuSn|)g9 z$~LjEEw^;V+AmGpbLrX=;pZ)SS}WtdY+`=ZiXO<@%Gs57bLPyX>UWM4C(Pz=2xH)D zcYag$hS8yWQysI0CWGQMp}S?N>8nqlKY4QI^q@6i_THUIX0tc_IKeA1<;nUE=1=_E zI_g%bOWya)`Iox0_Eq_oyOZuP9Qv + diff --git a/site/public/brand/perl/workspace/maskable-192-dark.png b/site/public/brand/perl/workspace/maskable-192-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..fc96e4bfa3e5a63966077f66cb8983c0959e4411 GIT binary patch literal 1122 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE2}s`E_d5VcaTa()7Bes~zW`yzt<^!<3=AwH zo-U3d6}R5r_05(kl{xTnh8>6LlCwE4q;9`+j=4J{ZSo}F#S52QyOQg&Sn<{tm!RJc zp_iIME=38fQ8F~+isM=o_S->U>y@jf>#B~{E)Kap6(4xNJjpIN)y01I?ljGkw5QDX z#SPBX{P_x58bB;qT>(r|U!F>a^$TGL)+b`zxz#@o8hYNvAxUL7A)si z=L)#-d47EDyE{*pymjVey7KEEKZ9w;yVLPb4$*uv%q#d7u)OdzS+IT`^Q@R35(*8A zm~Yj-;%;E*;>-AUW;+9;h-`p_0|O(A0Bwlv92tM6E?qhKdD6SNpN*I6GhLa|@b2Bc zA1|ck{q}s1++(}1B=Ol7)rML80XKHtTX?AK$uQqyqg)8SuAssx>z(m;@XyGPcsppJ*ZYKiFYza`4=#FR%RY`EX?3gOjxfuN+Kx z9<$+f!ST)RR^QH)zp<^W=F-|7lze`P+p*odjIIV9p8DY7@}%sNMa4@d-P*G^w?NvV zcbEC>;O1Yyy=uR>2eKm1UbY1jT6+yQg7kysTQpP&ErPgJ!(--2CBcN_8i z-Ok>1bk)4CH=P#k3xC8A`aGaw+Ee35>r%z(`eN_2zkY44_OB>X&Hbh#GJ&al85c@+ vfM=@)aJCY10Od4brb5m#c+@O$`6^zPRKB^o&^;MgXfSxX`njxgN@xNAMnsuq literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/maskable-192-light.png b/site/public/brand/perl/workspace/maskable-192-light.png new file mode 100644 index 0000000000000000000000000000000000000000..bbbec9a6d55614d5703756f701268f8aca5b8146 GIT binary patch literal 1137 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE2}s`E_d5VcaTa()7Bes~zW`yzt<^!<3=AyF zo-U3d6}R5ry`Md`ROZ0Psa@i6OI<6IrRPPh%{?}6xlF~weyiOpw_I@XFf;ba)s(pO zOe>wUDs7vX5ha*to}i z_{S_a?|t|C=fC&L{l3hOUBw^% zoDW~e{AK^EQ*rb5ypD(|De{fk`}Xbneig9i8<4oU688%s*CzhORf;D!o@tv#GEB zVcx)?B@_@jqb}#I8;~g%AmYHl$Ra>{qNJP2YyTy?`oq&KUz@k<@Bdiv`E_Xatswnv zp=)lL)TX}PvMl_4M%GSCUtj&X+Y&xHpEoJnvs*d*>!PQ@&-Hp%?|!DMQ~&3sWbyo6 z|2tC|M6;gleX13ZTY8rH;2X_{HDGTEu#`G71pEtnDmq1kDI{2$k?XL)f*<^A z8BOwje=9Toa$j!Enlmpg3l^vczMg8~5V+hgZBe9|HOJ1*JkhBue`jT9Nl8g9IyrUA zUiF0yCeO}>Fsgtv6T>86-T`JMXhuQLT|}yxvf>|;IKP$Fj1Hz93_#%N>gTe~DWM4f D7fznH literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/maskable-512-dark.png b/site/public/brand/perl/workspace/maskable-512-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..613f05af0c0945ef3229de4cd4931af69b4f5892 GIT binary patch literal 3776 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/mstile-150-light.png b/site/public/brand/perl/workspace/mstile-150-light.png new file mode 100644 index 0000000000000000000000000000000000000000..51c6fec799bf1eabad0dc944add3ade80fa28822 GIT binary patch literal 988 zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm2}o{Eezp}zaTa()7Bes~zW`yzt<^!D9tHsWSw3c^aQFS6!-U+p%}WOu>B;SG}7Ov!)1| z{bo!OTau9!#5d)_(o26@^A=sZ5M>`Q+2`(r*^BBO)Y&ctpYh%G{LuGLPwnE*wSRv6 zGUo2DUs{<~vd#>OjvfL|Co~*91cX|Eh(*zn10)3JBy#9#c)dJv{l>J5A9gK#>(6#o zcki`r+qQlB{`_x1SiY~ut1!cDF%P3w$;{d2@2jod71Q$AzILLo-_@sPT)T60Gv7|> zEm%DJ+*0k_b&cmYZxZPGsXlf7`~r8!n~T@gS#ti@*tJJ|)~~q!$|VXSua}3^Nw-+* zPph3hfBNKrlC$qlX1};QX{UtN!W;jesEF)L-{hIB_VpP>a~{wB=sBcKQ9j>H7;$27CT4IQKb^gIQI?a{rkWyPT~d-XUSW(RsDz zEsa85Z{FLAz4l%y^7)lj(atR@1x|s<|6LAVE?c?lW7q0tGv^aW&w-tFP_S;!?CxDr znxWO)r{%WaQs9|#!PZuKTCh&6`uUPCybdc8o$hvSi9IQ)EPqEJYevBI3A^my$^iW+ z0*pkec@4>^hxIBpW&4j7tgpO3_u1X;@h#KMPff7fZlSc=Bjxp`{#|XZ+x&L_d!t&} zC6MpE@81+xu0t!B*)@0cN&8j{P1^3b;%<-I;*%*|hBFnfm@TXbQL~Y%W$AhF>9?wy z+A5z4D^=DW1uL1%55j5b>8pJ*)~-6F+>w-=^rvO(R#PqEs=eGNJv}GnWOa?OA9 zO`UJ{8|&Ka{%@N!!Q{_;uBHhJEfW+QCMc+ID5i)2Nlqsq0*gX8o~!?|*=c_6^(x+* Q0nDxpp00i_>zopr0G{5GHvj+t literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/mstile-310-dark.png b/site/public/brand/perl/workspace/mstile-310-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..599968c2d1b83e89bbf5c1cc6f87f55a2a88bdcd GIT binary patch literal 2180 zcmb_edpJ~S7@ydBP?i}6i*d~wMB7RimlB6TE)Am#p$j$Dx;-uUQBdk*{ zkK0Ca%cWgnZBi%X8Mi4LCQ4<-NE-Ic4Dndo(;xfC_nr5=zwh^c@Av)Q^SmeifFn*) zLQw*NKuFr!0L}=+x*hx>CIWlBhjixQhj@U^kst&@l*J$G?nOACLmQz9=Z`tvNFoLeETw+$18Wf2jP36!QFr?tmaon01^KoZbzEz1#`k7+GoDaKadF!>=ugsVx%v1*L9`%wh z<&c`Xt~g#CZ%ekbAXpGkAPS^P(_#u^3O55KRS`5=F$jsX2!l|omuDOWL1AJg|w^kBvaIjR{~A)h6_ygevW4M zdrA34*IW@|ZHVbKPFii8OySiRsdDo4xPb$q^Fs_-H?x2L+U6}OIpzD3A z(2p1w72Bvzcj;>il>@IU7vPe;NH18fTQQ0?3k*6z4r;oY6P5m9w*iPZlrJ?8o>Fbd znIZmB9@uAFW88yX_*4lIpV}`@CvAw1J5xbm?IiG*eU(X}Y@9Ww* z&^**a&aRuEoZ{{Qv>8e7qGgatZahwAd6g%?UhvZC_qkw#2Wu@~yOJF%=8~0FF}LxL zR0qsXdn!Za?qJ9Zb+@T9vjFc@B7sXOM)FEo(IR2ww0igNqexU@rEyWBk!Cn}#@$O) z3ZjzQ+L$?;=}NcLf5UNr$r*LU7KgYe(aQUSXEh_Fc{FSoIqrS$qx7~`R8o=OYin6N z(5yvQsX^fZq+~h^Od@Geu;5FSN1cy0NY+p^fb^=QGzBiq!1M;8i*?XUXkY=P6&wMH zhF{?|7JOUaSTPaSf&_#@=@rXhYAhBGqxVa4XFp*3Tv!#R>A*2qy7FMz(f zIX^i*e{m9SDA;D%D@x-re8%J)XYA4-vv7@>=MQT@GyKZE;HkE9C7Lc_?Uze;Me8v?OWpJ}=BOq{?q z-XAO<5nIhEPw!2}TFF8h$Sjk+<*a-hL$7|m^nR}fg$R+Yvt*n+g6ERwugnxakYmKyIb>yNR>onAuK2L-%FwU-WjOy}p!jqCR94xJ< z7Tty3c;|$t2)_hViQV0uY*<(*Al`cMA{Vt?EV3m57Nro>+$!k*(MBlXx5p9`may7a z<+xOHUnz`L(3-K5a_jBp-a|R3Vs>lFpC=v3}}r&MQ(wAc<45etlOf9YX4z!Nz_h^6wyucp3<)j;709!{v=(6DR7l+zY3zKG}3SSxh zIKhq#4IydL^*mk1W^$>$15ZE`+?TJ>55Pm0CS<#ImCE$+vW)vM`wQ zz{z-PAn0+RvTJ)nTabK0t7(S)=$j&Az=>d{ilFbR!nub<7B9H)C_Zn6Uc09GxW`TRe7yZ z3fhkaI2ojX?}k_hEj=7CWuI`JHyx%WAzn-}mupWV`Du6epa)ecliGk+)$!p?^rb%f oP2F;_2d~{q|D!>l8Q_W7nT{CNT7Gu}{;fdRS~&t`7RN6A13I^gwg3PC literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/mstile-310-light.png b/site/public/brand/perl/workspace/mstile-310-light.png new file mode 100644 index 0000000000000000000000000000000000000000..a497dc2dbb335e5cb2fab619033573715bd4c8d3 GIT binary patch literal 2228 zcmd^Bdo+}37@tZBO$~ZCbhK9$VM*1H?Bvnxtq2q<1)%o#L%4Fb`Ta#g~j?h z6IPFnS2p@}$Pt`27Z<$A6q0t)`^6Xmbc7VG;h>9k8ZQmIWN!>KHc0t=(Jr_f3 z$On+5V=8*1l=IN+?gpa+`G;^1ipVW-T;Gz3YqMeeMX~eCHk@OG;P4-HFL~Hk&CN)v z0&2<{${G@O7EDW~rLm*2qYRjaVxd?ug)xQe;3_NvWk62UDk2P&uv-t50oMcJu(hm^ zcd@UZW@)KXeR1)r*&3_yKwU1Koj=_+pb8d&8N7MAPYft2>oquljWrrGK0{kx1 z9Xc~{ev^BZOsf+6ba0VZ#yB~ZzQ;o`9WKO|`48I*Oqe0{f9PfHXYsO@+vY3u#odx| zCRMU!rGZU?=uX9DZ7A`JtdO3LV`lCtcy@My6VckG=Jl_!3YNw5N`}u9xWgEy8jSHR zMX0NJT0Z;3(-vdFwBa4S%v`tn;HjvJqLP~4_69*xEZ3(mDIz3+%558!0UGafv+Dx< zZFPU4MxOOl0Vm!XIaJQkFw8iP8($k73UF&1F*Bs#t|zY)M!Zf0S3<11zdoQG(OsUbywkA377my;a8AEMAnoOjCBTo7v3kp6GV1G$F7(m-83!hgF z8#axtpw$4!O}@rxIE~ytGr(C_A@b&c4aGM@TjeT5!5jhM{Wj1OQ5Hd;EG{G`j9=SC z1x38pt*hkMa&7Px;%oQX6u<)rpI-| zq~pF0*JyRHNCoRwRWI4}s*%rA+sCklnZu^=&>{KxwCT4G&!%*^e=jtJzw@3H$SFLt zy0^$V_070WJ`yu%t9{srRDyXj9tauzR^`R#Tm#9pGT* zxB{V88x3DWc*jDN9B3?9F{(OqzVi+5q-BNNFwI||6D6#qyU_U&V{n9Q(a#^T7%ON_ z7D|U5ttBuYG>Dv!fLjHNC9nRep&8tPF|}~$l8Q5f|25oy>;b4t?PDlys9FK;P11EL zHzD=?$$>uMi%FG1BCk-l3%#_U|B=ErDSu0~Zuv2Z)GUHNDetW$xk0Tf%@yTu)bj6N z>zH~pr_T>0q3zmSLQKz5D3m}7hZV1&X+9XI4kn~h7YXWGL1Clqd{`qvGBn1*1QO2O zW<@;C#KSyTDBg)g@GamWv0BrJ1Pw%$iC5vIAhZYn8c~dYiTBnlRW?v zf2#qPSq*Zi+>s-C5r(Y`A+2%m3IV{3DDd)H>iB$TWMxI?56jKF1d}(j=;Pwtt~?Vd z$%3QA-pB3Arr`bDM~b^AIkRK!9Np1#I%0Dve~wS3vy|TMf3-*P7M)jp_4Uk1YwJ?p z1;f0$I`uR@YenWijA3|6|ND&o8{9Oe?e8qg4f;{{6zhF;1^x{|SddQu<;LGd{RMFo BxgG!j literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/opengraph-dark.jpg b/site/public/brand/perl/workspace/opengraph-dark.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0fdeab99c6be156a9dc1d26e80a4a15d4e474f5e GIT binary patch literal 41101 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/opengraph-dark.png b/site/public/brand/perl/workspace/opengraph-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..146045eb02ac59265606889b7ad64180557d9605 GIT binary patch literal 22680 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/opengraph-light.jpg b/site/public/brand/perl/workspace/opengraph-light.jpg new file mode 100644 index 0000000000000000000000000000000000000000..87407dc2d12dc7ab15067cab754288d3146249f8 GIT binary patch literal 43736 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 RLjr$D;Qu8F=>0zVKLFyHtjGWW literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/opengraph-light.png b/site/public/brand/perl/workspace/opengraph-light.png new file mode 100644 index 0000000000000000000000000000000000000000..0aab810ebfb6b89a2eccaa22de3024af6df643fd GIT binary patch literal 22570 zcmd43XIPV4w=QgjC2#9v3!;bY-r0SQHl z|H&5#KRbEy*yeiz{jzSY$DRI(u1_6r@_Hk5>%PVH4|V4UlFa8Py!W~(J9uCh?0@Y= z-2{H}fes%!!~zH2f&K(uj$H&^LRf$oHPE3$fAJkVbm$KjVDtZN!~QQWb+B>JpPIk{ z|9j8yzn<;COYjr+FC;Copo0p{EQ)Bxax#$KW68cm;f7~`k>aK#hyz9Ytt)4rpwIBYOLlXOgB2m!d=}3g zVtW*}-nBy}C4C!ky%YOmWbe7|jU^CmF+IO}ax)A$$<>#28Dty5;GRUraH&-b%P+Q* zNOgoERZ+VIFF zx`atSN(NDd(BcR_1MeJJ%p_x_-npR4TI%vo96of+8aBGW;P-5}pA)`eMO4g;?LKiF zr#JIq!;0C=U&0!P;s>WWA^>NlCfC4Ab}N zU(_mxYSfvq!NVfiW!DtV?*qOVr9u{yt-DT}x0I@>^N|7NkE7~RcaH%21|_UrjpwsF zVfAPWX?!7cebJGBhj1Kl(d4^UC;p6Y;Zs^(ou?cO4Y|*967`fFzJWtyw@=XlV~)S$ zI|n~10m=xRKikjDslYgpR2hrQHfGIQ1!J&XA(0)IT`-2g6 zmY01^mK``W@QwQ{Okenvyk_wKIpn5BB%YJ;*DN+HtKO{x|2bs+_vgofXhYi~Z3UVo z{qr95bA^+@B_He$kRYHxe}>UE2Sg~^20;I>ygAtVKT@Qf1W-#rS~Q^ow|F4AcR&#R zA=Ur#yevS(891=T78trxL1nry(b1lh zHoM<@1W-2G8Lop8y7_{ZU-AngbEEdkEA~|xeq7*zlzxo@g!5}BfG7?&aGItPM}7>) zO);R@T4Rb#q`XI(6Bzzf1O5D0P{yyF ze#2&_e&-Mu1l1mJlQiMHuLj|LC3}N6F|V+G?3JKAOh z*2WoM)3LBnOT1FOv(|al%74ICJw1=W3DF0)~F>k@1kdKRGvSPE3b!l z5#OuoO0M~|cYDhc>@kiO-xxAZ3kmthxN&FL;2hvQ|8)#;0@6osJ!bp;c$1MCv|h(6 ztIq*8iA#s9b*>v@VmTW>9ZY@mXXsKtQ( zq8#m&W^2mgk{JF?yp_`mSZS@pxezuhjqXlY&RkM8a{911zXEJ*_EL%30=~HW5yP?Dz7K(ETuxpRPG+@e{DwINIPlpB%|&1y`w#CAST z;r7c|-|P%2zOk2;AT#NbqJpe593JD-S5{R03qRLgvlX64-h1v=+f3vrV1*aV5F5Zw z1&g-TomPA4Rhg>D1e_lRL*!P1ja=i*_Rh%KxoKBp>}v;K76fVJ=Pb=?(AiWq^#RbYBxX)-H$huPt| zjcLA|gSujbt+HO%od~~W{j_|p0fq(>&nPz$Qt9$>Ya`$GOI1Vk9^F{?2@>JyT}@s; z8^Qo}smQ4Pq(+a@FELayqFh{xCpFBs{2sX?239$`+3%|*CcURh$e1kkoc5DNR=Ql+ z=)~ra!gQ10F5c}IhN!W}UTb(=Q!zxpE*45$=~PvE%$5DbLML!5k7Z`%In4H>GWblYW{Qb^8`{}cQjuHbT4-FuThpw z**q$;Aww2o3_=;X)l;J@>BY@+wl)a!QG0|AS7PX>TaI$+{D%P@Kuj!vw><|J30*H0 zDk`j2leyiN3-rS7x zTbQ6SD~-hQagnzMSi`PLdu{i%+B1Z+fw?l?cLt3yW;mQmOt^NBo$&2@td4SClgP>G z;>%%OMWYIm7_jH`TZ)q-Q@7@71==cOcZjWqy0tJMX}!I}W>rmy#l_ZYPDOR+V-KUv$nV^=a}d%pW^&HGsc1k+74kHav9Yc&pOpqcF$` zon$4auaopos#m{9Ot+FYR{Uw6Km8J$r$|W5EyC08Z2Xc-u~S~BfcL}k=yAL2J~L3# zesGg&h4P2?o&>9atZMW-O|J1pRD-RqT)<{Z?7UyGtu>ttjJPy3rm_}4zAOwf2j7!} zj?tyK7(x%B!LWfF0c$+_+p#*%+`M9n^I`8?O#RYGS?Bdf( z?~zN+Ne)4_qfDr-Vpq!4;*!hO=kI;Wf${DQX_e?;`YPoQ3!iN+CS~s@Uz`wF(_ZMq zI~;AV8>{RcZ#^!Rfa8lawt^I_#HE`4Rn^o`L)nsT`CjSXo$Hu7?ebfnVnW3)`}@T# zQ;|nFLOU*nQ=x~4-tfYsDn~s@wGq@gzq+y@(Gh3Frek)B%<6?VmAx%~^|zyU7}(Og zQ=5F*o-v(=v%1yI4p;I}irh-=YlDxQewNs<~Ez4kL+qSAe|j6ODy_8vg3 zmM)Rg4OJh|oq-r@YB{m2R*(M;Ui)I=;_%fsqOHZpMnCk#n>~iLHjv4j#!1vkGH;MS zL85DUVneKc5SMusUpeNMutQio$%u9TT5{4?3@DG)Rm@ukvqmj4Iw+}zQvr*Le~184_Sco06cS7{c?wtTYZyT8u}X#Y`jQlZO+`i!L%Ok zGJKa6J_JtRzB{*7iD}7P>6#2{iF87wx}Q(+d~@Pw#!%dfd2@Ey%|}bVsvvMbw0drr zGk%A!ZZmnQmJkUK!@S63ai182@rCqb8&HI54Rm38AR(i;} zpBT6Xe|i?qL0z)5|2y)kOg$u?g7Ix_D6bclO;}TC`ei*M({AmA;FnQ_yydCKsxXQO zzno$%Ef$A7(yEG6yx@wRe{mB-ze0B|&BfPG!4uAZF%eB=# z2T$wGoOEso9Y?-AYXy~-?NKN}P-fR$>E0WgIRl;|&E&Vj+E>{XLEIDs~Ntb*ME*8y;EeaDIm^3o6Py56z zrlSHKWk3~Fj%TT+KLO$~wYtEAB zup*}Q9=lskROr?xS*lE z`ohNip{-rcBE^i~%9-P4I_<|P5|Wwl(v`KyI#j#Tj2N>1`DV;=&U^un8x(N0)Qu0e zJkb2WI4!ji2CLwm9kV63egxlg^DXCJ#l-MN3nW1k|B&J2+WA`rDi*h%9Kg&1jEnzipZU)89&;fz86;0|NyH0XOQH z3Z1k$fdbsWC5x!K8heu{vQAUF8c1e>$SXG--~5s<;;RU?e*P8?`GDCVW7>hVVlNEp zy%4wud^xzb@E!|ssTq#g^C@C-US|_3+}QkLoT~9#k94ZIg10;)zI`{edU{@e5@Jj% zs5#&pJM$TZ$R3TfW4H=5_B+>a+e6pRe$nr>IHu{oJfLfwG3QW3s{-j=SZLn6!E}Y> z>g+MyUAY640SaNiWnJMWk59z|QiAwSR4+r3{ z`hBip5&l%KmP>Mhy3x>2yEps*3jpdcu0%EeMUMF=$oE~FLIqT!qPu+5?`6{5ID!UW zse5dd%7Y0`ZrNQY{#27Y6e>@R_k2SupR9!t6J#hIVj2H4;s#eH}4 ziqJ53E26uJ+m0cdF^fY|7K}P1=o)r7&%Jm>2hp3R*eP)J*GVV+w1NnP1i*4CM;vm( z*@|1S#Ix|DQXr`o!;NB9D{I0Ygq*EIeZM>Zem`WrtXDM`86+Wt4QxfMB6C*ca2$>q z^KXCaLPp4XlIQd;$t<^~ESNAZEd>4yWM8bb8DlkuczZ_69JdCng9sJq^I9yyBuuL1 z-X>`=2gn(h>J(?wCbmb;>bNO}Z-1YTQOx^&iDbSypmHP=zSb*k#4WOUw5DA?M$;6a z#3|TwvEwSrV48jb(GZR2t6QJyRKP-2B1G(CUoLVMl@8M>TYg~s71N-}C8L*(t^95h z7!tP^^Fllx(&6d?yg!L$3DI@zHVNcp)PE0MAN8D$H%E47g=%s`Y*s8M1IgW1Mdd~W zOW!fq`_Uh~wSLW4e*$HdU)=)al)GzRSL(=E!F1(-fe7!>R1;&Rxj;_Wi=c#XzErH+ zS{P9OF61Q}nnY+CY^cjmC;M zjE}Q!+1TDxtF8|5SfeuM`p?ji4qj|eafFyV`DP!6ua45;Jf<>T;K%6hL*kG^?lkdM z6(S*fOqD2LCOUO5#$26l(s)E(zh#;X=M&E@LRsk;+5ZtXK#o& zlhRfjkW`F6$C^?<)YKLG#iTCff8v$D`69$47lb-}d95H=h!?imz8Wls#(3!StDeT3 zMCE_jMV#6*p;|1t*V*%z=hbr$4)BYBATO{3f!z?H0Db;7kmDVmaj6dp0O{x#3h*XZ|PBn&s z#qY6*vZ}Gu3JHRq5N6C#Y(QYVaJe721>!E}xXJ?!VMW+yAP)_!kCG`0{>*sW!K6R; zU+MC3Yp#H<6PEH8q)F9JD}vE%R=)OD=~J(oVsic0UFJnV3GsYfUMPVf-ng4Fa+N~Z zW?=i{JH3BmL)T|t7TIkT?V1whzkQ9oMEq{eUq{*OH8!c=wU!bd9SEb<*9Wiw?nr_~ zupw{E5ME3v<3ZY@qbW2kYPWg^cS;s(Mm-m!vRBP#As8Y~zFJN-nbT#2QqK3tuc3IT zd|MJADSKe=Ro`>o)d3I>5^*%<7iLE3JI-b~wuF1e->Ompz%3;EXH+Kp*2=}4wp(AS zumM^uqC0AG?vtsNorQK!yGwMHG2>TXAmzWkx*WKx|FxB`OHkWYjM%xDS&zIS!Rhb2 z(SPeltoHbe&YD=}CLQa#I4BmlbqlDOI*4usJjKJqip#@s%^R{4TfIZNTT5}n3Z#&T zU8m*;Y9j@FkwQf^g)6Ps@K=f&Hs;dzXm`ZpW|kt*wP?w;dj?L+!N%R^0hd+I^?k4i z`3Mo9@%*~f{e{%uIyJ@rCCaZ4N=dq|Pvv)J;0Y(WMf1$8~vnoRAi7W$JZdb0T>z|xgB zW<~~jxW;^uR(|{udvdoW2@#QpiBAL{ngak;C7;C?HFh9ngv_t?0p3b({K1T54Vl;9 z11PM(5Go=6+vcED?}X?43#ndtcOZYv2X|+gcxS1Gc=l$`afCbWN39BzauWmCc%3& zKQN;cuTXQp7+o+#Py@pC481iSwG!h*Dr`vU2Cq~$>xoiN!^3!?7KAcK9fH(!i_a3Y z9s6jL{0@^yNd~|aTo>)?>^$jkA)|_A4y%yqCPC+g((WwMN&r3<;1iDF0O*XZv1S`d z&$QZ+6@6Q1%#GOJMjZnB()h`>6xx2I#mbCv>GXo+d1*f)xG!V^-#4h64U z=HNaqqT$$;xH|J=E$bi(K^9@9eAiyYvJw$Am@dnJvR4IN_8uA2@mY!prRR+^bljaT z*x4%69UgzgpjORz3`cope&3*o(9dT2Y_^~Z)>XGkXU$WyQoPfH*e_Taim87^Fy1E^ z=Lsi^XdDJIwd2-nq2kwIyUk1qQ3j@33EYK20M`NMi!4I!NwQfHT3`B~$y>4w^o@8lijJcZ?^@x!rq^XwetNKkb_F*C@ zl0BdZuX~_jTyTliH0CPgHcwo|lhK`xk?5B{djXQe0Lle~nyMovPV07*reYKrdKo{{ zYs7$$x!)fK)j(#ToGzttd=_J&;-!CfnJu~YH(%(=f{sQNubS4f!*A-yW$hlfJGNHB zpZ>j}cOQU}$M>Z98E*MFKeal*ut&&zkq~gQa7nx<4EcT4vWW9CO;yg9n%QFct+NH0 zl)05^XI-fSacdeL@3 zq;joUV7oWCek_>&RIn2Y-n<=b|5==WYxJe4b$qjn?}Y39;q><1k4cqiUxoL47H2|= zX=pK?SW*8+VeTnesy9)toxf%%)bA=Nr;g-CP&_lfx}6YQ`&VUf<;vxlO6~8{x(eN< z*MU^8ZHgI{nwRFeUnb}*fJj^~h3uDlTt3;*NEc1{7!6yTQhXq~sJ@w3n*}FAC{XFc{uS00e zt6nf_t@>F8N~@@PH-7v%|B)PRa>s)sG-F!;p^hiK=t}im{XX9t_>fEMwH6O#)Lr}^ z%E{U)6lmKxh&@MsFl4mGjsp_uA2Q|e4}Rx>n0i5L?KlAOXw4loqUPYsb|+4t!mQGQ zwpKDt!nuMw>t$6XhusAahAud>q~Dmr?H9MQ#Eb6ZuOXt-*2Arg4k)}!Ao^4oqA_~k zCv%0rUbcBn=qC}z<)OCiZiL;ks@hp{)c--Z9*{=#7A!4~Aza%lkqg1jzj(&K7*HdW zuhVl-*;X;pe@((pP7Qc!W$}|Rlw%1M??KpCV=e#nmvwBxPAe`(X%$VQX8&O+tN9}L zw-6$(Iy83efS3c=&*=u&x=`%He|=S)LU;7PU?6EU)X(qJL`8EH@4lP?NWPG-7k^0k zM)GVZ%Ntb=DJg+|JuqBLvH8G^#E}6%gn<+4h{r_hIy+XTn4N} z4;QPe>ifrTZ)0eTU^E^eo0cC5M*(%rRIXz>M*x-zfMR$b*@+ud>91`wf_H(WPG0h# zd;>Tq8+$MsV{b9Ei?%A*93L9CBr&I~Y$h~hNN-VScT7^CDJF zp8V-%&}o2QtghPt5+i6!K#5vdxLS8daV)#CeV z0elWg*~Dl2VS|>qBh1~lata{3gJQZtSwZiG3X#K*!#@B%EqfN3F{diEwfg-@0ED8| z?o)@?VBZ><)=C?%nX~$h`j@$mQQpfD^2aVGT}%$=bPRR~=mcO$EtdYvNw=T?=96E& zxTdi4Zg0pPt+a-U;N1W7BIv;TA8>xfFC#fC> ztr-S&&tW^W9W}#+Q}G;8xyq4%Yd7+ora?55URzDJ$1bLI=J)|P_#kzpuwf&f%;oX@ z)ma_+jX^19xtSLQej~0mvoJ{)|J~8~lYjoE6fG72cYVEK598-8xwM>h;%tu!DP-2z z3{lq|$muTO*wY1o7i&BLRvV8X6xW8HHJ{#kQk+<(jl~9lwMIBWI*ZC3Jf~OuM$4wG znH9Zm%NL1}Sm9l3{v}y7ILX(`>!kS69&P@&bM&eu#uJ<6QeppIpK^y~IGHjxLv!GD zqaszOtXe`m_CuM)cvf0c+?OceiiFcVuzsfkxA+IhDH(d6z!@Nmsb&vLl`osMhc}FW zi)mi*)^mHnq2RZCfdHKpQvbdDK9F5B@=s8>+GUVW7GJWy+*6 znCVFrqkmy>heC5#FA#S=YLYM>1FCFdwgA!S>XV|cqe>=^0ciLQ>kX{wcF95%cK;i7 z(_E1d>3!@Xci`4WYp1TxUJ$-9jQ5Fu>%Ail3-RN}FaEIk1NzL`A(Of(>l~kxf*0~D zM0kI}&;S&*Fm6H>lv!aaaas(qxd;GC^}F`8vQa)JvT8E8jAFCu)2N=nwq!@r#y94)>Ba-KI}%HZQr?UNyE{_51qGVn$~Bh9$*-oXsO%F5cB%r!B#sfz+(0Dk)(L zfY*uNxqA&30njPAryb*M4OYSJ*f}WoYVtsWfV^{jk_sR_bvwg~(W*OJjCbc>0SNI2 z=fVaYz-ez$>E-dSI(2)FW@?f)`i}iebh&@5Dwf&dQDl&!fZJ{pain+znUr0 z9OXCSbAN!o>#(rfE66Oez+o5TfiDR7oZTvKZgizhNK(M~>2Pqvozfxn=ttsduNBjn z5b?FnB4cn)_2`-`Mc=hwEJz639hbx^#5$|kZFTAbZ)H%|IRj)Gu!f43jm#vqcYMuE zLRNCgF*_DL{s<4CK;*xn3KoJ30LgE!K57($2g;wj`IWWq9a7xmi^!cEu8&~YbMFH8 zo%{9Mi06FAfFOJjdrqQ=Y9{F?9dG1&vM<)mXP7$?2%p#lx<3grM{x|ufTWHLJn5rs z&iY7z^e;FUAnt73cP*-U{8p`!SM0LV&Q=TOm8x(UhV;29JV&Uo#l?riS|(W7ErWX| zS!H^8R7$dT$X9uUQCT{QSj$(pTg$oWHjI&FDD>rlbNC9KewradLX4AHO|SJ5dv?HWj89F;B@H4`c- z0q3o~FJP2Qh>2A*I51sWtB9{WNGh*bNo~LTaYGRqeL}3kLg%_RkKLSgrA_av+jP6> zFx*bQzS*Sg#la`3#f&J6NaJ%_!?kVC*GN%;50~|IV*=M3m)jD;76V!4;$RJdivXRw zdb;E3fOgdga>J_3LUW^NbQ=jUJsjt)0sweMXfew(EoMj6GPIoCr*395?|fH(kbB2= z0=VP3S99~LXI%Y@d|h4bK<7b)iM))y_rM~@Qs?}|G6h9O)V(-i$Yv1?3u}pVUvzuL z%@oW|XCbXGMB^;yx*gnHCjk)GUpWGC%>r*}K*KJB8q{a3=vGob_bg9MP}@s%hn{=N z+;ZBzbDhb_MmUVR%jq5r0JT85EfgjsW(#nbIsKjJ3=fg{uQGc>fBSlf!O*uU^I=)r z@CI52SloSOgupsS%?&Bl8AKC(Rqy_@8_iqf2q0zcNN>5Ot_h*I@= z=Ihe8bk$knmokl(FZT^C5LtO|(A`=Lpim8y~a2*goc;l7G_t zyrl%4`8?3R(H$4Q^TMdhPo(Oo6DuyMzzi~CE^QvTJ*@a#7R+THoyuRB3>Hlc5j5WD zmQJl_pA`+`l_FOOHJtyqo9M~IRJZ`_f}nf+gWNG#_r56@VpQUP?^;NF0-J;SmvFwW zc29!Jnk6HOafvl%pgc|C_0w#lhyc6OZ>P+4&e%!3sU4V&TpUz3NHVE0ULD`Ium@j@ zHxqf0Y??gF)x(%;2o$&{=1D`6w|wHSX1mgwuXMj=(}?BB zkF>;+0hM}+-@oJV=cx}hz9q4#f3QK8)aOu!s>bi%SKH5_4Ubtre=;Zb#+6?ZTa@|< zy%>(r5xp!-pSw7GuDw4kN;-~Tu<%vamGS&@yRimjYY+EM*OYtjx(2^&B6^m;h9^AP z^5l>A>8qyx;mT6!8q>npby&>#;%t&L$Q&b^!f{Tvb3P|V&BQanvCvHT8nOjwg;{Gp zo8^wLikvz`3cg(Nvn6*4>vBZ7I3^Qz^ zHuV%amI2hOP_-SH{*kyO?<|JgyVqT8_dKS2hAXGJt8q)H80 zWa__{D1f{dEH&CY9&~tN(Aknp6+s*%)%Ax(p&mf=&qLbBpIDjRHc6VQ$uC*W=x|mk z+rF>6|M*p>Was6t#Hr5!Bx5q+mC!(`*X-3(l$J%9f)27OS|?nBnu!Sim(lIQp(ltg zuYAt6$8WWoJEDX-1m60nnbfyi`-K);glFblR>d#L7RqH&klDe6X&>n5p})5SbzZ0F zlor%Siq9Ga>(|(nZJ3r`*Q$xXM_6h%448d|zLS$aBnT>NRtMtDPI5rZZ1a28loxL= zyU#u@;mGT{JaZQnRFb2X7BKG%Js65m%b+oUUA@wEp$-*;nH$<(hNY_zvgw zjtbb_yaIgKREF2}z}?2S%CKfAdfSq$MRwy2Hujvxx~{iQo_gXZNpJE?=ad;x_j0;a zysAz$lr12~X9e7Qw)Gi?9`hfbtNn65FVd~*Q3$a0NZ2(xg;Bkr;9266sIrq~ukLJY zzkFZ&I*TzY9wHTQb&vSAsaTs$ZPc~5K7#X#!x-`dL3XmV+H*I@ki}QBu@o>owuA_4 zhpRwy(efjKPOp2_zPb^0dyG%71*W*w^|8Zg2qN{J}}XJ3i6{m$9w0tZmS z2|ucKm4T`{QBHtYDr3Bs@Tz0lND(iea?dX9L(6GY?QyTtXyoi>y;ZaC&olL$EXFx*2={={s zm8BLPF+^$m1^F7C{B5*nuSj*IxYqM{?1R;jEdejPa8A1x+i`R(RMD(JQV$^komWfj z#CNco>Nofps~dIp-x}4GY_cD1EG>bR;_LWhJprgjrwi~J&j1pTuD#322=}@#i`P-y?`v~jT{vt1u-JTQ_1_i1a<`#g zlId7NLdlCz@dU-}o8ftTrG}PRX4@5ecyoTUmoCwTL$zTvezjtJDT+P7eTQ3mwf#Zc z7tG?tFJ=wcb=~GD8gf*4%)0Q_k(J?9r zN?HBGMCgu{iouG@`0}59xV&!oNVZy{(3#G9Juj+tQBGt$?AmvJ#|((tPMX8*-_ADT zI;d0K{*n|w0MrZ1!bf~_FbFSpXR*s&j4i@xdKP~qE_d;)MpeOp)WJF7t*~r(TfLbG zLa(Q%`=N`&38R>{EG=`(>my5isSO^T2u9X;tke0HWy0xBPQQ`YH#@=}Pn3ONMA;b< zZrb160gAk*`O1f|WD{6qQJt5xxL8+eH!hyxZP2GESH#g*VVvN+PiMuIAs_Fra zcG-_)PBkxTbj)$gRt>PjN8fzN@BUyLgKQK|)mQPFK3R{6^PH{>?FwNzfGS?_Eqk%d z-K(Ey5<&Ob8@60k1xYcBD~g`?b5G43ahCTH9ltj1qv6{9!JTQi=FF`MhVflDN)BRLsv1Q5_5@wj5F z`(;l0X#17%AZJ!J6Ub8=U3A!MDAR3kBS8=Zw=+`hjRlC*9{MR^8vnf+*&MD+}LplZ0!3*qE$BfE^8?U3sC3@ zCxYcqSw^avFkvgqddvJuUpZiQlaiRsJiV-RgbFa3VzzgOa>i=3J*OGHbo_T_YdIsK ziwhRk+f9pU&JKog!6#8u(B5ldvk|>8v}I1h;acI@U4S;YQE4Op(NJ`>znWeH)AN+f zBUiop?aJNG+=f0AX|aY)+ax>h*DbEhQZhhmYq*cT`El#Mk=c>uPtNY!Gb1_4!HPxq zQvFc^j)PDMW6OB_Q@pTax;HqlN=_(w&Ryt4G0<1|9m6jkVGD-6=JQeC0DSw zo~YU369X_=Vk%RYJl+Pzz__t6(g|Ly{o!fSIV&GO94@+~QzI45- z0nKxe693TkRvd!O>ig8|uE$yS#)G2l19xlI@8!m_x{20MK8;bgO10DqMednm04~xg zeT?muHZDcw&#I7Oc4e*ogx*9Pax6=qR+f4VJQHU0ZZRSY%-1Hk=~MCSHLfJaRQD?hk0t|K*IiUh8Sye0IuD@ZLh7XPr0mkh+~2d* z4%s(5A76e3dV^&X?BjE>OMHJKri^Xs@2$OT{Jp~Q;X|co)UD{HLPmS0|TM6=0X+IQm?~5BB7Y{g``_! z?PXWg7dy&49r0Tlc?drVP=r%hD*!I<47Tri@f9+n9_KdRiNz*j19?$zSG21pz|mJ_ z?k)iRU7FffU>W~=8b(Tx+8d$%v?e|umKFg1GhkbfGFxHD7)^mqc#)Z43IKKYT5W+5 z>iDF#=~ZV=q32hjeDLqFuc0uuIqb=qPUxn<u^{mCADm@}`|zQIaj`6(O6WtAtMlcvx+oW^i@~srEtqU$sCJ zg(`J9cF|Ddx4(Xs-fNz++x$JO)dDskGODLE^tvW9X_~b9)-N88HY!|63JBFAd-i;E zX)!A^xD)N&QX~mji?_(rBB=qjR%KaHw8@;h!{80)dK!yo@y)pYnyV$isuV%@;IDVy z8-u+q=gcd^+q0kE*hG@?gYrg6Gf6_6korq*G8t`O(2_#bzvY2W$TWkJ37TJS0sFB8_G* zd`e#xXuULi19bR@+y9UtdBfm_hEc_CVs;YKYVBP{exrq{T+ss222o)lx*XT3+=Z+gIo(p05 z*$wcL356laU)x6veZ>OkWaZMNW~&>6`!$f_>&&;dK2u2va{oEHEX*=?A3AtvUbcRe zo1~NoQ(jos+V}lRYvThRFZzj#iR!CucX>}o^fmZl$$ziP>~FVDghs1e-rxEj+v|G< zKHwNcCX^S=^`v1kjV0YDmy3|;3eLoQ9kvfcHJT`{N7PApDA~va(8QOxrUHWn~)O=9xIOq!+6AH!Ru{!2SwP?pF3xo;7i>a9(M$L z8179!A79Nybbmqf&n`iD#O>y~779W)?U;qe1d?9q zi`C6#BQ~)`+JX2%Z?WE>!3m*#^7epO;6fZaIh`fPOsr;iI5b+JKJnXyn%iO#6Lo~1 zx8Vcdg{5n-xSaDW6Ou8LC~nm+>?ID4vz#7&{rZ+?nagpOp| zW>5>u1~#~cl)S*>sA=Dzja$zwOiU)O-MJq$TX82gHb9oS!9Al%M<9LmbEXc=qbqjS zGi7U7(b3Z1r*K^u+zzM*vF9y`Gvh{)cuahbn=gw4YcBx>e>uw*7QT{KsKzQSrvpscJ{CdM2=a`SD z%aU-d=?cU_h7Mh0aLZxM^x(cYSx5D(F~t1kx8zBGa{bO4e@1``FL_gNBC=dJU_Z3Q z@!o_Abz)m-@Tn?w3+%rW<*pl0G_^iw8Iv88%6v0;wS%)29G3bPtva{inA%2juLlN74`k*0Y5KjjB_TIVkm>tr`);i8 zS^3$Jfv-nn@~EobcgN)NA9USUrq&60pG1x`&$ni!5@eohKQ10Bn_(nx5B?zYy40;hk*kV0!2f+ZWpZ3ouvCo5@M|I_-mf zkjo`b*~0fm6wNF|%g<6;%qKm_ZBxzX1h!+>sDDj!=4Hx71}tVv>rF`17%JK&m-nzS zb9?z>Oe_MOVyJ9zs8`;~b^Ssy5uPB_mkc{fnOL0x@>}hCXG*%*Y6KnyWgIo8@$bzjAD4|$*T%~Y?N*qXCFt&aQavaa_f`k%pv>xEik8Gfp6 zy=Fsff8>l*4jX?F2Y)^Yb;U>{Rr0?6mL8Ab1JBWlDmLce-jABebhzNKjQH3-iXWYX z4MNxj^Yo=|iL_jT9IOFR$!&K1@zcjy`#JAh))4FW9*ClBxKm$!lt1MPj z?^C6y*L2hKRQLpsu7Es%Zu=ZtQo05VXew_ z4(m0UHpXnS6Z(oo0Hg%t2HYl+7R4x(U_y~WqOsni&`0`}xih$S0* zC)k_ftXjWQ%C%(>l!cX zD(OcyopUTH2q_+74V8Blxwbc?T`6pn>t9$a@iEm91~Z+;i}`Gx%Pq3`kS96>hT3{< z$ZGJi>s&THPK&t+lS;>r|Kly!1=w*}5;B|;W&zgT|)H95i+6tT0di6JI{nqX? zoTuT+XJbH_FeHziW;>4!Ny)IXRlNAlieI>U0nyf!&YH_>*_2~t+3rD-qNa*L-P(@H zaFiKalXEUf2Z_A|im;Dg;xNOtXfqfS3dz4MQgJ|B;y6N*6i(=5?x9Kn$qq|^_fwIYgp8EF^ zpjH(!irLD=i^HU6A>vK@S8cY?;zI95UuY0?GbM^Gj&Ds(ET$skeO*ek_;N@#b+glE({7Sv^Ch2g`5rG7cbU`^1Cy)9MZf>EA$4rVtI=j% z9Q#m$ty~n80+umlgD(KIenY1J>&uV-EH|)QUzoS-%jD}~an4f>v1_YsQulO2EbX-% z50;uRs~e*ntAN4{o}6ycF7kvD2y6S2deK~Sz?v*byrK86)Pm^+U!fymEXy3Xm8Y+jMDGel=C(JFnG&z!sP-k`8XJk8tX+V-#(f>rb&nSlOs*k1aJX5D+XRdi?{McAm{HQ+d&+dn|=GGHS}&Q=etW9sC zdfy!GvN$_b4bsl_^|Ca&)NWi#bQ;LH-a7_RCg@XhLJ;0SujdxYf|XdgcV%f;6c|yp zNhQyg+-eZjEu~IAY<^tS?<0jk3*K>tdL7Z2$3}J{31$lxo+1_H^A3I&Yu{omedx&yW^1w zd8jKpUfM1l1x}j)sx;%)oL3-3q`a^{Rys9cj!4wsSkM;o)thd{NC}h=%~vKu6*ix0 zb_9I5)9uxsB%GfdDsMftR6hzzmlEwUm8uZy3>TIw;wHQJu*`{u33DAc z^9WJdew%Ob`h78TXKxa@H+;lyJjF8QUZA>vnG;Tor8n#{RM z9yc@egr1{ss6JPg_`o!%B|N;ReB37LeV18&T7k(xSUNWBT5)#nlF=7_{d`5saqDyAbXPc& zd;bhth-={!mU-J*Hm^{Bk~f&rr*|H%dhdb@E4=wHJJaLZB!~R?wfEH!(UT&gTq69> z9O^vP;#R!xfi<3AN&)Me-7rTkWizKcMK#wyHWm`8O8dx!;)?H*6CplqBb!55ZS-HZ zQ1073TK&em*U~4KZhFi*kAbPvI3>oOW2X6Az*y170QuWxU0_e$uNEv_VeQ(B9+0{Z%8?WG(=4xRj0Z^Vp-UveqTd;KQ)IN|aVB1LpvXPynI znMA87PrB4Z+Z=z5q{rQiQO5Z9TL_At$pd=!2TX+1lOA-mAh=+=>QQPY$gvhzEaY8v zbm5Q=oh360h%Xr86Q4CNTb64_!$}Hg-MI^u!m^uG-v|-W`MmoUPm?~jMX$`(-oiUq zcC>LdPo;4Wd-#0cNx??ac=2SzF4W&QljR-&~-t?%3!W z;}foOY>TJ!@oWD>KOkX@uZtt7q|3nwk%ZozsBL1Ei}=`i`cWXcklwoFc);VF!joRl zz!Kyt04$!gPeBAJYbPd!RUr5VMLEXaO+|Cq3ZIlpF&R9y?r^(+z4HS8OBukcmzEd! z_IF}y~+sg^UQIOp$dyU(pG1#egqrwtF5lIn_}N~UxyX1u-Wnwx-K#mknMwme|CuBI&Jbj3L?UaYw}%{+xPtqGqljD8Ba8QBg~OPg@BW z0uiC_RhoV{gYnx8@girERwl)XovkgcMJ)%i#D{*Y zajyZ}r^|{}Cu)ze!=1LLmKI9Jtlv*<&)2&t92xEaO6EA%*uswm(TtbTqQm{$#R2_W z|6e;-8q`#pMR5=W1b12yMPY_!XfP2N2mvG@qOAzXfI!$nSfl|Z$W96Z-7R8844W!22T`Sbp~ukQD~^X_|f>)dmX zM~x!V^rvwQzMMXfO6sq@XmKR|I5%Q{MareJbe3#^1(;%h!i=;bJtAu8h{Bd7T929x z))`O^a(g)e?b;_?hMz@rrNmO{P19%n++AXJdpq81x3ylKBq?vGGz7o8S`!gC`{&5f zVIQB_znMVM(I3a6^+KNnUA$xB9ncWrKYWOyjG{IM9WdD$GtriOu#EGEueq}?;mVEU z_=Q(*Hnfohk}&HEba&UJfAg>v+exV<;{CpEuU>rGyK#8xW5#WVXf;=095k_b_}a6e zyWJsncUjkoUh@xc){ODi+V*xa>Vu=}+q1loS#6eH_YYNQCxrgoLHko8H;V@36S{t2 z9r=8iA$hB-8{sIYIhuIctp7j)xP{AFCR?CXbg0Od4zDRswPTWLhvRZ}hsfGp`=Z|X zrz;Mbl-}Fn5~YsJjMl6he#Cdv_fQ^uax`tG%R}C60&l-#P;p(L_~H)SLDSwDA2F_0 zaF@&q%jr=Qa%=Uh3<88g9dJD#OERYU_Y^je?uSYsLR9KBEhnZHU-cC_WPVTATl~@ROBrUn_rPz|F5a@AD(+8VXRj{SKUuw!1E~_{bdG=a3-banbxz^^GB&}uG zSRF;VZ0F*cbd3Pe0tTo)pW4%BKDj6vTi<7;i&}GHhT&(h)5ErBp-@}v_dZ@8$@^Jf z95|i6MSK%0LF5F((txrq(4m(eRE$>zNZ=95qFZ^1Tc+V`epOy7M9tz#b0zogL@N~- zZ`k00coobjQPoS|rdbk=TPbIw{muy}nSqW3WnoAI`|-dXQ}dOL0w(HNXKn}02+irAi#58d?woODjfDoz2KX>mUfkW6c*=pF%A=o{F)V7y9a zgG;%zt!HG-Wxf^~7j}W-Ly$f-9q2ymc1y3p<0o9-=V;~0x2#YeT|KS-4|ekQQpkJu zoB|_3d*HYy+nd~nqw4`AHGrYmx5zEm_j-qRb>?g*dBMeTh#I|u8H`tbvIy1Xx%7cM z{K_W-iUIAmotW+ZFDSM1K!Js5I?9&9&wGhz7`|;K{9FPOpw77Qs0u2rSua2kc)_3Vw8 zy^!61XNYNL+i7fK11q3{*svxfvnax)GWe%WPp;~jZO8?fR%HW6*t{k!jwN^UK(M(p zzYFY$SjWOKf85lh%Qqcm3W*d}fRH^!UEcKL60f|qDT=?bX<8++YXts+GGfiU^SGao z54LGSo^5!I!Vc9*J0URPViPeWfjG}VK;I{+8_PHa988$549u|u2=@U@FY8%kty|jFc#3=5TeF(Huq;1tj?a(B7Uk<&aG5G-S3KOfs;!& z15P!0XGE|RtR4^=3&H4CrLy%ADL~Bsz)| zEE+u+IIM9$_$eOcT$_uB&-vxzMch1&24Tn6j~Y!IN+qk)VU17G!4;&20#nRAwhO@G zSLe4rioZ)|mq aERpzu8vb(DodX~tan{o2ROLy}8@~Z=v|oJy literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/safari-pinned-tab.svg b/site/public/brand/perl/workspace/safari-pinned-tab.svg new file mode 100644 index 000000000..a47672b98 --- /dev/null +++ b/site/public/brand/perl/workspace/safari-pinned-tab.svg @@ -0,0 +1,2 @@ + + diff --git a/site/public/brand/perl/workspace/site-dark.webmanifest b/site/public/brand/perl/workspace/site-dark.webmanifest new file mode 100644 index 000000000..5440a814b --- /dev/null +++ b/site/public/brand/perl/workspace/site-dark.webmanifest @@ -0,0 +1,36 @@ +{ + "name": "libtmux for Perl — workspace CLI", + "short_name": "libtmux", + "id": "/", + "start_url": "/", + "scope": "/", + "display": "standalone", + "background_color": "#12161D", + "theme_color": "#0298C3", + "icons": [ + { + "src": "logo-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "maskable-192-dark.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "logo-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + }, + { + "src": "maskable-512-dark.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/site/public/brand/perl/workspace/site.webmanifest b/site/public/brand/perl/workspace/site.webmanifest new file mode 100644 index 000000000..ed6614035 --- /dev/null +++ b/site/public/brand/perl/workspace/site.webmanifest @@ -0,0 +1,36 @@ +{ + "name": "libtmux for Perl — workspace CLI", + "short_name": "libtmux", + "id": "/", + "start_url": "/", + "scope": "/", + "display": "standalone", + "background_color": "#F4F4F1", + "theme_color": "#0298C3", + "icons": [ + { + "src": "logo-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "maskable-192-light.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "logo-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + }, + { + "src": "maskable-512-light.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/site/public/brand/perl/workspace/social-square-dark.png b/site/public/brand/perl/workspace/social-square-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..0a7343f457e917c546923fc1fd8026ddd4afe644 GIT binary patch literal 25379 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

xc9PGxoAl{UT=Wv(^gk~wG8 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/twitter-dark.png b/site/public/brand/perl/workspace/twitter-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..8b24f2a96e4fbf8e07c542b3966e6efdf34ff0df GIT binary patch literal 22533 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 literal 0 HcmV?d00001 diff --git a/site/public/brand/perl/workspace/twitter-light.png b/site/public/brand/perl/workspace/twitter-light.png new file mode 100644 index 0000000000000000000000000000000000000000..a2769b4596d0bceff448abc652d74724317b4110 GIT binary patch literal 22424 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 J>+qW>@jt)PU}9RTC`i zWvQoM=;-8pHt7AVQjuAw@lvumbk3pBFfx63DIGpghCdrOK|j|K^DUQY=0S7n{G`HIHAW+<4`|!b{kFS6wn`o z5QgR>^;VuWxQ$r#1U>sqvaAk?$)1qORWE;?W*rD_e$W<)q3%n;zgat2%8s{ypDU_K%)60Esf@5|qckJ8KpJrRf0okYG+MUZ+8lAdq9m=AV`A>5K z2ym$HoO;cg+kk_ENfvr+=5f?DR71G48kmyGo92YQNM^Rg+q^2b?DV{~Q0hxyUWKfv zK~!w_78oV7$vwASE3t744I3dXtYC1n7+1qU9>{vX+c59FM^!?s5U5$Hq~N*ik;N`j z?gx;DajBgI0<6l)sWO<#2Iez7VuS);l)_M_u5VLku)TpjXYP1V+RM=U%V!|5b&a7S z&8(+D;q}eir#%nU3`m^|XoaeIr$jS9z) zDAU%3{oQ>5$;rd(HDUA}WI0i<&E7)dDAABg?0e~U-Z==LAL#&`5MvvPQ_Ott#T&XU z!T!1SPmj>a;%2u$39%jeiekp%<2&OO+uj@E#}yATQULMI^l|ny5DS7gv4V&hBkT}) z1dQ$3!;DK2Z_e1ZW;q8mW~%|*Z7BiTEx?#RiM!oi(wAN4u`!vZ!<*m8)CSEB@%Da2 z@+Qy9a6=v?y;9ku?SNUBx_wuNN492u?|#^EIv>%V#oH>Ic7C|J3jn3=F-8Jr^Ue}=| z{V!5HUw4oX0|Wi?Z@~ls=iQ0(9?U~Z218SETaz?nT-yi)HZ2el8&}ob--OuKd%Zo~ zj>;C9X=J$gNCAL5n>-O%v79KI0oSam4I5UN3c`aqg5mDL7r%^(Xg_6L;|Oto?JvQ^ zQ>X%kvi9qy^Tm>R_d7mk$nYB7u;+XRu0{VUkPxf3lfS_IF+3RRtr7HYnOv@>2m=?J_&e0zn!;@mEVXbgz^4De*HmibfzR5o{IYwD1QX)#OmcZ0BlRlh#oY$nM$v=g|lOSD=e$K0dwWaCLc zOf#PRhos$A<5;#hDISOvuyZ~_0MvX5c%cC*D}c{Ow)i{D{th4iivVfDAh3EsbpO9o z{g|k(^9ZmcLttD&?Yo3a!pup@KY)L6{^C91ugnd;daEK(9MlTj9YUVKwIHO&pT>Fq uiv4%9C%1(^-N{Gxb!7Gl<2~{rgcq9iH}n}SFylu-$m(m`o0S%x3I73-O=Xt= literal 0 HcmV?d00001 diff --git a/site/public/versions.json b/site/public/versions.json index 92c408cda..7c26be53d 100644 --- a/site/public/versions.json +++ b/site/public/versions.json @@ -128,6 +128,14 @@ "kind": "trunk", "supported": true } + ], + "perl": [ + { + "slug": "latest", + "label": "latest", + "kind": "trunk", + "supported": true + } ] }, "defaultVersion": { @@ -146,6 +154,7 @@ "swift": "latest", "powershell": "latest", "julia": "latest", - "elixir": "latest" + "elixir": "latest", + "perl": "latest" } } diff --git a/site/src/components/CoreHome.astro b/site/src/components/CoreHome.astro index c6edd4423..69957652c 100644 --- a/site/src/components/CoreHome.astro +++ b/site/src/components/CoreHome.astro @@ -65,14 +65,17 @@ const rest = (group: keyof typeof CAPABILITY_GROUPS) => home.capabilities[group] }

At a glance

-

Server → Session → Window → Pane. Each level of the tmux hierarchy has its own entry in the {info.name} API, with the tmux object it wraps.

+

Server → Session → {home.association && <>{home.association.name} → }Window → Pane. Each level of the tmux hierarchy has its own entry in the {info.name} API, with the tmux object it wraps.

{home.objects.map((object) => - )} + )}{home.association && + + + }
TypeWraps
{object.name} {object.wraps}{object.tmuxId && <>, ID {object.tmuxId}n}
{home.association.name}A session-window association, with its index and active state
diff --git a/site/src/components/ProseText.astro b/site/src/components/ProseText.astro index a7173ddac..f7616c9ba 100644 --- a/site/src/components/ProseText.astro +++ b/site/src/components/ProseText.astro @@ -1,5 +1,5 @@ --- -import { decideMention, notASymbol } from '@libtmux/api-model' +import { decideMention, notASymbol } from '@libtmux/api-model/reference' import { productApiHref } from '../lib/product-api' import { PORT_BY_SLUG, referenceUrl } from '../lib/ports' import { defaultVersionFor } from '../lib/versions' diff --git a/site/src/components/api/ApiCommandParameters.astro b/site/src/components/api/ApiCommandParameters.astro index fbf03c27c..7191282b5 100644 --- a/site/src/components/api/ApiCommandParameters.astro +++ b/site/src/components/api/ApiCommandParameters.astro @@ -1,5 +1,5 @@ --- -import { parameterId, type ApiSymbol, type Param, type SymbolIndex } from '@libtmux/api-model' +import { parameterId, type ApiSymbol, type Param, type SymbolIndex } from '@libtmux/api-model/reference' import { parameterBindingFacts, POWER_SHELL_COMMON_HELP, POWER_SHELL_COMMON_HELP_TITLE, powerShellCommonParameterHref, powerShellCommonParameterLabel } from '../../lib/api-sections' import ApiDoc from './ApiDoc.astro' import ApiType from './ApiType.astro' diff --git a/site/src/components/api/ApiEntry.astro b/site/src/components/api/ApiEntry.astro index 9ca0a8037..3eced7838 100644 --- a/site/src/components/api/ApiEntry.astro +++ b/site/src/components/api/ApiEntry.astro @@ -1,5 +1,5 @@ --- -import { boundLabel, parameterId, qualifiedNameOf, typeParameterId, typeParameterList, type ApiSymbol, type SymbolIndex, type SymbolKind } from '@libtmux/api-model' +import { boundLabel, parameterId, qualifiedNameOf, typeParameterId, typeParameterList, type ApiSymbol, type SymbolIndex, type SymbolKind } from '@libtmux/api-model/reference' import { apiInventoryAttributes } from '../../lib/inventory-targets' import { API_MODELS, mentionsOf, referenceAlternatives } from '../../lib/api-models' import { productApiIndex } from '../../lib/product-api' diff --git a/site/src/components/api/ApiReference.astro b/site/src/components/api/ApiReference.astro index 434c53e35..164f9cbe8 100644 --- a/site/src/components/api/ApiReference.astro +++ b/site/src/components/api/ApiReference.astro @@ -1,6 +1,6 @@ --- import type { ApiModel, ApiSymbol, SourceApiModel, SymbolIndex } from '@libtmux/api-model' -import { aliasMembersTarget, membersOf, pageMembersOf, memberTier, docSummaryText, memberSignals, parameterId, qualifiedNameOf, moduleOf, modulesIn, sourceUrl as apiSourceUrl, symbolsForProduct } from '@libtmux/api-model' +import { aliasMembersTarget, membersOf, pageMembersOf, memberTier, docSummaryText, memberSignals, parameterId, qualifiedNameOf, moduleOf, modulesIn, sourceUrl as apiSourceUrl, symbolsForProduct } from '@libtmux/api-model/reference' import mentionsData from '../../data/mentions.json' import ApiEntry from '../../components/api/ApiEntry.astro' import ApiTmuxSections from './ApiTmuxSections.astro' diff --git a/site/src/components/api/ApiRelationships.astro b/site/src/components/api/ApiRelationships.astro index 3d26534a6..6b4dffac3 100644 --- a/site/src/components/api/ApiRelationships.astro +++ b/site/src/components/api/ApiRelationships.astro @@ -1,6 +1,6 @@ --- import type { ApiModelBase, ApiSymbol } from '@libtmux/api-model' -import { qualifiedNameOf } from '@libtmux/api-model' +import { qualifiedNameOf } from '@libtmux/api-model/reference' import type { ApiRelationshipPath, ApiRelationshipSection } from '../../lib/api-relationships' import { apiCallSource } from '../../lib/api-relationships' import ApiBadge from './ApiBadge.astro' diff --git a/site/src/components/api/ApiSignatureParameters.astro b/site/src/components/api/ApiSignatureParameters.astro index 66f6481cb..b24020c73 100644 --- a/site/src/components/api/ApiSignatureParameters.astro +++ b/site/src/components/api/ApiSignatureParameters.astro @@ -1,5 +1,5 @@ --- -import { parameterId, type ApiSymbol, type Signature, type SymbolIndex } from '@libtmux/api-model' +import { parameterId, type ApiSymbol, type Signature, type SymbolIndex } from '@libtmux/api-model/reference' import { signatureMultiline } from '../../lib/api-sections' import type { PythonLayout } from '../../lib/python-code-layout' import ApiType from './ApiType.astro' diff --git a/site/src/components/api/ApiType.astro b/site/src/components/api/ApiType.astro index c4157caf6..159956c51 100644 --- a/site/src/components/api/ApiType.astro +++ b/site/src/components/api/ApiType.astro @@ -1,6 +1,6 @@ --- import type { ApiSymbol, Signature, SymbolIndex } from '@libtmux/api-model' -import { qualifiedNameOf } from '@libtmux/api-model' +import { qualifiedNameOf } from '@libtmux/api-model/reference' import { signatureSpans, typeLayout, type SignatureSpan, type SpanLayout } from '../../lib/code-layout' import SymbolName from './SymbolName.astro' import ApiKeyword from './ApiKeyword.astro' diff --git a/site/src/components/api/ProductApiIndex.astro b/site/src/components/api/ProductApiIndex.astro index 413904416..92993320a 100644 --- a/site/src/components/api/ProductApiIndex.astro +++ b/site/src/components/api/ProductApiIndex.astro @@ -1,5 +1,5 @@ --- -import { qualifiedNameOf, docSummaryText } from '@libtmux/api-model' +import { qualifiedNameOf, docSummaryText } from '@libtmux/api-model/reference' import { API_MODELS } from '../../lib/api-models' import { productApiHref, productApiRoots } from '../../lib/product-api' import { productApiSections } from '../../lib/product-api-sections' diff --git a/site/src/components/api/ProductApiPage.astro b/site/src/components/api/ProductApiPage.astro index 36efa30ac..72063760d 100644 --- a/site/src/components/api/ProductApiPage.astro +++ b/site/src/components/api/ProductApiPage.astro @@ -1,5 +1,5 @@ --- -import { qualifiedNameOf, docSummaryText, memberSignals, parameterId, sourceUrl, symbolsForProduct, type ApiModel, type ApiSymbol } from '@libtmux/api-model' +import { qualifiedNameOf, docSummaryText, memberSignals, parameterId, sourceUrl, symbolsForProduct, type ApiModel, type ApiSymbol } from '@libtmux/api-model/reference' import DocsLayout from '../../layouts/DocsLayout.astro' import ApiEntry from './ApiEntry.astro' import ApiMemberList from './ApiMemberList.astro' diff --git a/site/src/components/mcp/ProtocolReference.astro b/site/src/components/mcp/ProtocolReference.astro index a5e68f4bf..b06d657b7 100644 --- a/site/src/components/mcp/ProtocolReference.astro +++ b/site/src/components/mcp/ProtocolReference.astro @@ -1,6 +1,6 @@ --- import { Code } from 'astro-expressive-code/components' -import { parsePythonDoc } from '@libtmux/api-model' +import { parsePythonDoc } from '@libtmux/api-model/reference' import DocsLayout from '../../layouts/DocsLayout.astro' import ApiBadge from '../api/ApiBadge.astro' import { apiGlossaryHref } from '../../lib/api-glossary' diff --git a/site/src/content/docs/ports/perl/core/index.md b/site/src/content/docs/ports/perl/core/index.md new file mode 100644 index 000000000..d87e992a1 --- /dev/null +++ b/site/src/content/docs/ports/perl/core/index.md @@ -0,0 +1,23 @@ +--- +port: perl +route: core +title: tmux client library for Perl +description: "tmux client library for Perl. Control tmux, connect to and create servers, navigate sessions, windows, and panes, send keys, capture pane contents" +cards: + - label: Installation and guides + href: ../guides/ + body: Install the native distributions and work with captured tmux state. + - label: Filtering example + href: ../guides/filtering/ + body: Run a complete snapshot, criteria, callback, and native-array workflow. + - label: API reference + href: ../reference/ + body: Native package signatures and interlinked POD for core and optional async. +--- + +The core uses stable Perl 5.44 features and standard-library runtime modules. +The optional [LibTmux-Async distribution](../reference/) adds Future and IO::Async through a +caller-owned loop. Linux x86_64 LP64 is qualified; other platforms and ABIs +remain unsupported. + +The distributions are available from source and have no CPAN release. diff --git a/site/src/content/docs/ports/perl/workspace/index.md b/site/src/content/docs/ports/perl/workspace/index.md new file mode 100644 index 000000000..bca537b2e --- /dev/null +++ b/site/src/content/docs/ports/perl/workspace/index.md @@ -0,0 +1,21 @@ +--- +title: tmux workspace manager, +subtitle: forged in Perl. +shortTitle: Perl-based tmux workspace manager +description: Validate, plan, and load versioned JSON workspaces with LibTmux-Workspace. +port: perl +product: workspace +sidebar: + label: Overview + order: 0 +--- + +[LibTmux-Workspace](./reference/) is a separate native Perl distribution using public core +APIs. Its `libtmux-workspace` command validates, plans, and loads the +[libtmux.workspace/v1 JSON format](./source-guide/). Planning performs no tmux I/O. Loading +creates sessions, windows, and panes, with explicit conflict and repeat policies. + +Install core first, then workspace from the same source checkout. These +packages are not published to CPAN. The [workspace guide](./source-guide/) +contains the configuration contract and installed CLI commands. The +[API reference](./reference/) documents the public loader and report errors. diff --git a/site/src/data/api-destination-evidence.json b/site/src/data/api-destination-evidence.json index 72ed2ad5a..b952805b7 100644 --- a/site/src/data/api-destination-evidence.json +++ b/site/src/data/api-destination-evidence.json @@ -1,6 +1,6 @@ { "schema": 2, - "checkedAt": "2026-10-31", + "checkedAt": "2026-11-07", "inventories": [ {"name":"python","source":"https://docs.python.org/3/objects.inv","kind":"objects.inv","entries":16493,"digest":"9b186d22c55bd3056145d7009198a34a0274d7e4","ok":true,"missing":0,"checkedAt":"2026-10-25"}, {"name":"julia","source":"https://docs.julialang.org/en/v1/objects.inv","kind":"objects.inv","entries":2545,"digest":"94ff52276c38e7feea3d68234092a72496935b01","ok":true,"missing":0,"checkedAt":"2026-10-25"}, @@ -710,7 +710,11 @@ {"url":"https://luals.github.io/wiki/annotations/#class","host":"luals.github.io","status":200,"via":"html","title":"Lua Language Server | Wiki","heading":"@class","ok":true,"fragment":"found","terminal":[{"key":"authored:Lua class annotations","symbol":"Lua class annotations","at":"review"},{"key":"authored:Lua class inheritance","symbol":"Lua class inheritance","at":"review"}],"checkedAt":"2026-10-25","names":["glossary lua class","glossary lua inherited"],"sources":["authored"]}, {"url":"https://luals.github.io/wiki/annotations/#documenting-types","host":"luals.github.io","status":200,"via":"html","title":"Lua Language Server | Wiki","ok":true,"fragment":"found","terminal":[{"symbol":"any","at":"section","reason":"the wiki lists the recognized types in one section"}],"checkedAt":"2026-10-25","names":["lua:any"],"sources":["builtin","prose"]}, {"url":"https://luals.github.io/wiki/annotations/#overload","host":"luals.github.io","status":200,"via":"html","title":"Lua Language Server | Wiki","heading":"@overload","ok":true,"fragment":"found","terminal":[{"key":"authored:Lua overload annotations","symbol":"Lua overload annotations","at":"review"}],"checkedAt":"2026-10-25","names":["glossary lua overload"],"sources":["authored"]}, + {"url":"https://metacpan.org/pod/Future","host":"metacpan.org","status":200,"via":"html","title":"Future - represent an operation awaiting completion - metacpan.org","identity":{"via":"pod","declared":"module","kind":"module","path":["Future"]},"heading":"Future","ok":true,"terminal":[{"key":"doc-link:Future","symbol":"Future","at":"identity"}],"checkedAt":"2026-11-07","names":["perl:Future"],"sources":["doc-link"]}, + {"url":"https://metacpan.org/pod/IO::Async","host":"metacpan.org","status":200,"via":"html","title":"IO::Async - Asynchronous event-driven programming - metacpan.org","identity":{"via":"pod","declared":"module","kind":"module","path":["IO","Async"]},"heading":"IO.Async","ok":true,"terminal":[{"key":"doc-link:IO::Async","symbol":"IO::Async","at":"identity"}],"checkedAt":"2026-11-07","names":["perl:IO::Async"],"sources":["doc-link"]}, + {"url":"https://metacpan.org/pod/IO::Async::Loop","host":"metacpan.org","status":200,"via":"html","title":"IO::Async::Loop - core loop of the IO::Async framework - metacpan.org","identity":{"via":"pod","declared":"module","kind":"module","path":["IO","Async","Loop"]},"heading":"IO.Async.Loop","ok":true,"terminal":[{"key":"doc-link:IO::Async::Loop","symbol":"IO::Async::Loop","at":"identity"}],"checkedAt":"2026-11-07","names":["perl:IO::Async::Loop"],"sources":["doc-link"]}, {"url":"https://modelcontextprotocol.io/specification/2025-11-25/schema#toolannotations","host":"modelcontextprotocol.io","status":200,"via":"html","title":"Schema Reference - Model Context Protocol","heading":"ToolAnnotations","ok":true,"fragment":"found","terminal":[{"key":"authored:MCP ToolAnnotations","symbol":"MCP ToolAnnotations","at":"review"}],"checkedAt":"2026-10-25","names":["site/src/lib/api-glossary.ts"],"sources":["authored"]}, + {"url":"https://perldoc.perl.org/5.44.0/JSON::PP","host":"perldoc.perl.org","status":200,"via":"html","title":"JSON::PP - JSON::XS compatible pure-Perl module. - Perldoc Browser","identity":{"via":"pod","declared":"module","kind":"module","path":["JSON","PP"]},"heading":"JSON.PP","ok":true,"terminal":[{"key":"doc-link:JSON::PP","symbol":"JSON::PP","at":"identity"}],"checkedAt":"2026-11-07","names":["perl:JSON::PP"],"sources":["doc-link"]}, {"url":"https://pkg.go.dev/builtin#any","host":"pkg.go.dev","status":200,"via":"html","title":"builtin package - builtin - Go Packages","identity":{"via":"godoc","declared":"type","kind":"type","path":["builtin","any"]},"fragment":"found","ok":true,"terminal":[{"key":"go:any","symbol":"any","at":"identity"}],"checkedAt":"2026-10-25","names":["go:any"],"sources":["builtin","type"]}, {"url":"https://pkg.go.dev/builtin#bool","host":"pkg.go.dev","status":200,"via":"html","title":"builtin package - builtin - Go Packages","identity":{"via":"godoc","declared":"type","kind":"type","path":["builtin","bool"]},"fragment":"found","ok":true,"terminal":[{"key":"go:bool","symbol":"bool","at":"identity"}],"checkedAt":"2026-10-25","names":["go:bool"],"sources":["builtin","doc","type"]}, {"url":"https://pkg.go.dev/builtin#byte","host":"pkg.go.dev","status":200,"via":"html","title":"builtin package - builtin - Go Packages","identity":{"via":"godoc","declared":"type","kind":"type","path":["builtin","byte"]},"fragment":"found","ok":true,"terminal":[{"key":"go:byte","symbol":"byte","at":"identity"}],"checkedAt":"2026-10-25","names":["go:byte"],"sources":["builtin","type"]}, diff --git a/site/src/data/api/perl.json b/site/src/data/api/perl.json new file mode 100644 index 000000000..96cc21f74 --- /dev/null +++ b/site/src/data/api/perl.json @@ -0,0 +1 @@ +{"port":"perl","repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf","sources":[{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","package":"LibTmux","product":"core","repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf","version":"0.001_001"},{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","package":"LibTmux-Async","product":"core","repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf","version":"0.001_001"},{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","package":"LibTmux-Workspace","product":"workspace","repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf","version":"0.001_001"}],"extractor":"Perl PPI 1.291 + Pod::Simple native POD v1","nativeProvenance":{"exporter":{"file":"scripts/export-api.pl","perl":"v5.44.0","ppi":"1.291","repository":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf","sha256":"fb85c9e8bad4a7bc00f416ad2f3a5ad66d3043a3acbb47b30fb05cc8fab1ecfd","working_tree":false},"files":[{"path":"packages/core/LICENSE","sha256":"e32e2d62046374e7f08a57882699e3f37920edf6b770f817e5b67eb625e2eb4f"},{"path":"packages/core/Makefile.PL","sha256":"b1676ac18d88f57e08ed6ddf463af66c5752bd41ce0e8dd8074329a3e38f60af"},{"path":"packages/core/README.md","sha256":"c5b6e8006e0600bf8b5cfba2ebae2657cabb6cbdc5fe108352ef0d27e60ab830"},{"path":"packages/core/cpanfile","sha256":"c3872a5a5b6b7f367534376cd4db51f7ebf4a1ee31a4560c0de2661c9b25bdf7"},{"path":"packages/core/lib/LibTmux.pm","sha256":"f4716e9b7ba03c66fa57c084ac0803c68968ccacb37ff54a15023e34e854080c"},{"path":"packages/core/lib/LibTmux/Client.pm","sha256":"1d6a7fe38802d134215f476727e014cceb7f189d608a45e907aa74a9b33377a3"},{"path":"packages/core/lib/LibTmux/ClientSelection.pm","sha256":"24c200afefcb28a5df984b99db8df4253986176b005daf175ecd3f45ebc50aab"},{"path":"packages/core/lib/LibTmux/Codec.pm","sha256":"4d285f1b15d53791e5de537fc1a9ff4ef68d1e3cb335cc2171bce21f8fe05114"},{"path":"packages/core/lib/LibTmux/CommandResult.pm","sha256":"c05fee72a809d924d96908eeb5c9d4c328b088d5e4f9692f292f9c96b13fdbd9"},{"path":"packages/core/lib/LibTmux/Entity.pm","sha256":"46fbe507850d5880f59d78a732270e2554d5e4fe112d8a8013e60a9fca0d5c20"},{"path":"packages/core/lib/LibTmux/Filter.pm","sha256":"fa3b65a22515a6086d06f044e06eeb454575b926e41216419f445d084c8cd8bc"},{"path":"packages/core/lib/LibTmux/Operation.pm","sha256":"dc63406ae06d858fad89347a146cb7ba8496e6db9ee5eaf1ab278e2a67d250e3"},{"path":"packages/core/lib/LibTmux/Pane.pm","sha256":"1d34d763df3256c8645b91395788d0e863e1bff80115a473494b23c4525f3040"},{"path":"packages/core/lib/LibTmux/PaneSelection.pm","sha256":"6edb85943a642e56afcc5185b905c4fc82fcb9c3ca35d013aa61627421354fc5"},{"path":"packages/core/lib/LibTmux/Platform/Linux.pm","sha256":"7517a796378bd8eaca0a2429985af4950f89ba393417810426c2e72113480979"},{"path":"packages/core/lib/LibTmux/ProcessJob.pm","sha256":"81cc23db7ec08f539de0566631ea96ea0a72aa38c853f382aa082bbce602287d"},{"path":"packages/core/lib/LibTmux/QueryPlan.pm","sha256":"31c45ea79f19340be9371c4edefcbdaa48e6ebb70ac09f4b9005e8832d7147ff"},{"path":"packages/core/lib/LibTmux/Schema.pm","sha256":"69290dbf72abe7cb27d9364b519f261281088d59abd4c17af33026adf4d7a52f"},{"path":"packages/core/lib/LibTmux/Selection.pm","sha256":"12565d289dcb00e13852d297cbd843a65a9bab43c0e6cab6392bc6fdf8749c99"},{"path":"packages/core/lib/LibTmux/Selection/Iterator.pm","sha256":"755aaf2aa31e3302422d00573bd4ce4d26be8017f1d008b12be1f64708496d40"},{"path":"packages/core/lib/LibTmux/Server.pm","sha256":"075171cdab7c8654f7f16f275fc1cd6061bee611a0308f3e60966b72ba63cf98"},{"path":"packages/core/lib/LibTmux/Session.pm","sha256":"937f4399513d814108380b75beb1c8824960593354f3955559439e2bc999da83"},{"path":"packages/core/lib/LibTmux/SessionSelection.pm","sha256":"8ba23cdcf527ceb555ce392857c2b43b86b1b55ab4e881e5dc733ced99e95f4c"},{"path":"packages/core/lib/LibTmux/Snapshot.pm","sha256":"d25f65b94405c1d9cb3ff3f0e268de567d79d4aca178efa66c14db8bd040df5d"},{"path":"packages/core/lib/LibTmux/Transport.pm","sha256":"cc77f9006031439bfd5605422002e1021a5efefa453e1839a54326066714c5fd"},{"path":"packages/core/lib/LibTmux/Window.pm","sha256":"df01e902cc513dee0e7458c2499078ca9141446066a822525a2e45864942e06e"},{"path":"packages/core/lib/LibTmux/WindowLink.pm","sha256":"30c8937a5806bb2996af3b21c3a6936a383a3e34ead6d591748a077b7b6adebf"},{"path":"packages/core/lib/LibTmux/WindowLinkSelection.pm","sha256":"8301d518b97d620f76c7d1c7927c14809962a48b9ae5027768ea2163395550f1"},{"path":"packages/core/lib/LibTmux/WindowSelection.pm","sha256":"8b7956f6360344d3c3f8c7b1759f2e53e0acbbc98e81d2f3f864c339b8fcf8c2"},{"path":"packages/core/lib/LibTmux/X.pm","sha256":"cd2f10de0b7b14e1e53e1fdce92e8fbd949fbc8504d66a24794a094f60c0345f"},{"path":"packages/core/lib/LibTmux/schema.json","sha256":"8510922e6c95d9b8d880a9db1769eaca60a6a2b080a1b2d2bfbe99756c0125f7"},{"path":"packages/async/LICENSE","sha256":"e32e2d62046374e7f08a57882699e3f37920edf6b770f817e5b67eb625e2eb4f"},{"path":"packages/async/Makefile.PL","sha256":"d286c34dea28a19e5dee6676994572948484a14dcced38ac3c2b5ad836874d74"},{"path":"packages/async/README.md","sha256":"868cdfcaffd39a62b4edaf141fc20d2a62afcfc6eedae03058bda87d22959023"},{"path":"packages/async/cpanfile","sha256":"cf1db6b9b0dbf935acb2ff1377c3413e102af4cde98f35c65cb7fa3723792c64"},{"path":"packages/async/lib/LibTmux/Async.pm","sha256":"f223b46ea089d857539d28fa016197e3ba78e381f5be7a4efb49949e08c7ec68"},{"path":"packages/async/lib/LibTmux/Async/Server.pm","sha256":"081236c4fc435ecef45df32c1d53cb5d11c355e1adb4c633f4c8530640524009"},{"path":"packages/async/lib/LibTmux/Async/Transport.pm","sha256":"daef8612d81ed577bf9f09ea56b06dbb2e19427735e8e690a570f2bd03f93303"},{"path":"packages/async/lib/LibTmux/Async/X.pm","sha256":"c1f342b52f45de5eee2c1970e806049a373f0f88d1c579ae4c157ed40756d272"},{"path":"packages/workspace/LICENSE","sha256":"e32e2d62046374e7f08a57882699e3f37920edf6b770f817e5b67eb625e2eb4f"},{"path":"packages/workspace/Makefile.PL","sha256":"e0cd4934a909b4af792040dbaa9f29f430b0873cf1dd4be5d1079df03b177515"},{"path":"packages/workspace/README.md","sha256":"66075a42cc8e6bc57c70909d0fc5c1c1344a4b80c42a14dced9730a99439d9f8"},{"path":"packages/workspace/cpanfile","sha256":"1acf55e302b84a6050525354e8887ca39ae45c8b0e908ff9fc3ffa23cb7ad246"},{"path":"packages/workspace/lib/LibTmux/Workspace.pm","sha256":"78184b497b0f5d1d0545d392a90cb61d15b9be774967a5b8ed8f39017dd71251"},{"path":"packages/workspace/lib/LibTmux/Workspace/X.pm","sha256":"59e2fbb087478b744945ad9fc2dd3042c5c093dfac54652ec1d31744d7efcc93"},{"path":"examples/quickstart.pl","sha256":"ba9f650b81972f6b11556c4babd22b19d868335d9701980069e5d37748ce3cf2"},{"path":"examples/selection.pl","sha256":"164d1112c25f917ddd73f1e2aae6476154bb377bc4e02e4cd3532206b2222305"},{"path":"examples/workspace.pl","sha256":"6f0b49432880a956960fcc19c02fe1ed0c7eeb4f57f2131e17162c4ecb65fbf3"},{"path":"examples/async.pl","sha256":"f257901f48ba4caa6893ff6a8fb163a535c87b0c2effa74fdb5729285091d327"},{"path":"examples/await.pl","sha256":"31cd644ebed29a8530b134dd08083a2d5761efcd5035bcdd52deb14449156961"}]},"symbols":[{"apiScope":"exported","doc":{"body":"\n## DESCRIPTION\n\nUse :obj:`LibTmux::Server ` for acquisition and commands. Captured entities and :obj:`LibTmux::Selection ` queries perform no tmux I/O.\n\n","summary":"Explicit tmux commands and captured graph queries"},"id":"LibTmux","kind":"module","modifiers":[],"name":"LibTmux","package":"LibTmux","product":"core","publicId":"LibTmux","qualifiedName":"LibTmux","signatures":[{"params":[],"raw":"package LibTmux;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux"},{"apiScope":"exported","doc":{"body":"\n## DESCRIPTION\n\nThe async distribution depends on :obj:`LibTmux `, [IO::Async](https://metacpan.org/pod/IO::Async), and [Future](https://metacpan.org/pod/Future). Use :obj:`LibTmux::Async::Server ` or :obj:`LibTmux::Async::Transport ` with an explicitly supplied loop. Core snapshot filtering remains local and synchronous. Async dependencies are not required by the core or workspace distributions.\n\n","summary":"Optional Future-based libtmux execution"},"id":"LibTmux::Async","kind":"module","modifiers":[],"name":"Async","package":"LibTmux-Async","product":"core","publicId":"LibTmux::Async","qualifiedName":"LibTmux::Async","signatures":[{"params":[],"raw":"package LibTmux::Async;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async"},{"apiScope":"exported","doc":{"body":"\n## SYNOPSIS\n\n\n```perl\n use v5.44;\n use IO::Async::Loop;\n use LibTmux::Async::Server;\n my $loop = IO::Async::Loop->new;\n my $server = LibTmux::Async::Server->new(loop => $loop, socket_name => 'owned');\n my $capture = $server->snapshot;\n $loop->await($capture);\n my $panes = $capture->get->panes->where({ active => true });\n $loop->await($server->close);\n```\n\n","summary":"Optional Future facade over the core protocol","examples":[{"lang":"perl","code":"use v5.44;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse IO::Async::Loop;\nuse Future::AsyncAwait;\nuse LibTmux::Async::Server;\nuse LibTmuxFixture;\nasync sub capture_count ($server) {\n my $snapshot = await $server->snapshot;\n my $count = $snapshot->panes->count;\n await $server->close;\n return $count;\n}\nLibTmuxFixture->run(\n sub ($sync, $root) {\n $sync->new_session(\n name => 'await-example',\n command => ['/bin/sleep', '120']\n );\n my $loop = IO::Async::Loop->new;\n my $server = LibTmux::Async::Server->new(\n loop => $loop,\n socket_path => \"$root/s\",\n executable => $ENV{LIBTMUX_TEST_TMUX} // 'tmux'\n );\n my $work = capture_count($server);\n $loop->await($work);\n die 'await result differs' unless $work->get == 1;\n say 'optional caller await syntax: ok';\n }\n);\n","intro":"Complete installed-package program with an owned tmux fixture and result/cleanup assertions.","sourceUrl":"https://github.com/libtmux/libtmux-perl/blob/36b978c5eb6aa33873229046037e7d26136ca2cf/examples/await.pl"}]},"id":"LibTmux::Async::Server","kind":"class","modifiers":[],"name":"Server","package":"LibTmux-Async","product":"core","publicId":"LibTmux::Async::Server","qualifiedName":"LibTmux::Async::Server","signatures":[{"params":[],"raw":"package LibTmux::Async::Server;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"attach_argv\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::attach_argv","kind":"method","modifiers":["async"],"name":"attach_argv","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::attach_argv","qualifiedName":"LibTmux::Async::Server::attach_argv","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub attach_argv($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":88,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-attach_argv"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"batch\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::batch","kind":"method","modifiers":["async"],"name":"batch","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::batch","qualifiedName":"LibTmux::Async::Server::batch","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"requests"}],"raw":"sub batch($self, $requests)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":62,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-batch"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"capture_pane\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::capture_pane","kind":"method","modifiers":["async"],"name":"capture_pane","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::capture_pane","qualifiedName":"LibTmux::Async::Server::capture_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":29,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub capture_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":82,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-capture_pane"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"clients\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::clients","kind":"method","modifiers":["async"],"name":"clients","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::clients","qualifiedName":"LibTmux::Async::Server::clients","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":19}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub clients($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":87,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-clients"},{"apiScope":"exported","doc":{"summary":"Cancel active operations, suppress subsequent command continuations, reject new operations, and return a fresh cleanup observer [Future](https://metacpan.org/pod/Future). Only successful `is_done` completion proves owned processes and pipes finished. Cancellation of an observer does not cancel cleanup. The caller must drive its borrowed loop through shutdown. No tmux server is destroyed by closing this facade."},"id":"LibTmux::Async::Server::close","kind":"method","modifiers":["async"],"name":"close","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::close","qualifiedName":"LibTmux::Async::Server::close","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub close($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":55,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-close"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"cmd\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::cmd","kind":"method","modifiers":["async"],"name":"cmd","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::cmd","qualifiedName":"LibTmux::Async::Server::cmd","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":20,"kind":"parameter","parameter":0,"start":15}],"params":[{"name":"argv","variadic":"positional"}],"raw":"sub cmd($self, @argv)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":60,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-cmd"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"delete_buffer\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::delete_buffer","kind":"method","modifiers":["async"],"name":"delete_buffer","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::delete_buffer","qualifiedName":"LibTmux::Async::Server::delete_buffer","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub delete_buffer($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":103,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-delete_buffer"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"detach_client\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::detach_client","kind":"method","modifiers":["async"],"name":"detach_client","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::detach_client","qualifiedName":"LibTmux::Async::Server::detach_client","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub detach_client($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":89,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-detach_client"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"execute\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::execute","kind":"method","modifiers":["async"],"name":"execute","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::execute","qualifiedName":"LibTmux::Async::Server::execute","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":19}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub execute($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":63,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-execute"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"explain_panes\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::explain_panes","kind":"method","modifiers":["async"],"name":"explain_panes","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::explain_panes","qualifiedName":"LibTmux::Async::Server::explain_panes","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub explain_panes($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":69,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-explain_panes"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"get_environment\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::get_environment","kind":"method","modifiers":["async"],"name":"get_environment","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::get_environment","qualifiedName":"LibTmux::Async::Server::get_environment","signatures":[{"methodKind":"call","nativeSyntax":[{"end":19,"kind":"name","start":4},{"end":32,"kind":"parameter","parameter":0,"start":27}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub get_environment($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":96,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-get_environment"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"get_option\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::get_option","kind":"method","modifiers":["async"],"name":"get_option","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::get_option","qualifiedName":"LibTmux::Async::Server::get_option","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub get_option($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":91,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-get_option"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"kill_pane\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::kill_pane","kind":"method","modifiers":["async"],"name":"kill_pane","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::kill_pane","qualifiedName":"LibTmux::Async::Server::kill_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":21}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub kill_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":83,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-kill_pane"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"kill_server\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::kill_server","kind":"method","modifiers":["async"],"name":"kill_server","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::kill_server","qualifiedName":"LibTmux::Async::Server::kill_server","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub kill_server($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":86,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-kill_server"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"kill_session\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::kill_session","kind":"method","modifiers":["async"],"name":"kill_session","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::kill_session","qualifiedName":"LibTmux::Async::Server::kill_session","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":29,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub kill_session($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":85,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-kill_session"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"kill_window\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::kill_window","kind":"method","modifiers":["async"],"name":"kill_window","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::kill_window","qualifiedName":"LibTmux::Async::Server::kill_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub kill_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":84,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-kill_window"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"link_window\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::link_window","kind":"method","modifiers":["async"],"name":"link_window","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::link_window","qualifiedName":"LibTmux::Async::Server::link_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub link_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":72,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-link_window"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"listings\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::listings","kind":"method","modifiers":["async"],"name":"listings","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::listings","qualifiedName":"LibTmux::Async::Server::listings","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":20}],"params":[{"name":"kind"}],"raw":"sub listings($self, $kind)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":61,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-listings"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"move_window\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::move_window","kind":"method","modifiers":["async"],"name":"move_window","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::move_window","qualifiedName":"LibTmux::Async::Server::move_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub move_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":74,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-move_window"},{"apiScope":"exported","doc":{"summary":"`new(loop => $loop, %connection_options)` constructs without I/O. Borrow an [IO::Async::Loop](https://metacpan.org/pod/IO::Async::Loop); connection options belong to :obj:`\"new\" in LibTmux::Server `. `max_concurrent` and `max_queue` configure the owned :obj:`LibTmux::Async::Transport `. No event loop is run implicitly."},"id":"LibTmux::Async::Server::new","kind":"method","modifiers":[],"name":"new","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::new","qualifiedName":"LibTmux::Async::Server::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":21,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub new($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-new"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"new_session\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::new_session","kind":"method","modifiers":["async"],"name":"new_session","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::new_session","qualifiedName":"LibTmux::Async::Server::new_session","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub new_session($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":64,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-new_session"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"new_window\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::new_window","kind":"method","modifiers":["async"],"name":"new_window","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::new_window","qualifiedName":"LibTmux::Async::Server::new_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub new_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":65,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-new_window"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"query_panes\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::query_panes","kind":"method","modifiers":["async"],"name":"query_panes","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::query_panes","qualifiedName":"LibTmux::Async::Server::query_panes","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub query_panes($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":68,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-query_panes"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"rename_session\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::rename_session","kind":"method","modifiers":["async"],"name":"rename_session","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::rename_session","qualifiedName":"LibTmux::Async::Server::rename_session","signatures":[{"methodKind":"call","nativeSyntax":[{"end":18,"kind":"name","start":4},{"end":31,"kind":"parameter","parameter":0,"start":26}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub rename_session($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":70,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-rename_session"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"rename_window\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::rename_window","kind":"method","modifiers":["async"],"name":"rename_window","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::rename_window","qualifiedName":"LibTmux::Async::Server::rename_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub rename_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":71,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-rename_window"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"resize_pane\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::resize_pane","kind":"method","modifiers":["async"],"name":"resize_pane","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::resize_pane","qualifiedName":"LibTmux::Async::Server::resize_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub resize_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":78,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-resize_pane"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"select_layout\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::select_layout","kind":"method","modifiers":["async"],"name":"select_layout","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::select_layout","qualifiedName":"LibTmux::Async::Server::select_layout","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub select_layout($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":77,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-select_layout"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"select_pane\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::select_pane","kind":"method","modifiers":["async"],"name":"select_pane","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::select_pane","qualifiedName":"LibTmux::Async::Server::select_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub select_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":76,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-select_pane"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"select_window\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::select_window","kind":"method","modifiers":["async"],"name":"select_window","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::select_window","qualifiedName":"LibTmux::Async::Server::select_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub select_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":75,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-select_window"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"send_keys\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::send_keys","kind":"method","modifiers":["async"],"name":"send_keys","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::send_keys","qualifiedName":"LibTmux::Async::Server::send_keys","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":21}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub send_keys($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":80,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-send_keys"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"send_text\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::send_text","kind":"method","modifiers":["async"],"name":"send_text","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::send_text","qualifiedName":"LibTmux::Async::Server::send_text","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":21}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub send_text($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":81,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-send_text"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"set_buffer\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::set_buffer","kind":"method","modifiers":["async"],"name":"set_buffer","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::set_buffer","qualifiedName":"LibTmux::Async::Server::set_buffer","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_buffer($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":101,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-set_buffer"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"set_environment\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::set_environment","kind":"method","modifiers":["async"],"name":"set_environment","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::set_environment","qualifiedName":"LibTmux::Async::Server::set_environment","signatures":[{"methodKind":"call","nativeSyntax":[{"end":19,"kind":"name","start":4},{"end":32,"kind":"parameter","parameter":0,"start":27}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_environment($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":95,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-set_environment"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"set_hook\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::set_hook","kind":"method","modifiers":["async"],"name":"set_hook","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::set_hook","qualifiedName":"LibTmux::Async::Server::set_hook","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":20}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_hook($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":93,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-set_hook"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"set_option\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::set_option","kind":"method","modifiers":["async"],"name":"set_option","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::set_option","qualifiedName":"LibTmux::Async::Server::set_option","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_option($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":90,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-set_option"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"set_title\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::set_title","kind":"method","modifiers":["async"],"name":"set_title","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::set_title","qualifiedName":"LibTmux::Async::Server::set_title","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":21}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_title($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":79,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-set_title"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"show_buffer\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::show_buffer","kind":"method","modifiers":["async"],"name":"show_buffer","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::show_buffer","qualifiedName":"LibTmux::Async::Server::show_buffer","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub show_buffer($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":102,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-show_buffer"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"show_hooks\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::show_hooks","kind":"method","modifiers":["async"],"name":"show_hooks","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::show_hooks","qualifiedName":"LibTmux::Async::Server::show_hooks","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub show_hooks($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":94,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-show_hooks"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"snapshot\" in LibTmux::Server ` for arguments, returned value, and completion.","examples":[{"lang":"perl","code":"use v5.44;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse IO::Async::Loop;\nuse LibTmux::Async::Server;\nuse LibTmuxFixture;\nLibTmuxFixture->run(\n sub ($sync, $root) {\n $sync->new_session(\n name => 'async-example',\n command => ['/bin/sleep', '120']\n );\n my $loop = IO::Async::Loop->new;\n my $server = LibTmux::Async::Server->new(\n loop => $loop,\n socket_path => \"$root/s\",\n executable => $ENV{LIBTMUX_TEST_TMUX} // 'tmux',\n max_concurrent => 2\n );\n my $snapshot = $server->snapshot;\n $loop->await($snapshot);\n die 'async snapshot missing pane'\n unless $snapshot->get->panes->count == 1;\n my $closed = $server->close;\n $loop->await($closed);\n die 'cleanup failed' unless $closed->is_done;\n say 'async capture and cleanup: ok';\n }\n);\n","intro":"Complete installed-package program with an owned tmux fixture and result/cleanup assertions.","sourceUrl":"https://github.com/libtmux/libtmux-perl/blob/36b978c5eb6aa33873229046037e7d26136ca2cf/examples/async.pl"}]},"id":"LibTmux::Async::Server::snapshot","kind":"method","modifiers":["async"],"name":"snapshot","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::snapshot","qualifiedName":"LibTmux::Async::Server::snapshot","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":20}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub snapshot($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":67,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-snapshot"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"split_pane\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::split_pane","kind":"method","modifiers":["async"],"name":"split_pane","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::split_pane","qualifiedName":"LibTmux::Async::Server::split_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub split_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":66,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-split_pane"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"unlink_window\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::unlink_window","kind":"method","modifiers":["async"],"name":"unlink_window","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::unlink_window","qualifiedName":"LibTmux::Async::Server::unlink_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub unlink_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":73,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-unlink_window"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"unset_environment\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::unset_environment","kind":"method","modifiers":["async"],"name":"unset_environment","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::unset_environment","qualifiedName":"LibTmux::Async::Server::unset_environment","signatures":[{"methodKind":"call","nativeSyntax":[{"end":21,"kind":"name","start":4},{"end":34,"kind":"parameter","parameter":0,"start":29}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub unset_environment($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":98,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-unset_environment"},{"apiScope":"exported","doc":{"summary":"See :obj:`\"unset_option\" in LibTmux::Server ` for arguments, returned value, and completion."},"id":"LibTmux::Async::Server::unset_option","kind":"method","modifiers":["async"],"name":"unset_option","package":"LibTmux-Async","parent":"LibTmux::Async::Server","product":"core","publicId":"LibTmux::Async::Server::unset_option","qualifiedName":"LibTmux::Async::Server::unset_option","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":29,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub unset_option($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Server.pm","line":92,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-server-unset_option"},{"apiScope":"exported","doc":{"body":"","summary":"Bounded asynchronous process execution"},"id":"LibTmux::Async::Transport","kind":"class","modifiers":[],"name":"Transport","package":"LibTmux-Async","product":"core","publicId":"LibTmux::Async::Transport","qualifiedName":"LibTmux::Async::Transport","signatures":[{"params":[],"raw":"package LibTmux::Async::Transport;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Transport.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-transport"},{"apiScope":"exported","doc":{"summary":"Begin idempotent shutdown and return a fresh observer Future. New admissions fail with :obj:`Closed `; queued requests are cancelled without dispatch and running jobs are cancelled. Cancelling an observer never cancels private cleanup. Only successful `is_done` completion proves all owned jobs, pipes, and watchers have completed cleanup. The borrowed loop remains usable. Callers must keep driving it through shutdown."},"id":"LibTmux::Async::Transport::close","kind":"method","modifiers":[],"name":"close","package":"LibTmux-Async","parent":"LibTmux::Async::Transport","product":"core","publicId":"LibTmux::Async::Transport::close","qualifiedName":"LibTmux::Async::Transport::close","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub close($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Transport.pm","line":188,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-transport-close"},{"apiScope":"exported","doc":{"body":"The shared :obj:`LibTmux::ProcessJob ` owns supervision. Cancelling the Future requests cleanup; it does not prove exit or reverse command effects.","summary":"Accepts the same literal process arguments as :obj:`\"run\" in LibTmux::Transport `. Returns a [Future](https://metacpan.org/pod/Future) yielding one :obj:`command result `. Typed core exceptions remain the failure value. Queue overflow fails with :obj:`QueueFull ` before dispatch."},"id":"LibTmux::Async::Transport::execute","kind":"method","modifiers":[],"name":"execute","package":"LibTmux-Async","parent":"LibTmux::Async::Transport","product":"core","publicId":"LibTmux::Async::Transport::execute","qualifiedName":"LibTmux::Async::Transport::execute","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":19}],"params":[{"name":"request","variadic":"keyword"}],"raw":"sub execute($self, %request)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Transport.pm","line":32,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-transport-execute"},{"apiScope":"exported","doc":{"summary":"`new(loop => $loop, max_concurrent => 4, max_queue => 64)` borrows an [IO::Async::Loop](https://metacpan.org/pod/IO::Async::Loop). The loop owns supervisor reaping; competing external all-child reapers are unsupported. The library never runs/stops it."},"id":"LibTmux::Async::Transport::new","kind":"method","modifiers":[],"name":"new","package":"LibTmux-Async","parent":"LibTmux::Async::Transport","product":"core","publicId":"LibTmux::Async::Transport::new","qualifiedName":"LibTmux::Async::Transport::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":21,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub new($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/Transport.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-transport-new"},{"apiScope":"exported","doc":{"body":"","summary":"Shutdown has started and new work is refused. Callers may still observe cleanup through \"close\" in LibTmux::Async::Transport."},"id":"LibTmux::Async::X","kind":"class","modifiers":[],"name":"X","package":"LibTmux-Async","product":"core","publicId":"LibTmux::Async::X","qualifiedName":"LibTmux::Async::X","signatures":[{"params":[],"raw":"package LibTmux::Async::X;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/X.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-x"},{"apiScope":"exported","doc":{"summary":"Shutdown has started and new work is refused. Callers may still observe cleanup through :obj:`\"close\" in LibTmux::Async::Transport `."},"id":"LibTmux::Async::X::Closed","kind":"exception","modifiers":[],"name":"Closed","package":"LibTmux-Async","product":"core","publicId":"LibTmux::Async::X::Closed","qualifiedName":"LibTmux::Async::X::Closed","signatures":[{"params":[],"raw":"package LibTmux::Async::X::Closed;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-x-closed"},{"apiScope":"exported","doc":{"summary":"The configured running and pending limits are occupied. No command was submitted for this request. Returned through a failed [Future](https://metacpan.org/pod/Future)."},"id":"LibTmux::Async::X::QueueFull","kind":"exception","modifiers":[],"name":"QueueFull","package":"LibTmux-Async","product":"core","publicId":"LibTmux::Async::X::QueueFull","qualifiedName":"LibTmux::Async::X::QueueFull","signatures":[{"params":[],"raw":"package LibTmux::Async::X::QueueFull;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/async/lib/LibTmux/Async/X.pm","line":5,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-async-x-queuefull"},{"apiScope":"exported","doc":{"body":"\n## OWNERSHIP\n\nReaders use the retained graph and never refresh it. Acquire a new snapshot for new state. Inherited :obj:`to_record ` exports a detached scalar record.\n\n","summary":"Captured client entity"},"extends":["LibTmux::Entity"],"id":"LibTmux::Client","kind":"class","modifiers":[],"name":"Client","package":"LibTmux","product":"core","publicId":"LibTmux::Client","qualifiedName":"LibTmux::Client","signatures":[{"params":[],"raw":"package LibTmux::Client;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Client.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client"},{"apiScope":"exported","doc":{"summary":"Return the captured generation. Restarted daemons cannot silently reuse this handle."},"id":"LibTmux::Client::generation","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"generation","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::generation","qualifiedName":"LibTmux::Client::generation","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub generation($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-generation"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Client::height","kind":"method","modifiers":[],"name":"height","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::height","qualifiedName":"LibTmux::Client::height","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub height($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Client.pm","line":5,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-height"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Client::id","kind":"method","modifiers":[],"name":"id","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::id","qualifiedName":"LibTmux::Client::id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":6,"kind":"name","start":4}],"params":[],"raw":"sub id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Client.pm","line":6,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-id"},{"apiScope":"exported","doc":{"summary":"Return an opaque identity key scoped by server, generation, kind, and string ID. It is suitable for local equality; duplicate selection occurrences remain separate occurrences."},"id":"LibTmux::Client::identity","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"identity","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::identity","qualifiedName":"LibTmux::Client::identity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub identity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-identity"},{"apiScope":"exported","doc":{"summary":"Return the schema entity-kind string. Concrete public field readers belong to :obj:`LibTmux::Pane `, :obj:`LibTmux::Window `, :obj:`LibTmux::WindowLink `, :obj:`LibTmux::Session `, and :obj:`LibTmux::Client `."},"id":"LibTmux::Client::kind","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"kind","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::kind","qualifiedName":"LibTmux::Client::kind","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub kind($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-kind"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Client::name","kind":"method","modifiers":[],"name":"name","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::name","qualifiedName":"LibTmux::Client::name","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub name($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Client.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-name"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Client::pid","kind":"method","modifiers":[],"name":"pid","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::pid","qualifiedName":"LibTmux::Client::pid","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4}],"params":[],"raw":"sub pid($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Client.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-pid"},{"apiScope":"exported","doc":{"summary":"Return the captured server scope. No daemon discovery or refresh occurs."},"id":"LibTmux::Client::server_id","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"server_id","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::server_id","qualifiedName":"LibTmux::Client::server_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub server_id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-server_id"},{"apiScope":"exported","doc":{"summary":":obj:`LibTmux::Session ` entity or undef. Local captured data; no I/O."},"id":"LibTmux::Client::session","kind":"method","modifiers":[],"name":"session","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::session","qualifiedName":"LibTmux::Client::session","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub session($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Client.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-session"},{"apiScope":"exported","doc":{"summary":"Return a fresh hash reference of captured scalar fields and adjacency IDs. Editing it does not change the retained graph. Retaining the entity retains its captured graph, with no transport ownership or reference cycle."},"id":"LibTmux::Client::to_record","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"to_record","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::to_record","qualifiedName":"LibTmux::Client::to_record","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub to_record($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":21,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-to_record"},{"apiScope":"exported","doc":{"summary":"bytes. Local captured data; no I/O."},"id":"LibTmux::Client::tty","kind":"method","modifiers":[],"name":"tty","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::tty","qualifiedName":"LibTmux::Client::tty","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4}],"params":[],"raw":"sub tty($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Client.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-tty"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Client::width","kind":"method","modifiers":[],"name":"width","package":"LibTmux","parent":"LibTmux::Client","product":"core","publicId":"LibTmux::Client::width","qualifiedName":"LibTmux::Client::width","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub width($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Client.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-client-width"},{"apiScope":"exported","doc":{"body":"\n## DESCRIPTION\n\nInherits the fixed-return local query API of :obj:`LibTmux::Selection `. Members must be defined :obj:`LibTmux::Client ` handles from one server generation. Empty instances still validate against the client schema. Native array edits are possible; query methods validate membership and never perform tmux I/O.\n\n","summary":"Native array selection of captured client entities"},"extends":["LibTmux::Selection"],"id":"LibTmux::ClientSelection","kind":"class","modifiers":[],"name":"ClientSelection","package":"LibTmux","product":"core","publicId":"LibTmux::ClientSelection","qualifiedName":"LibTmux::ClientSelection","signatures":[{"params":[],"raw":"package LibTmux::ClientSelection;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ClientSelection.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection"},{"apiScope":"exported","doc":{"summary":"`count($criteria?)` returns an integer. Empty input returns zero. Validate all members before evaluating the optional criterion; count every matching occurrence, including duplicates."},"id":"LibTmux::ClientSelection::count","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::count","qualifiedName":"LibTmux::ClientSelection::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub count($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":77,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-count"},{"apiScope":"exported","doc":{"summary":"`exists($criteria?)` returns a native Boolean. Empty input returns false. After validating the entire membership, stop at the first matching entity. A reference itself remains true even when empty."},"id":"LibTmux::ClientSelection::exists","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"exists","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::exists","qualifiedName":"LibTmux::ClientSelection::exists","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub exists($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":85,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-exists"},{"apiScope":"exported","doc":{"summary":"`first($criteria?)` returns the first matching entity or undef. Input order determines first; after membership validation, later field reads may be skipped."},"id":"LibTmux::ClientSelection::first","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"first","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::first","qualifiedName":"LibTmux::ClientSelection::first","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub first($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":89,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-first"},{"apiScope":"exported","doc":{"summary":"`grep($callback)` returns a new same-class selection. Invoke the callback in scalar context with exactly one entity argument and a localized `$_`. Both bindings hold copies of the reference: assignment cannot replace a source slot. Restore `$_` and propagate the original thrown value even on failure. Predicates must not edit the traversed sequence."},"id":"LibTmux::ClientSelection::grep","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"grep","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::grep","qualifiedName":"LibTmux::ClientSelection::grep","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"callback"}],"raw":"sub grep($self, $callback)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":54,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-grep"},{"apiScope":"exported","doc":{"summary":"Return a fresh local cursor with a copy of current membership. Its `next` returns an entity or undef only at exhaustion. Later native array edits do not alter this traversal; the selection remains replayable."},"id":"LibTmux::ClientSelection::iterator","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"iterator","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::iterator","qualifiedName":"LibTmux::ClientSelection::iterator","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub iterator($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":122,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-iterator"},{"apiScope":"exported","doc":{"body":"Members may come from separate captures of the same server generation; each retains its own observation. Mixing servers or daemon generations throws :obj:`\"InvalidSelection\" in LibTmux::X `. Combining captures does not reconcile their times.","summary":"`new(@entities)` creates a concrete blessed array reference and validates every member. Construct an entity-specific selection such as :obj:`LibTmux::PaneSelection `; an empty instance retains that schema."},"id":"LibTmux::ClientSelection::new","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::new","qualifiedName":"LibTmux::ClientSelection::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":22,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"items","variadic":"positional"}],"raw":"sub new($class, @items)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-new"},{"apiScope":"exported","doc":{"summary":"`one($criteria?)` returns one entity. Zero throws :obj:`NoMatch `; a second occurrence throws :obj:`MultipleMatches `, reporting at least two and their IDs. Two occurrences of one identity are still ambiguous."},"id":"LibTmux::ClientSelection::one","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::one","qualifiedName":"LibTmux::ClientSelection::one","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":15}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":119,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-one"},{"apiScope":"exported","doc":{"summary":"`one_or_undef($criteria?)` returns an entity or undef for absence. A second matching occurrence still throws :obj:`MultipleMatches `."},"id":"LibTmux::ClientSelection::one_or_undef","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one_or_undef","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::one_or_undef","qualifiedName":"LibTmux::ClientSelection::one_or_undef","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":33,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one_or_undef($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":120,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-one_or_undef"},{"apiScope":"exported","doc":{"summary":"Return a fresh, unblessed array reference containing the same entity references. Editing its membership cannot corrupt graph adjacency or this selection. Captured entity values remain read-only through public readers."},"id":"LibTmux::ClientSelection::to_array","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"to_array","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::to_array","qualifiedName":"LibTmux::ClientSelection::to_array","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub to_array($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":66,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-to_array"},{"apiScope":"exported","doc":{"summary":"`where($criteria_or_filter)` eagerly returns a new selection of the same concrete class in scalar, list, or void context. Complete validation precedes evaluation, including on empty input. See :obj:`\"new\" in LibTmux::Filter `. Order and duplicate occurrences are preserved."},"id":"LibTmux::ClientSelection::where","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"where","package":"LibTmux","parent":"LibTmux::ClientSelection","product":"core","publicId":"LibTmux::ClientSelection::where","qualifiedName":"LibTmux::ClientSelection::where","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria"}],"raw":"sub where($self, $criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":48,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-clientselection-where"},{"apiScope":"exported","doc":{"body":"\n## OWNERSHIP\n\nReaders are local and do not mutate the result or perform I/O. A lifecycle exception may expose a bounded partial result; it does not imply rollback or command completion. See :obj:`\"run\" in LibTmux::Transport ` and :obj:`LibTmux::X `.\n\n","summary":"Completed or partial subprocess outcome"},"id":"LibTmux::CommandResult","kind":"class","modifiers":[],"name":"CommandResult","package":"LibTmux","product":"core","publicId":"LibTmux::CommandResult","qualifiedName":"LibTmux::CommandResult","signatures":[{"params":[],"raw":"package LibTmux::CommandResult;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/CommandResult.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-commandresult"},{"apiScope":"exported","doc":{"summary":"Return an exit code or undef when no child status is known."},"id":"LibTmux::CommandResult::exit_code","kind":"method","modifiers":[],"name":"exit_code","package":"LibTmux","parent":"LibTmux::CommandResult","product":"core","publicId":"LibTmux::CommandResult::exit_code","qualifiedName":"LibTmux::CommandResult::exit_code","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub exit_code($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/CommandResult.pm","line":5,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-commandresult-exit_code"},{"apiScope":"exported","doc":{"summary":"Return the POSIX wait status or undef when unavailable."},"id":"LibTmux::CommandResult::raw_status","kind":"method","modifiers":[],"name":"raw_status","package":"LibTmux","parent":"LibTmux::CommandResult","product":"core","publicId":"LibTmux::CommandResult::raw_status","qualifiedName":"LibTmux::CommandResult::raw_status","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub raw_status($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/CommandResult.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-commandresult-raw_status"},{"apiScope":"exported","doc":{"summary":"Return a terminating signal number, zero for ordinary exit, or undef for unknown status."},"id":"LibTmux::CommandResult::signal","kind":"method","modifiers":[],"name":"signal","package":"LibTmux","parent":"LibTmux::CommandResult","product":"core","publicId":"LibTmux::CommandResult::signal","qualifiedName":"LibTmux::CommandResult::signal","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub signal($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/CommandResult.pm","line":6,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-commandresult-signal"},{"apiScope":"exported","doc":{"summary":"Return separately retained stderr octets, possibly empty."},"id":"LibTmux::CommandResult::stderr","kind":"method","modifiers":[],"name":"stderr","package":"LibTmux","parent":"LibTmux::CommandResult","product":"core","publicId":"LibTmux::CommandResult::stderr","qualifiedName":"LibTmux::CommandResult::stderr","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub stderr($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/CommandResult.pm","line":4,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-commandresult-stderr"},{"apiScope":"exported","doc":{"summary":"Return retained stdout octets, possibly empty. No text decoding occurs."},"id":"LibTmux::CommandResult::stdout","kind":"method","modifiers":[],"name":"stdout","package":"LibTmux","parent":"LibTmux::CommandResult","product":"core","publicId":"LibTmux::CommandResult::stdout","qualifiedName":"LibTmux::CommandResult::stdout","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub stdout($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/CommandResult.pm","line":3,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-commandresult-stdout"},{"apiScope":"exported","doc":{"summary":"Return true only when known status proves ordinary exit zero. Unknown status is never success."},"id":"LibTmux::CommandResult::success","kind":"method","modifiers":[],"name":"success","package":"LibTmux","parent":"LibTmux::CommandResult","product":"core","publicId":"LibTmux::CommandResult::success","qualifiedName":"LibTmux::CommandResult::success","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub success($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/CommandResult.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-commandresult-success"},{"apiScope":"exported","doc":{"body":"\n## DESCRIPTION\n\nField readers and relationships resolve locally in the retained graph. :obj:`\"to_record\" ` returns detached scalar record data. Handles retain no transport.\n\n\n## EXECUTION\n\nAll methods in this module operate on local captured data and perform no tmux I/O. Ordering is deterministic; public query methods do not mutate membership. Typed validation/evaluation errors propagate. See :obj:`\"snapshot\" in LibTmux::Server ` for explicit acquisition and :obj:`LibTmux::X ` for machine-readable failures.\n\n","summary":"Read-only handle retaining a captured graph"},"id":"LibTmux::Entity","kind":"class","modifiers":[],"name":"Entity","package":"LibTmux","product":"core","publicId":"LibTmux::Entity","qualifiedName":"LibTmux::Entity","signatures":[{"params":[],"raw":"package LibTmux::Entity;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-entity"},{"apiScope":"exported","doc":{"summary":"Return the captured generation. Restarted daemons cannot silently reuse this handle."},"id":"LibTmux::Entity::generation","kind":"method","modifiers":[],"name":"generation","package":"LibTmux","parent":"LibTmux::Entity","product":"core","publicId":"LibTmux::Entity::generation","qualifiedName":"LibTmux::Entity::generation","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub generation($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-entity-generation"},{"apiScope":"exported","doc":{"summary":"Return an opaque identity key scoped by server, generation, kind, and string ID. It is suitable for local equality; duplicate selection occurrences remain separate occurrences."},"id":"LibTmux::Entity::identity","kind":"method","modifiers":[],"name":"identity","package":"LibTmux","parent":"LibTmux::Entity","product":"core","publicId":"LibTmux::Entity::identity","qualifiedName":"LibTmux::Entity::identity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub identity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-entity-identity"},{"apiScope":"exported","doc":{"summary":"Return the schema entity-kind string. Concrete public field readers belong to :obj:`LibTmux::Pane `, :obj:`LibTmux::Window `, :obj:`LibTmux::WindowLink `, :obj:`LibTmux::Session `, and :obj:`LibTmux::Client `."},"id":"LibTmux::Entity::kind","kind":"method","modifiers":[],"name":"kind","package":"LibTmux","parent":"LibTmux::Entity","product":"core","publicId":"LibTmux::Entity::kind","qualifiedName":"LibTmux::Entity::kind","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub kind($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-entity-kind"},{"apiScope":"exported","doc":{"summary":"Return the captured server scope. No daemon discovery or refresh occurs."},"id":"LibTmux::Entity::server_id","kind":"method","modifiers":[],"name":"server_id","package":"LibTmux","parent":"LibTmux::Entity","product":"core","publicId":"LibTmux::Entity::server_id","qualifiedName":"LibTmux::Entity::server_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub server_id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-entity-server_id"},{"apiScope":"exported","doc":{"summary":"Return a fresh hash reference of captured scalar fields and adjacency IDs. Editing it does not change the retained graph. Retaining the entity retains its captured graph, with no transport ownership or reference cycle."},"id":"LibTmux::Entity::to_record","kind":"method","modifiers":[],"name":"to_record","package":"LibTmux","parent":"LibTmux::Entity","product":"core","publicId":"LibTmux::Entity::to_record","qualifiedName":"LibTmux::Entity::to_record","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub to_record($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":21,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-entity-to_record"},{"apiScope":"exported","doc":{"body":"\n## SYNOPSIS\n\n\n```perl\n use v5.44;\n use LibTmux::Filter;\n my $filter = LibTmux::Filter->new(\n entity => 'pane', where => {width => {-gte => 120}},\n );\n my $matches = $snapshot->panes->where($filter);\n```\n\n\n## CONTRACT\n\nCompilation validates the entire tree and copies operands. Hash keys evaluate lexically; logical arrays retain input order. Missing reads throw; known-null ordering is false. String operators are literal. Relations use some/every/none and is/is_not with explicit dash prefixes in Perl data.\n\n`matches` accepts entities, plain records, and registered adapters. `to_data`/`to_json` export copies in libtmux.where/v1; `from_data`/`from_json` validate input. Regex/coderefs/cycles and non-UTF-8 byte-path wire operands are refused. Perl regex remains available through Selection `grep`.\n\n\n## EXECUTION\n\nAll methods in this module operate on local captured data and perform no tmux I/O. Ordering is deterministic; public query methods do not mutate membership. Typed validation/evaluation errors propagate. See :obj:`\"snapshot\" in LibTmux::Server ` for explicit acquisition and :obj:`LibTmux::X ` for machine-readable failures.\n\n","summary":"Validated, reusable local criteria and explicit wire data"},"id":"LibTmux::Filter","kind":"class","modifiers":[],"name":"Filter","package":"LibTmux","product":"core","publicId":"LibTmux::Filter","qualifiedName":"LibTmux::Filter","signatures":[{"params":[],"raw":"package LibTmux::Filter;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter"},{"apiScope":"exported","doc":{"summary":"Return the declared entity-kind string. It remains known for an empty :obj:`LibTmux::Selection `."},"id":"LibTmux::Filter::entity","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::Filter","product":"core","publicId":"LibTmux::Filter::entity","qualifiedName":"LibTmux::Filter::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter-entity"},{"apiScope":"exported","doc":{"summary":"`from_data($envelope)` validates the version, entity, fields, operators, and operands, then returns a compiled filter. Reject executable values, unknown versions, cycles, and unsupported regex nodes."},"id":"LibTmux::Filter::from_data","kind":"method","modifiers":[],"name":"from_data","package":"LibTmux","parent":"LibTmux::Filter","product":"core","publicId":"LibTmux::Filter::from_data","qualifiedName":"LibTmux::Filter::from_data","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"data"}],"raw":"sub from_data($class, $data)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":315,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter-from_data"},{"apiScope":"exported","doc":{"summary":"`from_json($json_octets)` decodes bounded JSON using core booleans and calls :obj:`\"from_data\" `. Invalid JSON throws :obj:`InvalidFilter `."},"id":"LibTmux::Filter::from_json","kind":"method","modifiers":[],"name":"from_json","package":"LibTmux","parent":"LibTmux::Filter","product":"core","publicId":"LibTmux::Filter::from_json","qualifiedName":"LibTmux::Filter::from_json","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"bytes"}],"raw":"sub from_json($class, $bytes)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":331,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter-from_json"},{"apiScope":"exported","doc":{"summary":"`matches($entity_or_record)` returns a native Boolean. Accept captured entities, plain hash records, or registered adapters of the declared kind. Missing required reads throw :obj:`Unloaded `; they never become null or false through negation. Evaluation performs no I/O."},"id":"LibTmux::Filter::matches","kind":"method","modifiers":[],"name":"matches","package":"LibTmux","parent":"LibTmux::Filter","product":"core","publicId":"LibTmux::Filter::matches","qualifiedName":"LibTmux::Filter::matches","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":19}],"params":[{"name":"record"}],"raw":"sub matches($self, $record)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":136,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter-matches"},{"apiScope":"exported","doc":{"summary":"`new(entity => kind, where => $hashref)` validates the complete criteria tree and owns a normalized copy. Schemas choose comparison types; no scalar-history coercion or arbitrary method dispatch occurs. Errors throw :obj:`InvalidFilter ` with precise paths, even for unreachable branches."},"id":"LibTmux::Filter::new","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::Filter","product":"core","publicId":"LibTmux::Filter::new","qualifiedName":"LibTmux::Filter::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":21,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub new($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter-new"},{"apiScope":"exported","doc":{"summary":"Return an independent copy of normalized Perl criteria. Editing it does not change the compiled filter."},"id":"LibTmux::Filter::normalized_where","kind":"method","modifiers":[],"name":"normalized_where","package":"LibTmux","parent":"LibTmux::Filter","product":"core","publicId":"LibTmux::Filter::normalized_where","qualifiedName":"LibTmux::Filter::normalized_where","signatures":[{"methodKind":"call","nativeSyntax":[{"end":20,"kind":"name","start":4}],"params":[],"raw":"sub normalized_where($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter-normalized_where"},{"apiScope":"exported","doc":{"summary":"`register_adapter(class => name, entity => kind, readers => { field => coderef })` registers trusted field readers without inheritance. Only declared fields are accepted. Readers are executable local code; they never enter portable criteria. See :obj:`LibTmux::Schema `."},"id":"LibTmux::Filter::register_adapter","kind":"method","modifiers":[],"name":"register_adapter","package":"LibTmux","parent":"LibTmux::Filter","product":"core","publicId":"LibTmux::Filter::register_adapter","qualifiedName":"LibTmux::Filter::register_adapter","signatures":[{"methodKind":"call","nativeSyntax":[{"end":20,"kind":"name","start":4},{"end":34,"kind":"parameter","parameter":0,"start":29}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub register_adapter($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":20,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter-register_adapter"},{"apiScope":"exported","doc":{"summary":"Return a fresh `libtmux.where/v1` envelope using canonical wire field/operator names. Normalize strings, numbers, native booleans, null, objects, and arrays by schema. Aliases are currently absent; one canonical name is encoded."},"id":"LibTmux::Filter::to_data","kind":"method","modifiers":[],"name":"to_data","package":"LibTmux","parent":"LibTmux::Filter","product":"core","publicId":"LibTmux::Filter::to_data","qualifiedName":"LibTmux::Filter::to_data","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub to_data($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":301,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter-to_data"},{"apiScope":"exported","doc":{"summary":"Return canonical-key UTF-8 JSON octets using [JSON::PP](https://perldoc.perl.org/5.44.0/JSON::PP). Non-UTF-8 opaque path bytes throw :obj:`UnsupportedValue `. This is reproducible key order, not semantic canonicalization of arbitrary Boolean trees."},"id":"LibTmux::Filter::to_json","kind":"method","modifiers":[],"name":"to_json","package":"LibTmux","parent":"LibTmux::Filter","product":"core","publicId":"LibTmux::Filter::to_json","qualifiedName":"LibTmux::Filter::to_json","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub to_json($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Filter.pm","line":311,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-filter-to_json"},{"apiScope":"exported","doc":{"body":"","summary":"Executor-independent prepared command continuations"},"id":"LibTmux::Operation","kind":"class","modifiers":[],"name":"Operation","package":"LibTmux","product":"core","publicId":"LibTmux::Operation","qualifiedName":"LibTmux::Operation","signatures":[{"params":[],"raw":"package LibTmux::Operation;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Operation.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-operation"},{"apiScope":"exported","doc":{"summary":"Recover a failure with one value or another Operation."},"id":"LibTmux::Operation::catch","kind":"method","modifiers":[],"name":"catch","package":"LibTmux","parent":"LibTmux::Operation","product":"core","publicId":"LibTmux::Operation::catch","qualifiedName":"LibTmux::Operation::catch","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"callback"}],"raw":"sub catch($self, $callback)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Operation.pm","line":33,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-operation-catch"},{"apiScope":"exported","doc":{"summary":"`request(argv => [...], stdin => $octets, ...)` owns its input arguments. Execution is explicit through :obj:`\"run\" `; preparation performs no I/O."},"id":"LibTmux::Operation::request","kind":"method","modifiers":[],"name":"request","package":"LibTmux","parent":"LibTmux::Operation","product":"core","publicId":"LibTmux::Operation::request","qualifiedName":"LibTmux::Operation::request","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":20}],"params":[{"name":"request","variadic":"keyword"}],"raw":"sub request($class, %request)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Operation.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-operation-request"},{"apiScope":"exported","doc":{"body":"The synchronous :obj:`LibTmux::Server ` and optional async distribution use the same preparation, codecs, and graph semantics. Core has no Future dependency.","summary":"`run($executor, $on_done, $on_fail)` supplies requests and two one-argument completion callbacks to the executor. The executor returns a cancellation hook. `run` returns a cancellation coderef suppressing further submissions. Each request settles once; the complete operation yields one value or error."},"id":"LibTmux::Operation::run","kind":"method","modifiers":[],"name":"run","package":"LibTmux","parent":"LibTmux::Operation","product":"core","publicId":"LibTmux::Operation::run","qualifiedName":"LibTmux::Operation::run","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":15},{"end":31,"kind":"parameter","parameter":1,"start":26},{"end":38,"kind":"parameter","parameter":2,"start":33}],"params":[{"name":"executor"},{"name":"done"},{"name":"fail"}],"raw":"sub run($self, $executor, $done, $fail)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Operation.pm","line":51,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-operation-run"},{"apiScope":"exported","doc":{"summary":"Execute an array of Operations in order, returning one arrayref of results."},"id":"LibTmux::Operation::sequence","kind":"method","modifiers":[],"name":"sequence","package":"LibTmux","parent":"LibTmux::Operation","product":"core","publicId":"LibTmux::Operation::sequence","qualifiedName":"LibTmux::Operation::sequence","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4},{"end":32,"kind":"parameter","parameter":0,"start":21}],"params":[{"name":"operations"}],"raw":"sub sequence($class, $operations)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Operation.pm","line":39,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-operation-sequence"},{"apiScope":"exported","doc":{"summary":"Compose a local transformation returning one value or another Operation. Exceptions retain their original identity."},"id":"LibTmux::Operation::then","kind":"method","modifiers":[],"name":"then","package":"LibTmux","parent":"LibTmux::Operation","product":"core","publicId":"LibTmux::Operation::then","qualifiedName":"LibTmux::Operation::then","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"callback"}],"raw":"sub then($self, $callback)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Operation.pm","line":27,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-operation-then"},{"apiScope":"exported","doc":{"summary":"Wrap one local value, including undef for a documented void operation."},"id":"LibTmux::Operation::value","kind":"method","modifiers":[],"name":"value","package":"LibTmux","parent":"LibTmux::Operation","product":"core","publicId":"LibTmux::Operation::value","qualifiedName":"LibTmux::Operation::value","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"value"}],"raw":"sub value($class, $value)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Operation.pm","line":25,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-operation-value"},{"apiScope":"exported","doc":{"body":"\n## OWNERSHIP\n\nReaders use the retained graph and never refresh it. Acquire a new snapshot for new state. Inherited :obj:`to_record ` exports a detached scalar record.\n\n","summary":"Captured pane entity"},"extends":["LibTmux::Entity"],"id":"LibTmux::Pane","kind":"class","modifiers":[],"name":"Pane","package":"LibTmux","product":"core","publicId":"LibTmux::Pane","qualifiedName":"LibTmux::Pane","signatures":[{"params":[],"raw":"package LibTmux::Pane;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane"},{"apiScope":"exported","doc":{"summary":"boolean. Local captured data; no I/O."},"id":"LibTmux::Pane::active","kind":"method","modifiers":[],"name":"active","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::active","qualifiedName":"LibTmux::Pane::active","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub active($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":5,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-active"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Pane::current_command","kind":"method","modifiers":[],"name":"current_command","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::current_command","qualifiedName":"LibTmux::Pane::current_command","signatures":[{"methodKind":"call","nativeSyntax":[{"end":19,"kind":"name","start":4}],"params":[],"raw":"sub current_command($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":6,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-current_command"},{"apiScope":"exported","doc":{"summary":"bytes. Local captured data; no I/O."},"id":"LibTmux::Pane::current_path","kind":"method","modifiers":[],"name":"current_path","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::current_path","qualifiedName":"LibTmux::Pane::current_path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4}],"params":[],"raw":"sub current_path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-current_path"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Pane::cursor_shape","kind":"method","modifiers":[],"name":"cursor_shape","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::cursor_shape","qualifiedName":"LibTmux::Pane::cursor_shape","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4}],"params":[],"raw":"sub cursor_shape($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-cursor_shape"},{"apiScope":"exported","doc":{"summary":"boolean. Local captured data; no I/O."},"id":"LibTmux::Pane::dead","kind":"method","modifiers":[],"name":"dead","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::dead","qualifiedName":"LibTmux::Pane::dead","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub dead($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-dead"},{"apiScope":"exported","doc":{"summary":"integer or undef. Local captured data; no I/O."},"id":"LibTmux::Pane::exit_status","kind":"method","modifiers":[],"name":"exit_status","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::exit_status","qualifiedName":"LibTmux::Pane::exit_status","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub exit_status($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-exit_status"},{"apiScope":"exported","doc":{"summary":"Return the captured generation. Restarted daemons cannot silently reuse this handle."},"id":"LibTmux::Pane::generation","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"generation","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::generation","qualifiedName":"LibTmux::Pane::generation","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub generation($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-generation"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Pane::height","kind":"method","modifiers":[],"name":"height","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::height","qualifiedName":"LibTmux::Pane::height","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub height($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-height"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Pane::id","kind":"method","modifiers":[],"name":"id","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::id","qualifiedName":"LibTmux::Pane::id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":6,"kind":"name","start":4}],"params":[],"raw":"sub id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-id"},{"apiScope":"exported","doc":{"summary":"Return an opaque identity key scoped by server, generation, kind, and string ID. It is suitable for local equality; duplicate selection occurrences remain separate occurrences."},"id":"LibTmux::Pane::identity","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"identity","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::identity","qualifiedName":"LibTmux::Pane::identity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub identity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-identity"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Pane::index","kind":"method","modifiers":[],"name":"index","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::index","qualifiedName":"LibTmux::Pane::index","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub index($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-index"},{"apiScope":"exported","doc":{"summary":"Return the schema entity-kind string. Concrete public field readers belong to :obj:`LibTmux::Pane `, :obj:`LibTmux::Window `, :obj:`LibTmux::WindowLink `, :obj:`LibTmux::Session `, and :obj:`LibTmux::Client `."},"id":"LibTmux::Pane::kind","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"kind","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::kind","qualifiedName":"LibTmux::Pane::kind","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub kind($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-kind"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Pane::pid","kind":"method","modifiers":[],"name":"pid","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::pid","qualifiedName":"LibTmux::Pane::pid","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4}],"params":[],"raw":"sub pid($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-pid"},{"apiScope":"exported","doc":{"summary":"Return the captured server scope. No daemon discovery or refresh occurs."},"id":"LibTmux::Pane::server_id","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"server_id","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::server_id","qualifiedName":"LibTmux::Pane::server_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub server_id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-server_id"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Pane::title","kind":"method","modifiers":[],"name":"title","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::title","qualifiedName":"LibTmux::Pane::title","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub title($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-title"},{"apiScope":"exported","doc":{"summary":"Return a fresh hash reference of captured scalar fields and adjacency IDs. Editing it does not change the retained graph. Retaining the entity retains its captured graph, with no transport ownership or reference cycle."},"id":"LibTmux::Pane::to_record","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"to_record","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::to_record","qualifiedName":"LibTmux::Pane::to_record","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub to_record($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":21,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-to_record"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Pane::width","kind":"method","modifiers":[],"name":"width","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::width","qualifiedName":"LibTmux::Pane::width","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub width($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-width"},{"apiScope":"exported","doc":{"summary":":obj:`LibTmux::Window ` entity. Local captured data; no I/O."},"id":"LibTmux::Pane::window","kind":"method","modifiers":[],"name":"window","package":"LibTmux","parent":"LibTmux::Pane","product":"core","publicId":"LibTmux::Pane::window","qualifiedName":"LibTmux::Pane::window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub window($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Pane.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-pane-window"},{"apiScope":"exported","doc":{"body":"\n## DESCRIPTION\n\nInherits the fixed-return local query API of :obj:`LibTmux::Selection `. Members must be defined :obj:`LibTmux::Pane ` handles from one server generation. Empty instances still validate against the pane schema. Native array edits are possible; query methods validate membership and never perform tmux I/O.\n\n","summary":"Native array selection of captured pane entities"},"extends":["LibTmux::Selection"],"id":"LibTmux::PaneSelection","kind":"class","modifiers":[],"name":"PaneSelection","package":"LibTmux","product":"core","publicId":"LibTmux::PaneSelection","qualifiedName":"LibTmux::PaneSelection","signatures":[{"params":[],"raw":"package LibTmux::PaneSelection;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/PaneSelection.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection"},{"apiScope":"exported","doc":{"summary":"`count($criteria?)` returns an integer. Empty input returns zero. Validate all members before evaluating the optional criterion; count every matching occurrence, including duplicates."},"id":"LibTmux::PaneSelection::count","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::count","qualifiedName":"LibTmux::PaneSelection::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub count($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":77,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-count"},{"apiScope":"exported","doc":{"summary":"`exists($criteria?)` returns a native Boolean. Empty input returns false. After validating the entire membership, stop at the first matching entity. A reference itself remains true even when empty."},"id":"LibTmux::PaneSelection::exists","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"exists","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::exists","qualifiedName":"LibTmux::PaneSelection::exists","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub exists($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":85,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-exists"},{"apiScope":"exported","doc":{"summary":"`first($criteria?)` returns the first matching entity or undef. Input order determines first; after membership validation, later field reads may be skipped."},"id":"LibTmux::PaneSelection::first","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"first","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::first","qualifiedName":"LibTmux::PaneSelection::first","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub first($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":89,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-first"},{"apiScope":"exported","doc":{"summary":"`grep($callback)` returns a new same-class selection. Invoke the callback in scalar context with exactly one entity argument and a localized `$_`. Both bindings hold copies of the reference: assignment cannot replace a source slot. Restore `$_` and propagate the original thrown value even on failure. Predicates must not edit the traversed sequence."},"id":"LibTmux::PaneSelection::grep","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"grep","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::grep","qualifiedName":"LibTmux::PaneSelection::grep","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"callback"}],"raw":"sub grep($self, $callback)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":54,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-grep"},{"apiScope":"exported","doc":{"summary":"Return a fresh local cursor with a copy of current membership. Its `next` returns an entity or undef only at exhaustion. Later native array edits do not alter this traversal; the selection remains replayable."},"id":"LibTmux::PaneSelection::iterator","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"iterator","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::iterator","qualifiedName":"LibTmux::PaneSelection::iterator","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub iterator($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":122,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-iterator"},{"apiScope":"exported","doc":{"body":"Members may come from separate captures of the same server generation; each retains its own observation. Mixing servers or daemon generations throws :obj:`\"InvalidSelection\" in LibTmux::X `. Combining captures does not reconcile their times.","summary":"`new(@entities)` creates a concrete blessed array reference and validates every member. Construct an entity-specific selection such as :obj:`LibTmux::PaneSelection `; an empty instance retains that schema."},"id":"LibTmux::PaneSelection::new","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::new","qualifiedName":"LibTmux::PaneSelection::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":22,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"items","variadic":"positional"}],"raw":"sub new($class, @items)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-new"},{"apiScope":"exported","doc":{"summary":"`one($criteria?)` returns one entity. Zero throws :obj:`NoMatch `; a second occurrence throws :obj:`MultipleMatches `, reporting at least two and their IDs. Two occurrences of one identity are still ambiguous."},"id":"LibTmux::PaneSelection::one","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::one","qualifiedName":"LibTmux::PaneSelection::one","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":15}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":119,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-one"},{"apiScope":"exported","doc":{"summary":"`one_or_undef($criteria?)` returns an entity or undef for absence. A second matching occurrence still throws :obj:`MultipleMatches `."},"id":"LibTmux::PaneSelection::one_or_undef","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one_or_undef","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::one_or_undef","qualifiedName":"LibTmux::PaneSelection::one_or_undef","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":33,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one_or_undef($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":120,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-one_or_undef"},{"apiScope":"exported","doc":{"summary":"Return a fresh, unblessed array reference containing the same entity references. Editing its membership cannot corrupt graph adjacency or this selection. Captured entity values remain read-only through public readers."},"id":"LibTmux::PaneSelection::to_array","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"to_array","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::to_array","qualifiedName":"LibTmux::PaneSelection::to_array","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub to_array($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":66,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-to_array"},{"apiScope":"exported","doc":{"summary":"`where($criteria_or_filter)` eagerly returns a new selection of the same concrete class in scalar, list, or void context. Complete validation precedes evaluation, including on empty input. See :obj:`\"new\" in LibTmux::Filter `. Order and duplicate occurrences are preserved."},"id":"LibTmux::PaneSelection::where","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"where","package":"LibTmux","parent":"LibTmux::PaneSelection","product":"core","publicId":"LibTmux::PaneSelection::where","qualifiedName":"LibTmux::PaneSelection::where","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria"}],"raw":"sub where($self, $criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":48,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-paneselection-where"},{"apiScope":"exported","doc":{"body":"","summary":"Shared owned process-supervision boundary"},"id":"LibTmux::ProcessJob","kind":"class","modifiers":[],"name":"ProcessJob","package":"LibTmux","product":"core","publicId":"LibTmux::ProcessJob","qualifiedName":"LibTmux::ProcessJob","signatures":[{"params":[],"raw":"package LibTmux::ProcessJob;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ProcessJob.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-processjob"},{"apiScope":"exported","doc":{"summary":"Request cleanup without blocking. Cancellation can follow dispatch and does not imply rollback or completed reaping."},"id":"LibTmux::ProcessJob::cancel","kind":"method","modifiers":[],"name":"cancel","package":"LibTmux","parent":"LibTmux::ProcessJob","product":"core","publicId":"LibTmux::ProcessJob::cancel","qualifiedName":"LibTmux::ProcessJob::cancel","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub cancel($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ProcessJob.pm","line":100,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-processjob-cancel"},{"apiScope":"exported","doc":{"summary":"True only after a valid supervisor result proves owned program cleanup."},"id":"LibTmux::ProcessJob::cleanup_complete","kind":"method","modifiers":[],"name":"cleanup_complete","package":"LibTmux","parent":"LibTmux::ProcessJob","product":"core","publicId":"LibTmux::ProcessJob::cleanup_complete","qualifiedName":"LibTmux::ProcessJob::cleanup_complete","signatures":[{"methodKind":"call","nativeSyntax":[{"end":20,"kind":"name","start":4}],"params":[],"raw":"sub cleanup_complete($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ProcessJob.pm","line":91,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-processjob-cleanup_complete"},{"apiScope":"exported","doc":{"summary":"Accumulate bounded result octets. Malformed or excessive data is a failure."},"id":"LibTmux::ProcessJob::consume","kind":"method","modifiers":[],"name":"consume","package":"LibTmux","parent":"LibTmux::ProcessJob","product":"core","publicId":"LibTmux::ProcessJob::consume","qualifiedName":"LibTmux::ProcessJob::consume","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":19}],"params":[{"name":"bytes"}],"raw":"sub consume($self, $bytes)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ProcessJob.pm","line":112,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-processjob-consume"},{"apiScope":"exported","doc":{"summary":"Decode the complete result after EOF and supervisor exit. Return one :obj:`LibTmux::CommandResult ` or throw a typed error."},"id":"LibTmux::ProcessJob::finish","kind":"method","modifiers":[],"name":"finish","package":"LibTmux","parent":"LibTmux::ProcessJob","product":"core","publicId":"LibTmux::ProcessJob::finish","qualifiedName":"LibTmux::ProcessJob::finish","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub finish($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ProcessJob.pm","line":120,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-processjob-finish"},{"apiScope":"exported","doc":{"summary":"Return the supervisor PID. It differs from the program PID."},"id":"LibTmux::ProcessJob::pid","kind":"method","modifiers":[],"name":"pid","package":"LibTmux","parent":"LibTmux::ProcessJob","product":"core","publicId":"LibTmux::ProcessJob::pid","qualifiedName":"LibTmux::ProcessJob::pid","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4}],"params":[],"raw":"sub pid($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ProcessJob.pm","line":90,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-processjob-pid"},{"apiScope":"exported","doc":{"summary":"Start a supervised literal command using the same arguments as :obj:`\"run\" in LibTmux::Transport `. This explicit operation performs I/O."},"id":"LibTmux::ProcessJob::start","kind":"method","modifiers":[],"name":"start","package":"LibTmux","parent":"LibTmux::ProcessJob","product":"core","publicId":"LibTmux::ProcessJob::start","qualifiedName":"LibTmux::ProcessJob::start","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"input","variadic":"keyword"}],"raw":"sub start($class, %input)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ProcessJob.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-processjob-start"},{"apiScope":"exported","doc":{"summary":"Transfer the result pipe exactly once. Its reader owns closing that handle."},"id":"LibTmux::ProcessJob::take_result_handle","kind":"method","modifiers":[],"name":"take_result_handle","package":"LibTmux","parent":"LibTmux::ProcessJob","product":"core","publicId":"LibTmux::ProcessJob::take_result_handle","qualifiedName":"LibTmux::ProcessJob::take_result_handle","signatures":[{"methodKind":"call","nativeSyntax":[{"end":22,"kind":"name","start":4}],"params":[],"raw":"sub take_result_handle($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ProcessJob.pm","line":93,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-processjob-take_result_handle"},{"apiScope":"exported","doc":{"summary":"The synchronous reader/reaper. A loop-owned job refuses blocking wait. Async adapters supply a spawn/reap callback and retain jobs through EOF plus the matching exit notification. Dropping a job closes its parent guard but does not synchronously wait; owners must complete their cleanup protocol."},"id":"LibTmux::ProcessJob::wait","kind":"method","modifiers":[],"name":"wait","package":"LibTmux","parent":"LibTmux::ProcessJob","product":"core","publicId":"LibTmux::ProcessJob::wait","qualifiedName":"LibTmux::ProcessJob::wait","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub wait($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/ProcessJob.pm","line":192,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-processjob-wait"},{"apiScope":"exported","doc":{"body":"","summary":"Explainable explicit pane acquisition"},"id":"LibTmux::QueryPlan","kind":"class","modifiers":[],"name":"QueryPlan","package":"LibTmux","product":"core","publicId":"LibTmux::QueryPlan","qualifiedName":"LibTmux::QueryPlan","signatures":[{"params":[],"raw":"package LibTmux::QueryPlan;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/QueryPlan.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-queryplan"},{"apiScope":"exported","doc":{"summary":"Return the compiled :obj:`LibTmux::Filter `. Its matching remains local."},"id":"LibTmux::QueryPlan::filter","kind":"method","modifiers":[],"name":"filter","package":"LibTmux","parent":"LibTmux::QueryPlan","product":"core","publicId":"LibTmux::QueryPlan::filter","qualifiedName":"LibTmux::QueryPlan::filter","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub filter($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/QueryPlan.pm","line":31,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-queryplan-filter"},{"apiScope":"exported","doc":{"summary":"Return auto, never, or require. :obj:`\"query_panes\" in LibTmux::Server ` executes the plan with complete captured local evaluation. Native candidates cannot hide errors or discard matches from that captured result. Only verified complete translation qualifies for require; runtime disagreement is a race error."},"id":"LibTmux::QueryPlan::policy","kind":"method","modifiers":[],"name":"policy","package":"LibTmux","parent":"LibTmux::QueryPlan","product":"core","publicId":"LibTmux::QueryPlan::policy","qualifiedName":"LibTmux::QueryPlan::policy","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub policy($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/QueryPlan.pm","line":32,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-queryplan-policy"},{"apiScope":"exported","doc":{"summary":"Describe native lowering and local residual reasons. Explanation performs no I/O and uses the support floor until connected capabilities are available."},"id":"LibTmux::QueryPlan::summary","kind":"method","modifiers":[],"name":"summary","package":"LibTmux","parent":"LibTmux::QueryPlan","product":"core","publicId":"LibTmux::QueryPlan::summary","qualifiedName":"LibTmux::QueryPlan::summary","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub summary($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/QueryPlan.pm","line":146,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-queryplan-summary"},{"apiScope":"exported","doc":{"summary":"Return an inspectable plan with source commands, filter, policy, and reasons. The :obj:`LibTmux::Schema ` catalog identifies required fields and relations."},"id":"LibTmux::QueryPlan::to_data","kind":"method","modifiers":[],"name":"to_data","package":"LibTmux","parent":"LibTmux::QueryPlan","product":"core","publicId":"LibTmux::QueryPlan::to_data","qualifiedName":"LibTmux::QueryPlan::to_data","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub to_data($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/QueryPlan.pm","line":190,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-queryplan-to_data"},{"apiScope":"exported","doc":{"body":"","summary":"Catalog and explicit record adapters"},"id":"LibTmux::Schema","kind":"class","modifiers":[],"name":"Schema","package":"LibTmux","product":"core","publicId":"LibTmux::Schema","qualifiedName":"LibTmux::Schema","signatures":[{"params":[],"raw":"package LibTmux::Schema;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Schema.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-schema"},{"apiScope":"exported","doc":{"summary":"`register_adapter(class => ..., entity => ..., readers => {...})` registers trusted callbacks for declared fields. Unknown criteria keys never become method names. Missing fields throw; nullable undef is known null."},"id":"LibTmux::Schema::register_adapter","kind":"method","modifiers":[],"name":"register_adapter","package":"LibTmux","parent":"LibTmux::Schema","product":"core","publicId":"LibTmux::Schema::register_adapter","qualifiedName":"LibTmux::Schema::register_adapter","signatures":[{"methodKind":"call","nativeSyntax":[{"end":20,"kind":"name","start":4},{"end":34,"kind":"parameter","parameter":0,"start":29}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub register_adapter($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Schema.pm","line":121,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-schema-register_adapter"},{"apiScope":"exported","doc":{"body":"\n## EXECUTION\n\nAll methods in this module operate on local captured data and perform no tmux I/O. Ordering is deterministic; public query methods do not mutate membership. Typed validation/evaluation errors propagate. See :obj:`\"snapshot\" in LibTmux::Server ` for explicit acquisition and :obj:`LibTmux::X ` for machine-readable failures.\n\n","summary":"Native array selections with fixed query returns","examples":[{"lang":"perl","code":"use v5.44;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse LibTmuxFixture;\nuse LibTmux::Filter;\nuse List::Util qw(any first);\nLibTmuxFixture->run(\n sub ($server, $root) {\n my $session = $server->new_session(\n name => 'example',\n command => ['/bin/sleep', '120']\n );\n my $initial = $session->window_links->one->window->panes->one;\n $server->split_pane(\n pane => $initial,\n horizontal => true,\n command => ['/bin/sleep', '120']\n );\n my $snapshot = $server->snapshot;\n my $panes = $snapshot->panes->where({current_command => 'sleep'})\n ->grep(sub ($pane) { $pane->width >= 1 });\n die 'expected two panes' unless $panes->count == 2;\n for my $pane ($panes->@*) {\n say $pane->id . ' ' . $pane->current_command;\n }\n my $only_active = $panes->one({active => true});\n die 'active pane unavailable' unless defined $only_active;\n my $has_active = any { $_->active } $panes->@*;\n my $first_active = first { $_->active } $panes->@*;\n die 'List::Util alternatives differ'\n unless $has_active && $first_active->id eq $only_active->id;\n my @ids = map { $_->id } $panes->@*;\n my @positive = grep { $_->width > 0 } $panes->@*;\n die 'ordinary Perl arrays differ' unless @ids == 2 && @positive == 2;\n my $filter =\n LibTmux::Filter->new(entity => 'pane', where => {active => true});\n my $decoded = LibTmux::Filter->from_json($filter->to_json);\n die 'wire filter changed meaning'\n unless $panes->where($decoded)->one->id eq $only_active->id;\n my $retained = do {\n my $observed = $server->snapshot;\n $observed->pane_by_id($only_active->id);\n };\n die 'retained graph lost a relationship'\n unless $retained->window->panes->count == 2;\n my $same_child = $snapshot->windows->where(\n {panes => {-some => {-and => [{index => 0}, {index => 1}]}}});\n my $different_children = $snapshot->windows->where(\n {\n -and => [\n {panes => {-some => {index => 0}}},\n {panes => {-some => {index => 1}}}\n ]\n }\n );\n die 'quantifiers conflated children'\n unless $same_child->count == 0 && $different_children->count == 1;\n my $where = {active => true, width => {-gte => 1}};\n my $local = $server->query_panes(where => $where, pushdown => 'never');\n my $native =\n $server->query_panes(where => $where, pushdown => 'require');\n die 'native/local disagreement'\n unless join(',', map { $_->id } @$local) eq\n join(',', map { $_->id } @$native);\n say 'selection, wire, graph lifetime, quantifiers, and query: ok';\n }\n);\n","intro":"Complete installed-package program with an owned tmux fixture and result/cleanup assertions.","sourceUrl":"https://github.com/libtmux/libtmux-perl/blob/36b978c5eb6aa33873229046037e7d26136ca2cf/examples/selection.pl"}]},"id":"LibTmux::Selection","kind":"class","modifiers":[],"name":"Selection","package":"LibTmux","product":"core","publicId":"LibTmux::Selection","qualifiedName":"LibTmux::Selection","signatures":[{"params":[],"raw":"package LibTmux::Selection;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection"},{"apiScope":"exported","doc":{"body":"","summary":"Local cursor over frozen membership"},"id":"LibTmux::Selection::Iterator","kind":"class","modifiers":[],"name":"Iterator","package":"LibTmux","product":"core","publicId":"LibTmux::Selection::Iterator","qualifiedName":"LibTmux::Selection::Iterator","signatures":[{"params":[],"raw":"package LibTmux::Selection::Iterator;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection/Iterator.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-iterator-cvun"},{"apiScope":"exported","doc":{"summary":"Return the next captured entity or undef only at exhaustion. Order and multiplicity match creation-time membership. Later native selection edits do not change this traversal. A cursor is consumable; create a fresh cursor with :obj:`\"iterator\" in LibTmux::Selection ` to traverse again. No tmux I/O occurs."},"id":"LibTmux::Selection::Iterator::next","kind":"method","modifiers":[],"name":"next","package":"LibTmux","parent":"LibTmux::Selection::Iterator","product":"core","publicId":"LibTmux::Selection::Iterator::next","qualifiedName":"LibTmux::Selection::Iterator::next","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub next($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection/Iterator.pm","line":4,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-iterator-next"},{"apiScope":"exported","doc":{"summary":"`count($criteria?)` returns an integer. Empty input returns zero. Validate all members before evaluating the optional criterion; count every matching occurrence, including duplicates."},"id":"LibTmux::Selection::count","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::count","qualifiedName":"LibTmux::Selection::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub count($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":77,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-count"},{"apiScope":"exported","doc":{"summary":"`exists($criteria?)` returns a native Boolean. Empty input returns false. After validating the entire membership, stop at the first matching entity. A reference itself remains true even when empty."},"id":"LibTmux::Selection::exists","kind":"method","modifiers":[],"name":"exists","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::exists","qualifiedName":"LibTmux::Selection::exists","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub exists($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":85,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-exists"},{"apiScope":"exported","doc":{"summary":"`first($criteria?)` returns the first matching entity or undef. Input order determines first; after membership validation, later field reads may be skipped."},"id":"LibTmux::Selection::first","kind":"method","modifiers":[],"name":"first","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::first","qualifiedName":"LibTmux::Selection::first","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub first($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":89,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-first"},{"apiScope":"exported","doc":{"summary":"`grep($callback)` returns a new same-class selection. Invoke the callback in scalar context with exactly one entity argument and a localized `$_`. Both bindings hold copies of the reference: assignment cannot replace a source slot. Restore `$_` and propagate the original thrown value even on failure. Predicates must not edit the traversed sequence."},"id":"LibTmux::Selection::grep","kind":"method","modifiers":[],"name":"grep","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::grep","qualifiedName":"LibTmux::Selection::grep","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"callback"}],"raw":"sub grep($self, $callback)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":54,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-grep"},{"apiScope":"exported","doc":{"summary":"Return a fresh local cursor with a copy of current membership. Its `next` returns an entity or undef only at exhaustion. Later native array edits do not alter this traversal; the selection remains replayable."},"id":"LibTmux::Selection::iterator","kind":"method","modifiers":[],"name":"iterator","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::iterator","qualifiedName":"LibTmux::Selection::iterator","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub iterator($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":122,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-iterator-2bn1"},{"apiScope":"exported","doc":{"body":"Members may come from separate captures of the same server generation; each retains its own observation. Mixing servers or daemon generations throws :obj:`\"InvalidSelection\" in LibTmux::X `. Combining captures does not reconcile their times.","summary":"`new(@entities)` creates a concrete blessed array reference and validates every member. Construct an entity-specific selection such as :obj:`LibTmux::PaneSelection `; an empty instance retains that schema."},"id":"LibTmux::Selection::new","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::new","qualifiedName":"LibTmux::Selection::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":22,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"items","variadic":"positional"}],"raw":"sub new($class, @items)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-new"},{"apiScope":"exported","doc":{"summary":"`one($criteria?)` returns one entity. Zero throws :obj:`NoMatch `; a second occurrence throws :obj:`MultipleMatches `, reporting at least two and their IDs. Two occurrences of one identity are still ambiguous."},"id":"LibTmux::Selection::one","kind":"method","modifiers":[],"name":"one","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::one","qualifiedName":"LibTmux::Selection::one","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":15}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":119,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-one"},{"apiScope":"exported","doc":{"summary":"`one_or_undef($criteria?)` returns an entity or undef for absence. A second matching occurrence still throws :obj:`MultipleMatches `."},"id":"LibTmux::Selection::one_or_undef","kind":"method","modifiers":[],"name":"one_or_undef","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::one_or_undef","qualifiedName":"LibTmux::Selection::one_or_undef","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":33,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one_or_undef($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":120,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-one_or_undef"},{"apiScope":"exported","doc":{"summary":"Return a fresh, unblessed array reference containing the same entity references. Editing its membership cannot corrupt graph adjacency or this selection. Captured entity values remain read-only through public readers."},"id":"LibTmux::Selection::to_array","kind":"method","modifiers":[],"name":"to_array","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::to_array","qualifiedName":"LibTmux::Selection::to_array","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub to_array($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":66,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-to_array"},{"apiScope":"exported","doc":{"summary":"`where($criteria_or_filter)` eagerly returns a new selection of the same concrete class in scalar, list, or void context. Complete validation precedes evaluation, including on empty input. See :obj:`\"new\" in LibTmux::Filter `. Order and duplicate occurrences are preserved."},"id":"LibTmux::Selection::where","kind":"method","modifiers":[],"name":"where","package":"LibTmux","parent":"LibTmux::Selection","product":"core","publicId":"LibTmux::Selection::where","qualifiedName":"LibTmux::Selection::where","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria"}],"raw":"sub where($self, $criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":48,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-selection-where"},{"apiScope":"exported","doc":{"body":"\n## SYNOPSIS\n\n\n```perl\n use v5.44;\n use LibTmux::Server;\n my $server = LibTmux::Server->new(socket_name => 'application');\n my $snapshot = $server->snapshot;\n my $pane = $snapshot->panes->first;\n say $server->capture_pane(pane => $pane) if defined $pane;\n```\n\n\n## CONTRACT\n\nConstruction and planning perform no I/O. Acquisition and mutation are explicit, bounded operations. Captured :obj:`LibTmux::Snapshot ` entities retain their observed graph; mutations do not refresh them. Acquire another snapshot to observe changes. Connection settings remain owned by the server wrapper; destroying it never kills a tmux daemon. See the [orchestration guide](https://github.com/libtmux/libtmux-perl/blob/master/docs/orchestration.md).\n\nPhysical entity targets accept stable ID strings or generation-checked handles. Session-relative window operations require :obj:`LibTmux::WindowLink `. Checks across subprocesses are optimistic rather than transactional. Single-quote session IDs such as `'$1'` to avoid interpolating a Perl capture variable.\n\n\n## ERRORS\n\nInvalid arguments throw :obj:`\"InvalidArgument\" in LibTmux::X ` before dispatch. Acquisition and checked commands propagate typed :obj:`LibTmux::X ` failures, including missing executables, absent daemons, vanished targets, stale handles, codec errors, timeouts, and output limits. Failures never become empty selections. Cancellation or a timeout after dispatch does not prove nonexecution or roll back effects.\n\n","summary":"Explicit tmux acquisition and commands","examples":[{"lang":"perl","code":"use v5.44;\nuse Config;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse LibTmuxFixture;\n\n# This complete demo owns a Linux child-reaping scope, including tmux panes.\nBEGIN {\n die 'Requires Linux x86_64 LP64'\n unless $^O eq 'linux'\n && $Config::Config{archname} =~ /x86_64/\n && $Config::Config{ptrsize} == 8\n && $Config::Config{ivsize} == 8;\n syscall(157, 36, 1, 0, 0, 0) == 0 or die \"subreaper: $!\";\n}\n\ntry {\n LibTmuxFixture->run(\n sub ($server, $root) {\n my $session = $server->new_session(\n name => 'demo',\n command => ['/bin/cat']\n );\n my $failure;\n try {\n my $editor = $session->window_links->one->window;\n $server->rename_window(window => $editor, name => 'editor');\n my $right = $server->split_pane(\n pane => $editor->panes->one,\n horizontal => true,\n command => ['/bin/cat']\n );\n my $logs = $server->new_window(\n session => $session,\n name => 'logs',\n command => ['/bin/cat']\n );\n $server->select_pane(pane => $right);\n my $snapshot = $server->snapshot;\n my $link = $snapshot->window_links->one(\n {\n window => {-is => {id => $logs->id}}\n }\n );\n $server->select_window(link => $link);\n $snapshot = $server->snapshot;\n\n for my $entry ($snapshot->sessions->@*) {\n say 'session ', $entry->name;\n for my $link ($entry->window_links->@*) {\n my $window = $link->window;\n my $ids = join ' ', map { $_->id } $window->panes->@*;\n my $label = $link->index . ':' . $window->name;\n say ' window ', $label, ': ', $ids;\n }\n }\n my $panes =\n $snapshot->windows->one({name => 'editor'})\n ->panes->where({width => {-gte => 1}})\n ->grep(sub ($pane) { $pane->height >= 1 });\n my $selected = $panes->one({active => true});\n die 'unexpected pane membership' unless $panes->count == 2;\n my $name = $selected->window->name;\n say $selected->id, ' is in window ', $name;\n }\n catch ($error) { $failure = $error }\n $server->kill_session(session => $session);\n die $failure if defined $failure;\n }\n );\n}\ncatch ($error) {\n warn \"tmux quickstart failed: $error\\n\";\n die $error;\n}\n","intro":"Complete installed-package program with an owned tmux fixture and result/cleanup assertions.","sourceUrl":"https://github.com/libtmux/libtmux-perl/blob/36b978c5eb6aa33873229046037e7d26136ca2cf/examples/quickstart.pl"}]},"id":"LibTmux::Server","kind":"class","modifiers":[],"name":"Server","package":"LibTmux","product":"core","publicId":"LibTmux::Server","qualifiedName":"LibTmux::Server","signatures":[{"params":[],"raw":"package LibTmux::Server;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server"},{"apiScope":"exported","doc":{"body":"Return a fresh literal argument array for a caller-owned interactive terminal without I/O. The session target is a stable ID string; obtain it through :obj:`\"id\" in LibTmux::Session `. The caller owns terminal/process setup and exit observation; the bounded capture transport does not allocate a TTY. Invalid inputs throw :obj:`\"InvalidArgument\" in LibTmux::X `.\n\n\n```perl\n my $argv = $server->attach_argv(session => '$1');\n```","summary":"`attach_argv(session => session_id)`."},"id":"LibTmux::Server::attach_argv","kind":"method","modifiers":[],"name":"attach_argv","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::attach_argv","qualifiedName":"LibTmux::Server::attach_argv","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub attach_argv($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":955,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-attach_argv"},{"apiScope":"exported","doc":{"body":"Perform ordered independent literal requests and return a fresh array reference of {result, error} records in input order. Each result is :obj:`LibTmux::CommandResult ` or undef; each dispatch error is the original typed :obj:`LibTmux::X ` or undef. Nonzero command exits stay raw results. An empty input returns an empty array without command I/O. Requests are attempted in order, without rollback or tmux command-list attribution.\n\n\n```perl\n my $results = $server->batch([['display-message', '-p', '#{version}']]);\n```","summary":"`batch(arrayref_of_argv)`."},"id":"LibTmux::Server::batch","kind":"method","modifiers":[],"name":"batch","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::batch","qualifiedName":"LibTmux::Server::batch","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"requests"}],"raw":"sub batch($self, $requests)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":951,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-batch"},{"apiScope":"exported","doc":{"body":"Read a :obj:`LibTmux::Pane ` and return raw terminal octets, including tmux's final newline. Optional start/end select native history rows; no UTF-8 replacement is performed. This I/O reads current observed content without waiting for application work. Command/transport failures propagate through :obj:`LibTmux::X `.\n\n\n```perl\n my $bytes = $server->capture_pane(pane => $pane, start => -20);\n```","summary":"`capture_pane(pane => Pane|pane_id, start => integer?, end => integer?)`."},"id":"LibTmux::Server::capture_pane","kind":"method","modifiers":[],"name":"capture_pane","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::capture_pane","qualifiedName":"LibTmux::Server::capture_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":29,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub capture_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1035,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-capture_pane"},{"apiScope":"exported","doc":{"body":"Acquire a graph and return its :obj:`LibTmux::ClientSelection `. A daemon without attached clients produces an empty selection. Membership is copied away from graph storage. Acquisition failures propagate through :obj:`LibTmux::X `; :obj:`\"detach_client\" ` changes client state explicitly.\n\n\n```perl\n my $clients = $server->clients;\n```","summary":"`clients()`."},"id":"LibTmux::Server::clients","kind":"method","modifiers":[],"name":"clients","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::clients","qualifiedName":"LibTmux::Server::clients","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":19}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub clients($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1054,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-clients"},{"apiScope":"exported","doc":{"body":"Perform one checked literal tmux command and return :obj:`LibTmux::CommandResult `. No shell wrapper or implicit tmux command list is used. Nonzero exits throw :obj:`\"Command\" in LibTmux::X ` or a more specific target/server error; transport failures propagate.\n\n\n```perl\n my $result = $server->cmd('display-message', '-p', '#{version}');\n```","summary":"`cmd(@literal_arguments)`."},"id":"LibTmux::Server::cmd","kind":"method","modifiers":[],"name":"cmd","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::cmd","qualifiedName":"LibTmux::Server::cmd","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":20,"kind":"parameter","parameter":0,"start":15}],"params":[{"name":"argv","variadic":"positional"}],"raw":"sub cmd($self, @argv)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":945,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-cmd"},{"apiScope":"exported","doc":{"body":"Delete the named daemon buffer loaded through :obj:`\"set_buffer\" `. Other daemon buffers remain untouched; later :obj:`\"show_buffer\" ` calls report absence as a command failure.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->delete_buffer(name => 'application');\n```","summary":"`delete_buffer(name => string)`."},"id":"LibTmux::Server::delete_buffer","kind":"method","modifiers":[],"name":"delete_buffer","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::delete_buffer","qualifiedName":"LibTmux::Server::delete_buffer","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub delete_buffer($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1097,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-delete_buffer"},{"apiScope":"exported","doc":{"body":"Request detachment of a captured :obj:`LibTmux::Client ` or explicit native client name. Command acceptance can precede client-process exit; callers owning an attached process must observe its exit separately.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->detach_client(client => $client);\n```","summary":"`detach_client(client => Client|client_name)`."},"id":"LibTmux::Server::detach_client","kind":"method","modifiers":[],"name":"detach_client","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::detach_client","qualifiedName":"LibTmux::Server::detach_client","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub detach_client($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1056,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-detach_client"},{"apiScope":"exported","doc":{"body":"Perform one raw command and return :obj:`LibTmux::CommandResult `, including nonzero exits. stdout and stderr remain separate octet strings. stdin is optional bytes; cancel_fh is borrowed and remains open. Transport failures throw typed :obj:`LibTmux::X ` with bounded partial output when available.\n\n\n```perl\n my $result = $server->execute(argv => ['list-sessions']);\n```","summary":"`execute(argv => arrayref, stdin => bytes?, timeout => seconds?, cancel_fh => handle?)`."},"id":"LibTmux::Server::execute","kind":"method","modifiers":[],"name":"execute","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::execute","qualifiedName":"LibTmux::Server::execute","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":19}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub execute($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":964,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-execute"},{"apiScope":"exported","doc":{"body":"Validate criteria and return an inspectable :obj:`LibTmux::QueryPlan ` without I/O or mutation. The plan records required fields/relations, source commands, residuals, and conditional daemon capability needs. Invalid criteria throw :obj:`\"InvalidFilter\" in LibTmux::X `. Executing :obj:`\"query_panes\" ` discovers the connected generation and capabilities.\n\n\n```perl\n my $plan = $server->explain_panes(where => {width => {-gte => 120}});\n```","summary":"`explain_panes(where => criteria|Filter, pushdown => policy?)`."},"id":"LibTmux::Server::explain_panes","kind":"method","modifiers":[],"name":"explain_panes","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::explain_panes","qualifiedName":"LibTmux::Server::explain_panes","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub explain_panes($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":983,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-explain_panes"},{"apiScope":"exported","doc":{"body":"Read a session/global variable and return its octets with the NAME= prefix and final record newline removed. Empty text and '0' remain values. Performs I/O; missing or explicitly unset variables throw :obj:`\"Command\" in LibTmux::X `. See :obj:`\"set_environment\" `.\n\n\n```perl\n my $value = $server->get_environment(session => $session->id, name => 'BUILD');\n```","summary":"`get_environment(name => env_name, session => session_id?)`."},"id":"LibTmux::Server::get_environment","kind":"method","modifiers":[],"name":"get_environment","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::get_environment","qualifiedName":"LibTmux::Server::get_environment","signatures":[{"methodKind":"call","nativeSyntax":[{"end":19,"kind":"name","start":4},{"end":32,"kind":"parameter","parameter":0,"start":27}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub get_environment($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1081,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-get_environment"},{"apiScope":"exported","doc":{"body":"Read an option and return octets with one output-record newline removed. Empty text and '0' remain values. inherited => true requests tmux's -A behavior; without it only the selected local level is queried. Performs I/O; missing values throw :obj:`\"Command\" in LibTmux::X `. See :obj:`\"set_option\" ` and :obj:`\"unset_option\" `.\n\n\n```perl\n my $value = $server->get_option(scope => 'window', target => $window->id, name => '@build');\n```","summary":"`get_option(name => string, scope => scope, target => id?, global => boolean?, inherited => boolean?)`."},"id":"LibTmux::Server::get_option","kind":"method","modifiers":[],"name":"get_option","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::get_option","qualifiedName":"LibTmux::Server::get_option","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub get_option($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1064,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-get_option"},{"apiScope":"exported","doc":{"body":"Destroy the selected :obj:`LibTmux::Pane `. Killing a window's final pane may destroy the physical window and its :obj:`LibTmux::WindowLink ` associations. Previously captured records remain readable observations.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->kill_pane(pane => $pane);\n```","summary":"`kill_pane(pane => Pane|pane_id)`."},"id":"LibTmux::Server::kill_pane","kind":"method","modifiers":[],"name":"kill_pane","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::kill_pane","qualifiedName":"LibTmux::Server::kill_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":21}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub kill_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1039,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-kill_pane"},{"apiScope":"exported","doc":{"body":"Explicitly request destruction of the connected tmux daemon. This method can affect a borrowed server and must be called intentionally; wrapper destruction never calls it. Successful command acceptance alone does not prove every daemon/client process exited.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->kill_server;\n```","summary":"`kill_server()`."},"id":"LibTmux::Server::kill_server","kind":"method","modifiers":[],"name":"kill_server","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::kill_server","qualifiedName":"LibTmux::Server::kill_server","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub kill_server($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1051,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-kill_server"},{"apiScope":"exported","doc":{"body":"Destroy the selected :obj:`LibTmux::Session ` and its links. Windows linked elsewhere can survive. Captured data remains local; later mutations through stale generation handles are checked.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->kill_session(session => $session);\n```","summary":"`kill_session(session => Session|session_id)`."},"id":"LibTmux::Server::kill_session","kind":"method","modifiers":[],"name":"kill_session","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::kill_session","qualifiedName":"LibTmux::Server::kill_session","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":29,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub kill_session($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1047,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-kill_session"},{"apiScope":"exported","doc":{"body":"Destroy the physical :obj:`LibTmux::Window ` and every :obj:`LibTmux::WindowLink ` referring to it. Use :obj:`\"unlink_window\" ` when removing one association is the intended effect.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->kill_window(window => $window);\n```","summary":"`kill_window(window => Window|window_id)`."},"id":"LibTmux::Server::kill_window","kind":"method","modifiers":[],"name":"kill_window","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::kill_window","qualifiedName":"LibTmux::Server::kill_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub kill_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1043,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-kill_window"},{"apiScope":"exported","doc":{"body":"Add an association from a physical :obj:`LibTmux::Window ` to a :obj:`LibTmux::Session `. index is optional; conflicts remain command failures. Existing associations are preserved. Inspect new :obj:`LibTmux::WindowLink ` records through :obj:`\"snapshot\" `.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->link_window(window => $window, session => $session, index => 4);\n```","summary":"`link_window(window => Window|window_id, session => Session|session_id, index => integer?)`."},"id":"LibTmux::Server::link_window","kind":"method","modifiers":[],"name":"link_window","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::link_window","qualifiedName":"LibTmux::Server::link_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub link_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":995,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-link_window"},{"apiScope":"exported","doc":{"body":"Perform acquisition and return a fresh unblessed array reference of contextual hash records in tmux order, preserving duplicate physical identities. kind is session, window, pane, or client. An attached-client listing can be empty. Records are detached values; :obj:`\"snapshot\" ` normalizes the graph. Acquisition/codec failures propagate through :obj:`LibTmux::X `.\n\n\n```perl\n my $rows = $server->listings('window');\n```","summary":"`listings(kind)`."},"id":"LibTmux::Server::listings","kind":"method","modifiers":[],"name":"listings","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::listings","qualifiedName":"LibTmux::Server::listings","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":20}],"params":[{"name":"kind"}],"raw":"sub listings($self, $kind)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":947,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-listings"},{"apiScope":"exported","doc":{"body":"Move one contextual :obj:`LibTmux::WindowLink ` into the destination session/index. Other links of the physical window keep their own associations. Use :obj:`\"link_window\" ` to add an association without moving one.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->move_window(link => $link, session => $session, index => 4);\n```","summary":"`move_window(link => WindowLink|session_id:index, session => Session|session_id, index => integer?)`."},"id":"LibTmux::Server::move_window","kind":"method","modifiers":[],"name":"move_window","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::move_window","qualifiedName":"LibTmux::Server::move_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub move_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1003,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-move_window"},{"apiScope":"exported","doc":{"body":"Return a new server wrapper without I/O. Select socket_name or socket_path, never both. Defaults are executable tmux, timeout 5 seconds, and an 8 MiB combined retained-output limit. env is copied; child processes clear ambient TMUX and TMUX_PANE. Invalid configuration throws :obj:`\"InvalidArgument\" in LibTmux::X `.\n\n\n```perl\n my $server = LibTmux::Server->new(socket_name => 'application');\n```","summary":"`new(executable => tmux, socket_name|socket_path => string, timeout => seconds, max_output => bytes, config_file => path, env => hashref)`."},"id":"LibTmux::Server::new","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::new","qualifiedName":"LibTmux::Server::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":21,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub new($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-new"},{"apiScope":"exported","doc":{"body":"Create a detached session and return its captured :obj:`LibTmux::Session `. command is a literal argument vector; shell_command explicitly requests a shell and is mutually exclusive. Omitting both uses tmux's default command. cwd is path octets; environment supplies NAME/value pairs to the first process. Performs I/O. If creation succeeds but acquisition fails, :obj:`\"Creation\" in LibTmux::X ` retains the known generation-scoped creation receipt and cause.\n\n\n```perl\n my $session = $server->new_session(name => 'application', command => ['/bin/cat']);\n```","summary":"`new_session(name => string, command => arrayref?, shell_command => string?, width => integer?, height => integer?, cwd => bytes?, environment => hashref?)`."},"id":"LibTmux::Server::new_session","kind":"method","modifiers":[],"name":"new_session","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::new_session","qualifiedName":"LibTmux::Server::new_session","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub new_session($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":966,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-new_session"},{"apiScope":"exported","doc":{"body":"Create a detached physical window in the selected session and return its captured :obj:`LibTmux::Window `. command, shell_command, cwd, and environment follow :obj:`\"new_session\" `. The new link uses tmux's next available index. Performs I/O; :obj:`\"Creation\" in LibTmux::X ` preserves known effects if subsequent acquisition fails.\n\n\n```perl\n my $window = $server->new_window(session => $session, name => 'logs', command => ['/bin/cat']);\n```","summary":"`new_window(session => Session|session_id, name => string?, command => arrayref?, shell_command => string?, cwd => bytes?, environment => hashref?)`."},"id":"LibTmux::Server::new_window","kind":"method","modifiers":[],"name":"new_window","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::new_window","qualifiedName":"LibTmux::Server::new_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub new_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":970,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-new_window"},{"apiScope":"exported","doc":{"body":"```perl\n my $operation = $server->operation('snapshot');\n```","summary":"`operation($name, %arguments)` validates and copies arguments, returning one :obj:`LibTmux::Operation ` without I/O. The optional Future facade shares this preparation and parsing boundary. Use the named methods above for synchronous execution. Invalid arguments or criteria throw :obj:`\"InvalidArgument\" in LibTmux::X ` or :obj:`\"InvalidFilter\" in LibTmux::X ` before submission."},"id":"LibTmux::Server::operation","kind":"method","modifiers":[],"name":"operation","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::operation","qualifiedName":"LibTmux::Server::operation","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":21},{"end":33,"kind":"parameter","parameter":1,"start":28}],"params":[{"name":"name"},{"name":"args","variadic":"keyword"}],"raw":"sub operation($self, $name, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":832,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-operation"},{"apiScope":"exported","doc":{"body":"Acquire and return a new :obj:`LibTmux::PaneSelection ` in captured physical-pane order. where accepts a hash reference or :obj:`LibTmux::Filter `. auto verifies safe scalar pruning and keeps residual evaluation local; never disables native filtering; require throws :obj:`\"Unsupported\" in LibTmux::X ` unless lowering is exact. native_filter is an exclusive expert escape hatch. Empty successful matches remain a typed selection; acquisition/evaluation failures propagate. See :obj:`\"explain_panes\" `.\n\n\n```perl\n my $panes = $server->query_panes(where => {active => true}, pushdown => 'auto');\n```","summary":"`query_panes(where => criteria|Filter?, pushdown => auto|never|require?, native_filter => string?)`."},"id":"LibTmux::Server::query_panes","kind":"method","modifiers":[],"name":"query_panes","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::query_panes","qualifiedName":"LibTmux::Server::query_panes","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub query_panes($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":979,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-query_panes"},{"apiScope":"exported","doc":{"body":"Rename the selected :obj:`LibTmux::Session ` using a literal name. Existing captured handles keep the old observed name; use :obj:`\"snapshot\" ` to observe the change.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->rename_session(session => $session, name => 'application');\n```","summary":"`rename_session(session => Session|session_id, name => string)`."},"id":"LibTmux::Server::rename_session","kind":"method","modifiers":[],"name":"rename_session","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::rename_session","qualifiedName":"LibTmux::Server::rename_session","signatures":[{"methodKind":"call","nativeSyntax":[{"end":18,"kind":"name","start":4},{"end":31,"kind":"parameter","parameter":0,"start":26}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub rename_session($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":987,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-rename_session"},{"apiScope":"exported","doc":{"body":"Rename the physical :obj:`LibTmux::Window ` across all its links. Names remain literal rather than expanding tmux formats. Captured handles keep their observed name.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->rename_window(window => $window, name => 'logs');\n```","summary":"`rename_window(window => Window|window_id, name => string)`."},"id":"LibTmux::Server::rename_window","kind":"method","modifiers":[],"name":"rename_window","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::rename_window","qualifiedName":"LibTmux::Server::rename_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub rename_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":991,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-rename_window"},{"apiScope":"exported","doc":{"body":"Resize a :obj:`LibTmux::Pane ` to the supplied positive width and/or height. tmux's layout constraints may affect the resulting dimensions; inspect another :obj:`LibTmux::Snapshot ` for observed values.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->resize_pane(pane => $pane, width => 100);\n```","summary":"`resize_pane(pane => Pane|pane_id, width => positive_integer?, height => positive_integer?)`."},"id":"LibTmux::Server::resize_pane","kind":"method","modifiers":[],"name":"resize_pane","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::resize_pane","qualifiedName":"LibTmux::Server::resize_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub resize_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1019,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-resize_pane"},{"apiScope":"exported","doc":{"body":"Apply an unambiguous predefined layout name or a checksum-prefixed native layout to a :obj:`LibTmux::Window `. Unknown or ambiguous predefined names throw :obj:`\"InvalidArgument\" in LibTmux::X ` before dispatch, including on tmux 3.3a. Native custom-layout validation remains tmux's responsibility.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->select_layout(window => $window, layout => 'tiled');\n```","summary":"`select_layout(window => Window|window_id, layout => string)`."},"id":"LibTmux::Server::select_layout","kind":"method","modifiers":[],"name":"select_layout","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::select_layout","qualifiedName":"LibTmux::Server::select_layout","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub select_layout($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1015,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-select_layout"},{"apiScope":"exported","doc":{"body":"Change the active :obj:`LibTmux::Pane ` of its physical window. This differs from selecting a session's :obj:`LibTmux::WindowLink `.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->select_pane(pane => $pane);\n```","summary":"`select_pane(pane => Pane|pane_id)`."},"id":"LibTmux::Server::select_pane","kind":"method","modifiers":[],"name":"select_pane","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::select_pane","qualifiedName":"LibTmux::Server::select_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub select_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1011,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-select_pane"},{"apiScope":"exported","doc":{"body":"Select a :obj:`LibTmux::WindowLink ` within its session. A physical window alone cannot identify session-relative active state. Capture again through :obj:`\"snapshot\" ` to observe the selected link.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->select_window(link => $link);\n```","summary":"`select_window(link => WindowLink|session_id:index)`."},"id":"LibTmux::Server::select_window","kind":"method","modifiers":[],"name":"select_window","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::select_window","qualifiedName":"LibTmux::Server::select_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub select_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1007,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-select_window"},{"apiScope":"exported","doc":{"body":"Send the array's named keys in order to a :obj:`LibTmux::Pane `. tmux interprets key names; arguments beginning with a dash remain key operands. An empty array sends no keys. Acceptance does not prove the pane application consumed input. Use :obj:`\"send_text\" ` for literal text.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->send_keys(pane => $pane, keys => ['Enter']);\n```","summary":"`send_keys(pane => Pane|pane_id, keys => arrayref)`."},"id":"LibTmux::Server::send_keys","kind":"method","modifiers":[],"name":"send_keys","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::send_keys","qualifiedName":"LibTmux::Server::send_keys","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":21}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub send_keys($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1027,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-send_keys"},{"apiScope":"exported","doc":{"body":"Send literal text/bytes to a :obj:`LibTmux::Pane `, then optionally send Enter. Empty text is permitted. Acceptance does not prove application completion. Use an application-specific observable handshake before relying on output; :obj:`\"capture_pane\" ` reads observed terminal content.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->send_text(pane => $pane, text => 'hello', enter => true);\n```","summary":"`send_text(pane => Pane|pane_id, text => string|bytes, enter => boolean?)`."},"id":"LibTmux::Server::send_text","kind":"method","modifiers":[],"name":"send_text","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::send_text","qualifiedName":"LibTmux::Server::send_text","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":21}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub send_text($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1031,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-send_text"},{"apiScope":"exported","doc":{"body":"Load a named tmux buffer through stdin bytes rather than interpolating data into a command. Empty data is permitted. :obj:`\"show_buffer\" ` retrieves bytes; buffer ownership remains in the daemon until :obj:`\"delete_buffer\" ` or an external change.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->set_buffer(name => 'application', data => \"a\\0b\");\n```","summary":"`set_buffer(name => string, data => bytes)`."},"id":"LibTmux::Server::set_buffer","kind":"method","modifiers":[],"name":"set_buffer","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::set_buffer","qualifiedName":"LibTmux::Server::set_buffer","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_buffer($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1089,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-set_buffer"},{"apiScope":"exported","doc":{"body":"Set a literal environment value for an explicit session ID, or globally when session is omitted. Empty text and '0' remain values. Existing pane processes are unaffected; creation-time environment belongs to :obj:`\"new_session\" `, :obj:`\"new_window\" `, and :obj:`\"split_pane\" `.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->set_environment(session => $session->id, name => 'BUILD', value => '0');\n```","summary":"`set_environment(name => env_name, value => bytes, session => session_id?)`."},"id":"LibTmux::Server::set_environment","kind":"method","modifiers":[],"name":"set_environment","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::set_environment","qualifiedName":"LibTmux::Server::set_environment","signatures":[{"methodKind":"call","nativeSyntax":[{"end":19,"kind":"name","start":4},{"end":32,"kind":"parameter","parameter":0,"start":27}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_environment($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1077,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-set_environment"},{"apiScope":"exported","doc":{"body":"Set a native hook or sparse hook[index] entry for an explicit session target or global scope. command is deliberately a tmux command string, unlike literal process argv. :obj:`\"show_hooks\" ` preserves native indexes/quoting rather than inventing a flattened hook list.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->set_hook(target => $session->id, name => 'after-select-window[3]', command => 'display-message hook');\n```","summary":"`set_hook(name => hook_or_hook[index], command => explicit_tmux_command_string, target => session_id?, global => boolean?)`."},"id":"LibTmux::Server::set_hook","kind":"method","modifiers":[],"name":"set_hook","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::set_hook","qualifiedName":"LibTmux::Server::set_hook","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":20}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_hook($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1071,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-set_hook"},{"apiScope":"exported","doc":{"body":"Set an option at explicit session/window/pane/server scope. Supply an exact target ID for local settings or global => true for the global level. Empty and zero values are preserved. :obj:`\"get_option\" ` controls whether inherited values participate.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->set_option(scope => 'window', target => $window->id, name => '@build', value => '0');\n```","summary":"`set_option(name => string, value => string|integer, scope => session|window|pane|server, target => id?, global => boolean?)`."},"id":"LibTmux::Server::set_option","kind":"method","modifiers":[],"name":"set_option","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::set_option","qualifiedName":"LibTmux::Server::set_option","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_option($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1060,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-set_option"},{"apiScope":"exported","doc":{"body":"Set a :obj:`LibTmux::Pane ` title. Literal input is protected from format expansion; tmux's own title sanitization remains observable in a new :obj:`LibTmux::Snapshot `.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->set_title(pane => $pane, title => 'build.v2');\n```","summary":"`set_title(pane => Pane|pane_id, title => string)`."},"id":"LibTmux::Server::set_title","kind":"method","modifiers":[],"name":"set_title","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::set_title","qualifiedName":"LibTmux::Server::set_title","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":21}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub set_title($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1023,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-set_title"},{"apiScope":"exported","doc":{"body":"Read a named tmux buffer and return raw octets, including embedded NUL bytes. Empty data remains an empty string. Performs I/O; a missing buffer throws :obj:`\"Command\" in LibTmux::X `. See :obj:`\"set_buffer\" `.\n\n\n```perl\n my $bytes = $server->show_buffer(name => 'application');\n```","summary":"`show_buffer(name => string)`."},"id":"LibTmux::Server::show_buffer","kind":"method","modifiers":[],"name":"show_buffer","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::show_buffer","qualifiedName":"LibTmux::Server::show_buffer","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":23}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub show_buffer($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1093,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-show_buffer"},{"apiScope":"exported","doc":{"body":"Read hooks and return raw octets preserving sparse indexes and tmux quoting. No hooks produce empty text. Performs I/O; failures propagate through :obj:`LibTmux::X `. See :obj:`\"set_hook\" ` for explicit command-string semantics.\n\n\n```perl\n my $hooks = $server->show_hooks(target => $session->id);\n```","summary":"`show_hooks(target => session_id?, global => boolean?)`."},"id":"LibTmux::Server::show_hooks","kind":"method","modifiers":[],"name":"show_hooks","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::show_hooks","qualifiedName":"LibTmux::Server::show_hooks","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub show_hooks($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1073,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-show_hooks"},{"apiScope":"exported","doc":{"body":"Perform strict graph acquisition and return :obj:`LibTmux::Snapshot `. Physical windows/panes appear once; :obj:`LibTmux::WindowLink ` retains each contextual association. Capture start/end describe an observation interval, not an atomic transaction. Acquisition, unsupported capabilities, and incomplete topology throw typed :obj:`LibTmux::X `; no partial snapshot is returned.\n\n\n```perl\n my $snapshot = $server->snapshot;\n```","summary":"`snapshot()`."},"id":"LibTmux::Server::snapshot","kind":"method","modifiers":[],"name":"snapshot","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::snapshot","qualifiedName":"LibTmux::Server::snapshot","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":20}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub snapshot($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":977,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-snapshot"},{"apiScope":"exported","doc":{"body":"Split the targeted pane and return the new captured :obj:`LibTmux::Pane `. horizontal selects side-by-side placement; false uses tmux's vertical split. command, shell_command, cwd, and environment follow :obj:`\"new_session\" `. Performs I/O; creation/acquisition failures follow :obj:`\"Creation\" in LibTmux::X `.\n\n\n```perl\n my $other = $server->split_pane(pane => $pane, horizontal => true, command => ['/bin/cat']);\n```","summary":"`split_pane(pane => Pane|pane_id, horizontal => boolean?, command => arrayref?, cwd => bytes?, environment => hashref?)`."},"id":"LibTmux::Server::split_pane","kind":"method","modifiers":[],"name":"split_pane","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::split_pane","qualifiedName":"LibTmux::Server::split_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub split_pane($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":974,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-split_pane"},{"apiScope":"exported","doc":{"body":"Remove exactly one :obj:`LibTmux::WindowLink `, given a captured link or session_id:index string. Removing the final link can destroy its physical window; other linked associations retain their context.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->unlink_window(link => $link);\n```","summary":"`unlink_window(link => WindowLink|session_id:index)`."},"id":"LibTmux::Server::unlink_window","kind":"method","modifiers":[],"name":"unlink_window","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::unlink_window","qualifiedName":"LibTmux::Server::unlink_window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub unlink_window($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":999,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-unlink_window"},{"apiScope":"exported","doc":{"body":"Unset the named session/global variable. This differs from setting an empty value; :obj:`\"get_environment\" ` reports the unset state as a command error.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->unset_environment(session => $session->id, name => 'BUILD');\n```","summary":"`unset_environment(name => env_name, session => session_id?)`."},"id":"LibTmux::Server::unset_environment","kind":"method","modifiers":[],"name":"unset_environment","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::unset_environment","qualifiedName":"LibTmux::Server::unset_environment","signatures":[{"methodKind":"call","nativeSyntax":[{"end":21,"kind":"name","start":4},{"end":34,"kind":"parameter","parameter":0,"start":29}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub unset_environment($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1085,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-unset_environment"},{"apiScope":"exported","doc":{"body":"Remove the selected local/global option so inheritance can take effect. Scope and target follow :obj:`\"set_option\" `; removing an override differs from assigning empty text.\n\nReturns `undef` after command acceptance. Performs I/O; failures propagate through :obj:`LibTmux::X `. Captured objects are not modified.\n\n\n```perl\n $server->unset_option(scope => 'window', target => $window->id, name => '@build');\n```","summary":"`unset_option(name => string, scope => scope, target => id?, global => boolean?)`."},"id":"LibTmux::Server::unset_option","kind":"method","modifiers":[],"name":"unset_option","package":"LibTmux","parent":"LibTmux::Server","product":"core","publicId":"LibTmux::Server::unset_option","qualifiedName":"LibTmux::Server::unset_option","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":29,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub unset_option($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Server.pm","line":1068,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-server-unset_option"},{"apiScope":"exported","doc":{"body":"\n## OWNERSHIP\n\nReaders use the retained graph and never refresh it. Acquire a new snapshot for new state. Inherited :obj:`to_record ` exports a detached scalar record.\n\n","summary":"Captured session entity"},"extends":["LibTmux::Entity"],"id":"LibTmux::Session","kind":"class","modifiers":[],"name":"Session","package":"LibTmux","product":"core","publicId":"LibTmux::Session","qualifiedName":"LibTmux::Session","signatures":[{"params":[],"raw":"package LibTmux::Session;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Session.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Session::attached","kind":"method","modifiers":[],"name":"attached","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::attached","qualifiedName":"LibTmux::Session::attached","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub attached($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Session.pm","line":5,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-attached"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Session::created","kind":"method","modifiers":[],"name":"created","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::created","qualifiedName":"LibTmux::Session::created","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub created($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Session.pm","line":6,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-created"},{"apiScope":"exported","doc":{"summary":"Return the captured generation. Restarted daemons cannot silently reuse this handle."},"id":"LibTmux::Session::generation","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"generation","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::generation","qualifiedName":"LibTmux::Session::generation","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub generation($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-generation"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Session::id","kind":"method","modifiers":[],"name":"id","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::id","qualifiedName":"LibTmux::Session::id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":6,"kind":"name","start":4}],"params":[],"raw":"sub id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Session.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-id"},{"apiScope":"exported","doc":{"summary":"Return an opaque identity key scoped by server, generation, kind, and string ID. It is suitable for local equality; duplicate selection occurrences remain separate occurrences."},"id":"LibTmux::Session::identity","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"identity","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::identity","qualifiedName":"LibTmux::Session::identity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub identity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-identity"},{"apiScope":"exported","doc":{"summary":"Return the schema entity-kind string. Concrete public field readers belong to :obj:`LibTmux::Pane `, :obj:`LibTmux::Window `, :obj:`LibTmux::WindowLink `, :obj:`LibTmux::Session `, and :obj:`LibTmux::Client `."},"id":"LibTmux::Session::kind","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"kind","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::kind","qualifiedName":"LibTmux::Session::kind","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub kind($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-kind"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Session::name","kind":"method","modifiers":[],"name":"name","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::name","qualifiedName":"LibTmux::Session::name","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub name($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Session.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-name"},{"apiScope":"exported","doc":{"summary":"bytes. Local captured data; no I/O."},"id":"LibTmux::Session::path","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::path","qualifiedName":"LibTmux::Session::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Session.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-path"},{"apiScope":"exported","doc":{"summary":"Return the captured server scope. No daemon discovery or refresh occurs."},"id":"LibTmux::Session::server_id","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"server_id","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::server_id","qualifiedName":"LibTmux::Session::server_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub server_id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-server_id"},{"apiScope":"exported","doc":{"summary":"Return a fresh hash reference of captured scalar fields and adjacency IDs. Editing it does not change the retained graph. Retaining the entity retains its captured graph, with no transport ownership or reference cycle."},"id":"LibTmux::Session::to_record","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"to_record","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::to_record","qualifiedName":"LibTmux::Session::to_record","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub to_record($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":21,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-to_record"},{"apiScope":"exported","doc":{"summary":":obj:`LibTmux::Selection ` of :obj:`LibTmux::WindowLink ` entities. Local captured data; no I/O."},"id":"LibTmux::Session::window_links","kind":"method","modifiers":[],"name":"window_links","package":"LibTmux","parent":"LibTmux::Session","product":"core","publicId":"LibTmux::Session::window_links","qualifiedName":"LibTmux::Session::window_links","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4}],"params":[],"raw":"sub window_links($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Session.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-session-window_links"},{"apiScope":"exported","doc":{"body":"\n## DESCRIPTION\n\nInherits the fixed-return local query API of :obj:`LibTmux::Selection `. Members must be defined :obj:`LibTmux::Session ` handles from one server generation. Empty instances still validate against the session schema. Native array edits are possible; query methods validate membership and never perform tmux I/O.\n\n","summary":"Native array selection of captured session entities"},"extends":["LibTmux::Selection"],"id":"LibTmux::SessionSelection","kind":"class","modifiers":[],"name":"SessionSelection","package":"LibTmux","product":"core","publicId":"LibTmux::SessionSelection","qualifiedName":"LibTmux::SessionSelection","signatures":[{"params":[],"raw":"package LibTmux::SessionSelection;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/SessionSelection.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection"},{"apiScope":"exported","doc":{"summary":"`count($criteria?)` returns an integer. Empty input returns zero. Validate all members before evaluating the optional criterion; count every matching occurrence, including duplicates."},"id":"LibTmux::SessionSelection::count","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::count","qualifiedName":"LibTmux::SessionSelection::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub count($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":77,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-count"},{"apiScope":"exported","doc":{"summary":"`exists($criteria?)` returns a native Boolean. Empty input returns false. After validating the entire membership, stop at the first matching entity. A reference itself remains true even when empty."},"id":"LibTmux::SessionSelection::exists","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"exists","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::exists","qualifiedName":"LibTmux::SessionSelection::exists","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub exists($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":85,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-exists"},{"apiScope":"exported","doc":{"summary":"`first($criteria?)` returns the first matching entity or undef. Input order determines first; after membership validation, later field reads may be skipped."},"id":"LibTmux::SessionSelection::first","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"first","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::first","qualifiedName":"LibTmux::SessionSelection::first","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub first($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":89,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-first"},{"apiScope":"exported","doc":{"summary":"`grep($callback)` returns a new same-class selection. Invoke the callback in scalar context with exactly one entity argument and a localized `$_`. Both bindings hold copies of the reference: assignment cannot replace a source slot. Restore `$_` and propagate the original thrown value even on failure. Predicates must not edit the traversed sequence."},"id":"LibTmux::SessionSelection::grep","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"grep","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::grep","qualifiedName":"LibTmux::SessionSelection::grep","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"callback"}],"raw":"sub grep($self, $callback)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":54,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-grep"},{"apiScope":"exported","doc":{"summary":"Return a fresh local cursor with a copy of current membership. Its `next` returns an entity or undef only at exhaustion. Later native array edits do not alter this traversal; the selection remains replayable."},"id":"LibTmux::SessionSelection::iterator","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"iterator","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::iterator","qualifiedName":"LibTmux::SessionSelection::iterator","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub iterator($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":122,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-iterator"},{"apiScope":"exported","doc":{"body":"Members may come from separate captures of the same server generation; each retains its own observation. Mixing servers or daemon generations throws :obj:`\"InvalidSelection\" in LibTmux::X `. Combining captures does not reconcile their times.","summary":"`new(@entities)` creates a concrete blessed array reference and validates every member. Construct an entity-specific selection such as :obj:`LibTmux::PaneSelection `; an empty instance retains that schema."},"id":"LibTmux::SessionSelection::new","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::new","qualifiedName":"LibTmux::SessionSelection::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":22,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"items","variadic":"positional"}],"raw":"sub new($class, @items)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-new"},{"apiScope":"exported","doc":{"summary":"`one($criteria?)` returns one entity. Zero throws :obj:`NoMatch `; a second occurrence throws :obj:`MultipleMatches `, reporting at least two and their IDs. Two occurrences of one identity are still ambiguous."},"id":"LibTmux::SessionSelection::one","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::one","qualifiedName":"LibTmux::SessionSelection::one","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":15}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":119,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-one"},{"apiScope":"exported","doc":{"summary":"`one_or_undef($criteria?)` returns an entity or undef for absence. A second matching occurrence still throws :obj:`MultipleMatches `."},"id":"LibTmux::SessionSelection::one_or_undef","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one_or_undef","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::one_or_undef","qualifiedName":"LibTmux::SessionSelection::one_or_undef","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":33,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one_or_undef($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":120,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-one_or_undef"},{"apiScope":"exported","doc":{"summary":"Return a fresh, unblessed array reference containing the same entity references. Editing its membership cannot corrupt graph adjacency or this selection. Captured entity values remain read-only through public readers."},"id":"LibTmux::SessionSelection::to_array","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"to_array","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::to_array","qualifiedName":"LibTmux::SessionSelection::to_array","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub to_array($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":66,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-to_array"},{"apiScope":"exported","doc":{"summary":"`where($criteria_or_filter)` eagerly returns a new selection of the same concrete class in scalar, list, or void context. Complete validation precedes evaluation, including on empty input. See :obj:`\"new\" in LibTmux::Filter `. Order and duplicate occurrences are preserved."},"id":"LibTmux::SessionSelection::where","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"where","package":"LibTmux","parent":"LibTmux::SessionSelection","product":"core","publicId":"LibTmux::SessionSelection::where","qualifiedName":"LibTmux::SessionSelection::where","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria"}],"raw":"sub where($self, $criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":48,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-sessionselection-where"},{"apiScope":"exported","doc":{"body":"\n## EXECUTION\n\nAll methods in this module operate on local captured data and perform no tmux I/O. Ordering is deterministic; public query methods do not mutate membership. Typed validation/evaluation errors propagate. See :obj:`\"snapshot\" in LibTmux::Server ` for explicit acquisition and :obj:`LibTmux::X ` for machine-readable failures.\n\n","summary":"Captured graph with explicit completeness"},"id":"LibTmux::Snapshot","kind":"class","modifiers":[],"name":"Snapshot","package":"LibTmux","product":"core","publicId":"LibTmux::Snapshot","qualifiedName":"LibTmux::Snapshot","signatures":[{"params":[],"raw":"package LibTmux::Snapshot;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot"},{"apiScope":"exported","doc":{"summary":"Return a fresh :obj:`LibTmux::ClientSelection ` in captured order. A loaded empty client set is valid."},"id":"LibTmux::Snapshot::clients","kind":"method","modifiers":[],"name":"clients","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::clients","qualifiedName":"LibTmux::Snapshot::clients","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub clients($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":209,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-clients"},{"apiScope":"exported","doc":{"summary":"Return the capture completeness Boolean. The strict live acquisition path fails on incomplete topology; it does not synthesize empty relations."},"id":"LibTmux::Snapshot::complete","kind":"method","modifiers":[],"name":"complete","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::complete","qualifiedName":"LibTmux::Snapshot::complete","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub complete($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":104,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-complete"},{"apiScope":"exported","doc":{"summary":"`from_records(server_id => ..., generation => ..., sessions => [...], windows => [...], window_links => [...], panes => [...], clients => [...])` constructs a detached graph. Scalar records and relation IDs are copied. Omitted fields/collections remain unloaded; null is explicit. Invalid identities or inconsistent complete topology throw typed acquisition errors."},"id":"LibTmux::Snapshot::from_records","kind":"method","modifiers":[],"name":"from_records","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::from_records","qualifiedName":"LibTmux::Snapshot::from_records","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":30,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub from_records($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":25,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-from_records"},{"apiScope":"exported","doc":{"summary":"Return the captured daemon generation. :obj:`LibTmux::Server ` checks it before mutations through captured handles; retained snapshots never silently refresh."},"id":"LibTmux::Snapshot::generation","kind":"method","modifiers":[],"name":"generation","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::generation","qualifiedName":"LibTmux::Snapshot::generation","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub generation($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":103,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-generation"},{"apiScope":"exported","doc":{"summary":"Return a fresh metadata hash with capture start/end, daemon version, and PID where acquired. Several commands observe an interval; the snapshot is not an atomic tmux transaction."},"id":"LibTmux::Snapshot::metadata","kind":"method","modifiers":[],"name":"metadata","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::metadata","qualifiedName":"LibTmux::Snapshot::metadata","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub metadata($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":105,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-metadata"},{"apiScope":"exported","doc":{"summary":"`pane_by_id('%3')` returns a :obj:`LibTmux::Pane ` or undef. The returned handle retains the captured graph after this wrapper goes out of scope."},"id":"LibTmux::Snapshot::pane_by_id","kind":"method","modifiers":[],"name":"pane_by_id","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::pane_by_id","qualifiedName":"LibTmux::Snapshot::pane_by_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"id"}],"raw":"sub pane_by_id($self, $id)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":212,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-pane_by_id"},{"apiScope":"exported","doc":{"summary":"Return a fresh :obj:`LibTmux::PaneSelection ` containing each physical pane identity once. Membership edits cannot change the graph store."},"id":"LibTmux::Snapshot::panes","kind":"method","modifiers":[],"name":"panes","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::panes","qualifiedName":"LibTmux::Snapshot::panes","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub panes($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":208,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-panes"},{"apiScope":"exported","doc":{"summary":"Return the captured server scope. Entity IDs are meaningful only within this scope and :obj:`\"generation\" `."},"id":"LibTmux::Snapshot::server_id","kind":"method","modifiers":[],"name":"server_id","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::server_id","qualifiedName":"LibTmux::Snapshot::server_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub server_id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":102,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-server_id"},{"apiScope":"exported","doc":{"summary":"`session_by_id('$1')` returns a :obj:`LibTmux::Session ` or undef. Single quotes preserve the dollar-prefixed ID instead of interpolating a regex capture."},"id":"LibTmux::Snapshot::session_by_id","kind":"method","modifiers":[],"name":"session_by_id","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::session_by_id","qualifiedName":"LibTmux::Snapshot::session_by_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":17,"kind":"name","start":4},{"end":28,"kind":"parameter","parameter":0,"start":25}],"params":[{"name":"id"}],"raw":"sub session_by_id($self, $id)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":210,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-session_by_id"},{"apiScope":"exported","doc":{"summary":"Return a fresh :obj:`LibTmux::SessionSelection ` in captured order. Empty loaded collections yield empty selections; unloaded collections throw."},"id":"LibTmux::Snapshot::sessions","kind":"method","modifiers":[],"name":"sessions","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::sessions","qualifiedName":"LibTmux::Snapshot::sessions","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub sessions($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":205,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-sessions"},{"apiScope":"exported","doc":{"summary":"Return independent scalar records and adjacency IDs for detached use. No handles or live transport are serialized."},"id":"LibTmux::Snapshot::to_records","kind":"method","modifiers":[],"name":"to_records","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::to_records","qualifiedName":"LibTmux::Snapshot::to_records","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub to_records($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":214,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-to_records"},{"apiScope":"exported","doc":{"summary":"`window_by_id('@3')` returns one physical :obj:`LibTmux::Window ` or undef, independent of session link context."},"id":"LibTmux::Snapshot::window_by_id","kind":"method","modifiers":[],"name":"window_by_id","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::window_by_id","qualifiedName":"LibTmux::Snapshot::window_by_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"id"}],"raw":"sub window_by_id($self, $id)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":211,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-window_by_id"},{"apiScope":"exported","doc":{"summary":"Return a fresh :obj:`LibTmux::WindowLinkSelection ` retaining every session/index association, including repeated links of one physical window."},"id":"LibTmux::Snapshot::window_links","kind":"method","modifiers":[],"name":"window_links","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::window_links","qualifiedName":"LibTmux::Snapshot::window_links","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4}],"params":[],"raw":"sub window_links($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":207,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-window_links"},{"apiScope":"exported","doc":{"summary":"Return a fresh :obj:`LibTmux::WindowSelection ` containing each physical window identity once. Context lives in :obj:`\"window_links\" `."},"id":"LibTmux::Snapshot::windows","kind":"method","modifiers":[],"name":"windows","package":"LibTmux","parent":"LibTmux::Snapshot","product":"core","publicId":"LibTmux::Snapshot::windows","qualifiedName":"LibTmux::Snapshot::windows","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub windows($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Snapshot.pm","line":206,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-snapshot-windows"},{"apiScope":"exported","doc":{"body":"\n## RESULTS\n\nLibTmux::CommandResult exposes stdout, stderr, exit_code, signal, raw_status, and success. Output remains octets.\n\nThe private supervisor owns program signals/groups and reaps the program. Application SIGCHLD handlers remain intact; SIGCHLD=IGNORE is refused. Cancellation handles are borrowed and remain open. Cancellation after release can have effects and never implies rollback. Parent death triggers cleanup.\n\n","summary":"Supervised literal process execution"},"id":"LibTmux::Transport","kind":"class","modifiers":[],"name":"Transport","package":"LibTmux","product":"core","publicId":"LibTmux::Transport","qualifiedName":"LibTmux::Transport","signatures":[{"params":[],"raw":"package LibTmux::Transport;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Transport.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-transport"},{"apiScope":"exported","doc":{"summary":"`run(argv => [...], stdin => $octets, timeout => $seconds, max_output => $bytes, cancel_fh => $handle)` returns a CommandResult. Stdout/stderr are separate octet strings. Nonzero exits are results; spawn, timeout, cancellation, output limits, and supervision failures are typed errors."},"id":"LibTmux::Transport::run","kind":"method","modifiers":[],"name":"run","package":"LibTmux","parent":"LibTmux::Transport","product":"core","publicId":"LibTmux::Transport::run","qualifiedName":"LibTmux::Transport::run","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":21,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub run($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Transport.pm","line":100,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-transport-run"},{"apiScope":"exported","doc":{"summary":"Return a :obj:`LibTmux::ProcessJob ` for an executor adapter."},"id":"LibTmux::Transport::start","kind":"method","modifiers":[],"name":"start","package":"LibTmux","parent":"LibTmux::Transport","product":"core","publicId":"LibTmux::Transport::start","qualifiedName":"LibTmux::Transport::start","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":23,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub start($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Transport.pm","line":96,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-transport-start"},{"apiScope":"exported","doc":{"body":"\n## OWNERSHIP\n\nReaders use the retained graph and never refresh it. Acquire a new snapshot for new state. Inherited :obj:`to_record ` exports a detached scalar record.\n\n","summary":"Captured window entity"},"extends":["LibTmux::Entity"],"id":"LibTmux::Window","kind":"class","modifiers":[],"name":"Window","package":"LibTmux","product":"core","publicId":"LibTmux::Window","qualifiedName":"LibTmux::Window","signatures":[{"params":[],"raw":"package LibTmux::Window;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Window.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window"},{"apiScope":"exported","doc":{"summary":":obj:`LibTmux::Pane ` entity or undef. Local captured data; no I/O."},"id":"LibTmux::Window::active_pane","kind":"method","modifiers":[],"name":"active_pane","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::active_pane","qualifiedName":"LibTmux::Window::active_pane","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub active_pane($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Window.pm","line":5,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-active_pane"},{"apiScope":"exported","doc":{"summary":"Return the captured generation. Restarted daemons cannot silently reuse this handle."},"id":"LibTmux::Window::generation","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"generation","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::generation","qualifiedName":"LibTmux::Window::generation","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub generation($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-generation"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Window::height","kind":"method","modifiers":[],"name":"height","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::height","qualifiedName":"LibTmux::Window::height","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub height($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Window.pm","line":6,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-height"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Window::id","kind":"method","modifiers":[],"name":"id","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::id","qualifiedName":"LibTmux::Window::id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":6,"kind":"name","start":4}],"params":[],"raw":"sub id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Window.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-id"},{"apiScope":"exported","doc":{"summary":"Return an opaque identity key scoped by server, generation, kind, and string ID. It is suitable for local equality; duplicate selection occurrences remain separate occurrences."},"id":"LibTmux::Window::identity","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"identity","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::identity","qualifiedName":"LibTmux::Window::identity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub identity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-identity"},{"apiScope":"exported","doc":{"summary":"Return the schema entity-kind string. Concrete public field readers belong to :obj:`LibTmux::Pane `, :obj:`LibTmux::Window `, :obj:`LibTmux::WindowLink `, :obj:`LibTmux::Session `, and :obj:`LibTmux::Client `."},"id":"LibTmux::Window::kind","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"kind","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::kind","qualifiedName":"LibTmux::Window::kind","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub kind($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-kind"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Window::layout","kind":"method","modifiers":[],"name":"layout","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::layout","qualifiedName":"LibTmux::Window::layout","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub layout($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Window.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-layout"},{"apiScope":"exported","doc":{"summary":":obj:`LibTmux::Selection ` of :obj:`LibTmux::WindowLink ` entities. Local captured data; no I/O."},"id":"LibTmux::Window::links","kind":"method","modifiers":[],"name":"links","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::links","qualifiedName":"LibTmux::Window::links","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub links($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Window.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-links"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::Window::name","kind":"method","modifiers":[],"name":"name","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::name","qualifiedName":"LibTmux::Window::name","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub name($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Window.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-name"},{"apiScope":"exported","doc":{"summary":":obj:`LibTmux::Selection ` of :obj:`LibTmux::Pane ` entities. Local captured data; no I/O."},"id":"LibTmux::Window::panes","kind":"method","modifiers":[],"name":"panes","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::panes","qualifiedName":"LibTmux::Window::panes","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub panes($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Window.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-panes"},{"apiScope":"exported","doc":{"summary":"Return the captured server scope. No daemon discovery or refresh occurs."},"id":"LibTmux::Window::server_id","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"server_id","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::server_id","qualifiedName":"LibTmux::Window::server_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub server_id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-server_id"},{"apiScope":"exported","doc":{"summary":"Return a fresh hash reference of captured scalar fields and adjacency IDs. Editing it does not change the retained graph. Retaining the entity retains its captured graph, with no transport ownership or reference cycle."},"id":"LibTmux::Window::to_record","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"to_record","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::to_record","qualifiedName":"LibTmux::Window::to_record","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub to_record($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":21,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-to_record"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::Window::width","kind":"method","modifiers":[],"name":"width","package":"LibTmux","parent":"LibTmux::Window","product":"core","publicId":"LibTmux::Window::width","qualifiedName":"LibTmux::Window::width","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub width($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Window.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-window-width"},{"apiScope":"exported","doc":{"body":"\n## OWNERSHIP\n\nReaders use the retained graph and never refresh it. Acquire a new snapshot for new state. Inherited :obj:`to_record ` exports a detached scalar record.\n\n","summary":"Captured window_link entity"},"extends":["LibTmux::Entity"],"id":"LibTmux::WindowLink","kind":"class","modifiers":[],"name":"WindowLink","package":"LibTmux","product":"core","publicId":"LibTmux::WindowLink","qualifiedName":"LibTmux::WindowLink","signatures":[{"params":[],"raw":"package LibTmux::WindowLink;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/WindowLink.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink"},{"apiScope":"exported","doc":{"summary":"boolean. Local captured data; no I/O."},"id":"LibTmux::WindowLink::active","kind":"method","modifiers":[],"name":"active","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::active","qualifiedName":"LibTmux::WindowLink::active","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub active($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/WindowLink.pm","line":5,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-active"},{"apiScope":"exported","doc":{"summary":"Return the captured generation. Restarted daemons cannot silently reuse this handle."},"id":"LibTmux::WindowLink::generation","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"generation","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::generation","qualifiedName":"LibTmux::WindowLink::generation","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub generation($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-generation"},{"apiScope":"exported","doc":{"summary":"string. Local captured data; no I/O."},"id":"LibTmux::WindowLink::id","kind":"method","modifiers":[],"name":"id","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::id","qualifiedName":"LibTmux::WindowLink::id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":6,"kind":"name","start":4}],"params":[],"raw":"sub id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/WindowLink.pm","line":6,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-id"},{"apiScope":"exported","doc":{"summary":"Return an opaque identity key scoped by server, generation, kind, and string ID. It is suitable for local equality; duplicate selection occurrences remain separate occurrences."},"id":"LibTmux::WindowLink::identity","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"identity","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::identity","qualifiedName":"LibTmux::WindowLink::identity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub identity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-identity"},{"apiScope":"exported","doc":{"summary":"integer. Local captured data; no I/O."},"id":"LibTmux::WindowLink::index","kind":"method","modifiers":[],"name":"index","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::index","qualifiedName":"LibTmux::WindowLink::index","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub index($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/WindowLink.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-index"},{"apiScope":"exported","doc":{"summary":"Return the schema entity-kind string. Concrete public field readers belong to :obj:`LibTmux::Pane `, :obj:`LibTmux::Window `, :obj:`LibTmux::WindowLink `, :obj:`LibTmux::Session `, and :obj:`LibTmux::Client `."},"id":"LibTmux::WindowLink::kind","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"kind","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::kind","qualifiedName":"LibTmux::WindowLink::kind","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub kind($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-kind"},{"apiScope":"exported","doc":{"summary":"Return the captured server scope. No daemon discovery or refresh occurs."},"id":"LibTmux::WindowLink::server_id","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"server_id","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::server_id","qualifiedName":"LibTmux::WindowLink::server_id","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub server_id($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-server_id"},{"apiScope":"exported","doc":{"summary":":obj:`LibTmux::Session ` entity. Local captured data; no I/O."},"id":"LibTmux::WindowLink::session","kind":"method","modifiers":[],"name":"session","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::session","qualifiedName":"LibTmux::WindowLink::session","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub session($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/WindowLink.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-session"},{"apiScope":"exported","doc":{"summary":"Return a fresh hash reference of captured scalar fields and adjacency IDs. Editing it does not change the retained graph. Retaining the entity retains its captured graph, with no transport ownership or reference cycle."},"id":"LibTmux::WindowLink::to_record","inheritedFrom":"LibTmux::Entity","kind":"method","modifiers":[],"name":"to_record","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::to_record","qualifiedName":"LibTmux::WindowLink::to_record","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4}],"params":[],"raw":"sub to_record($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Entity.pm","line":21,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-to_record"},{"apiScope":"exported","doc":{"summary":":obj:`LibTmux::Window ` entity. Local captured data; no I/O."},"id":"LibTmux::WindowLink::window","kind":"method","modifiers":[],"name":"window","package":"LibTmux","parent":"LibTmux::WindowLink","product":"core","publicId":"LibTmux::WindowLink::window","qualifiedName":"LibTmux::WindowLink::window","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub window($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/WindowLink.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlink-window"},{"apiScope":"exported","doc":{"body":"\n## DESCRIPTION\n\nInherits the fixed-return local query API of :obj:`LibTmux::Selection `. Members must be defined :obj:`LibTmux::WindowLink ` handles from one server generation. Empty instances still validate against the window_link schema. Native array edits are possible; query methods validate membership and never perform tmux I/O.\n\n","summary":"Native array selection of captured window_link entities"},"extends":["LibTmux::Selection"],"id":"LibTmux::WindowLinkSelection","kind":"class","modifiers":[],"name":"WindowLinkSelection","package":"LibTmux","product":"core","publicId":"LibTmux::WindowLinkSelection","qualifiedName":"LibTmux::WindowLinkSelection","signatures":[{"params":[],"raw":"package LibTmux::WindowLinkSelection;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/WindowLinkSelection.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection"},{"apiScope":"exported","doc":{"summary":"`count($criteria?)` returns an integer. Empty input returns zero. Validate all members before evaluating the optional criterion; count every matching occurrence, including duplicates."},"id":"LibTmux::WindowLinkSelection::count","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::count","qualifiedName":"LibTmux::WindowLinkSelection::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub count($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":77,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-count"},{"apiScope":"exported","doc":{"summary":"`exists($criteria?)` returns a native Boolean. Empty input returns false. After validating the entire membership, stop at the first matching entity. A reference itself remains true even when empty."},"id":"LibTmux::WindowLinkSelection::exists","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"exists","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::exists","qualifiedName":"LibTmux::WindowLinkSelection::exists","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub exists($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":85,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-exists"},{"apiScope":"exported","doc":{"summary":"`first($criteria?)` returns the first matching entity or undef. Input order determines first; after membership validation, later field reads may be skipped."},"id":"LibTmux::WindowLinkSelection::first","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"first","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::first","qualifiedName":"LibTmux::WindowLinkSelection::first","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub first($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":89,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-first"},{"apiScope":"exported","doc":{"summary":"`grep($callback)` returns a new same-class selection. Invoke the callback in scalar context with exactly one entity argument and a localized `$_`. Both bindings hold copies of the reference: assignment cannot replace a source slot. Restore `$_` and propagate the original thrown value even on failure. Predicates must not edit the traversed sequence."},"id":"LibTmux::WindowLinkSelection::grep","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"grep","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::grep","qualifiedName":"LibTmux::WindowLinkSelection::grep","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"callback"}],"raw":"sub grep($self, $callback)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":54,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-grep"},{"apiScope":"exported","doc":{"summary":"Return a fresh local cursor with a copy of current membership. Its `next` returns an entity or undef only at exhaustion. Later native array edits do not alter this traversal; the selection remains replayable."},"id":"LibTmux::WindowLinkSelection::iterator","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"iterator","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::iterator","qualifiedName":"LibTmux::WindowLinkSelection::iterator","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub iterator($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":122,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-iterator"},{"apiScope":"exported","doc":{"body":"Members may come from separate captures of the same server generation; each retains its own observation. Mixing servers or daemon generations throws :obj:`\"InvalidSelection\" in LibTmux::X `. Combining captures does not reconcile their times.","summary":"`new(@entities)` creates a concrete blessed array reference and validates every member. Construct an entity-specific selection such as :obj:`LibTmux::PaneSelection `; an empty instance retains that schema."},"id":"LibTmux::WindowLinkSelection::new","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::new","qualifiedName":"LibTmux::WindowLinkSelection::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":22,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"items","variadic":"positional"}],"raw":"sub new($class, @items)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-new"},{"apiScope":"exported","doc":{"summary":"`one($criteria?)` returns one entity. Zero throws :obj:`NoMatch `; a second occurrence throws :obj:`MultipleMatches `, reporting at least two and their IDs. Two occurrences of one identity are still ambiguous."},"id":"LibTmux::WindowLinkSelection::one","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::one","qualifiedName":"LibTmux::WindowLinkSelection::one","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":15}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":119,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-one"},{"apiScope":"exported","doc":{"summary":"`one_or_undef($criteria?)` returns an entity or undef for absence. A second matching occurrence still throws :obj:`MultipleMatches `."},"id":"LibTmux::WindowLinkSelection::one_or_undef","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one_or_undef","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::one_or_undef","qualifiedName":"LibTmux::WindowLinkSelection::one_or_undef","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":33,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one_or_undef($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":120,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-one_or_undef"},{"apiScope":"exported","doc":{"summary":"Return a fresh, unblessed array reference containing the same entity references. Editing its membership cannot corrupt graph adjacency or this selection. Captured entity values remain read-only through public readers."},"id":"LibTmux::WindowLinkSelection::to_array","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"to_array","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::to_array","qualifiedName":"LibTmux::WindowLinkSelection::to_array","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub to_array($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":66,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-to_array"},{"apiScope":"exported","doc":{"summary":"`where($criteria_or_filter)` eagerly returns a new selection of the same concrete class in scalar, list, or void context. Complete validation precedes evaluation, including on empty input. See :obj:`\"new\" in LibTmux::Filter `. Order and duplicate occurrences are preserved."},"id":"LibTmux::WindowLinkSelection::where","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"where","package":"LibTmux","parent":"LibTmux::WindowLinkSelection","product":"core","publicId":"LibTmux::WindowLinkSelection::where","qualifiedName":"LibTmux::WindowLinkSelection::where","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria"}],"raw":"sub where($self, $criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":48,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowlinkselection-where"},{"apiScope":"exported","doc":{"body":"\n## DESCRIPTION\n\nInherits the fixed-return local query API of :obj:`LibTmux::Selection `. Members must be defined :obj:`LibTmux::Window ` handles from one server generation. Empty instances still validate against the window schema. Native array edits are possible; query methods validate membership and never perform tmux I/O.\n\n","summary":"Native array selection of captured window entities"},"extends":["LibTmux::Selection"],"id":"LibTmux::WindowSelection","kind":"class","modifiers":[],"name":"WindowSelection","package":"LibTmux","product":"core","publicId":"LibTmux::WindowSelection","qualifiedName":"LibTmux::WindowSelection","signatures":[{"params":[],"raw":"package LibTmux::WindowSelection;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/WindowSelection.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection"},{"apiScope":"exported","doc":{"summary":"`count($criteria?)` returns an integer. Empty input returns zero. Validate all members before evaluating the optional criterion; count every matching occurrence, including duplicates."},"id":"LibTmux::WindowSelection::count","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::count","qualifiedName":"LibTmux::WindowSelection::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub count($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":77,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-count"},{"apiScope":"exported","doc":{"summary":"`exists($criteria?)` returns a native Boolean. Empty input returns false. After validating the entire membership, stop at the first matching entity. A reference itself remains true even when empty."},"id":"LibTmux::WindowSelection::exists","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"exists","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::exists","qualifiedName":"LibTmux::WindowSelection::exists","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub exists($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":85,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-exists"},{"apiScope":"exported","doc":{"summary":"`first($criteria?)` returns the first matching entity or undef. Input order determines first; after membership validation, later field reads may be skipped."},"id":"LibTmux::WindowSelection::first","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"first","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::first","qualifiedName":"LibTmux::WindowSelection::first","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub first($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":89,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-first"},{"apiScope":"exported","doc":{"summary":"`grep($callback)` returns a new same-class selection. Invoke the callback in scalar context with exactly one entity argument and a localized `$_`. Both bindings hold copies of the reference: assignment cannot replace a source slot. Restore `$_` and propagate the original thrown value even on failure. Predicates must not edit the traversed sequence."},"id":"LibTmux::WindowSelection::grep","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"grep","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::grep","qualifiedName":"LibTmux::WindowSelection::grep","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4},{"end":25,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"callback"}],"raw":"sub grep($self, $callback)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":54,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-grep"},{"apiScope":"exported","doc":{"summary":"Return a fresh local cursor with a copy of current membership. Its `next` returns an entity or undef only at exhaustion. Later native array edits do not alter this traversal; the selection remains replayable."},"id":"LibTmux::WindowSelection::iterator","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"iterator","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::iterator","qualifiedName":"LibTmux::WindowSelection::iterator","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub iterator($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":122,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-iterator"},{"apiScope":"exported","doc":{"body":"Members may come from separate captures of the same server generation; each retains its own observation. Mixing servers or daemon generations throws :obj:`\"InvalidSelection\" in LibTmux::X `. Combining captures does not reconcile their times.","summary":"`new(@entities)` creates a concrete blessed array reference and validates every member. Construct an entity-specific selection such as :obj:`LibTmux::PaneSelection `; an empty instance retains that schema."},"id":"LibTmux::WindowSelection::new","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::new","qualifiedName":"LibTmux::WindowSelection::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":22,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"items","variadic":"positional"}],"raw":"sub new($class, @items)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-new"},{"apiScope":"exported","doc":{"summary":"`one($criteria?)` returns one entity. Zero throws :obj:`NoMatch `; a second occurrence throws :obj:`MultipleMatches `, reporting at least two and their IDs. Two occurrences of one identity are still ambiguous."},"id":"LibTmux::WindowSelection::one","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::one","qualifiedName":"LibTmux::WindowSelection::one","signatures":[{"methodKind":"call","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":15}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":119,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-one"},{"apiScope":"exported","doc":{"summary":"`one_or_undef($criteria?)` returns an entity or undef for absence. A second matching occurrence still throws :obj:`MultipleMatches `."},"id":"LibTmux::WindowSelection::one_or_undef","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"one_or_undef","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::one_or_undef","qualifiedName":"LibTmux::WindowSelection::one_or_undef","signatures":[{"methodKind":"call","nativeSyntax":[{"end":16,"kind":"name","start":4},{"end":33,"kind":"parameter","parameter":0,"start":24}],"params":[{"name":"criteria","variadic":"positional"}],"raw":"sub one_or_undef($self, @criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":120,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-one_or_undef"},{"apiScope":"exported","doc":{"summary":"Return a fresh, unblessed array reference containing the same entity references. Editing its membership cannot corrupt graph adjacency or this selection. Captured entity values remain read-only through public readers."},"id":"LibTmux::WindowSelection::to_array","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"to_array","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::to_array","qualifiedName":"LibTmux::WindowSelection::to_array","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub to_array($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":66,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-to_array"},{"apiScope":"exported","doc":{"summary":"`where($criteria_or_filter)` eagerly returns a new selection of the same concrete class in scalar, list, or void context. Complete validation precedes evaluation, including on empty input. See :obj:`\"new\" in LibTmux::Filter `. Order and duplicate occurrences are preserved."},"id":"LibTmux::WindowSelection::where","inheritedFrom":"LibTmux::Selection","kind":"method","modifiers":[],"name":"where","package":"LibTmux","parent":"LibTmux::WindowSelection","product":"core","publicId":"LibTmux::WindowSelection::where","qualifiedName":"LibTmux::WindowSelection::where","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":17}],"params":[{"name":"criteria"}],"raw":"sub where($self, $criteria)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/Selection.pm","line":48,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-windowselection-where"},{"apiScope":"exported","doc":{"body":"\n## SYNOPSIS\n\n\n```perl\n use LibTmux::Workspace;\n my $workspace = LibTmux::Workspace->from_json($json_octets);\n my $plan = $workspace->plan(existing => 'error');\n my $report = $workspace->load(server => $server);\n```\n\n\n## COMMAND LINE\n\nThe packaged `libtmux-workspace` executable exposes `validate`, `plan`, and `load`. `--dry-run` selects planning without tmux I/O. See the installed executable's help for socket and repeat-application options.\n\n","summary":"Versioned JSON configuration and owned orchestration"},"id":"LibTmux::Workspace","kind":"class","modifiers":[],"name":"Workspace","package":"LibTmux-Workspace","product":"workspace","publicId":"LibTmux::Workspace","qualifiedName":"LibTmux::Workspace","signatures":[{"params":[],"raw":"package LibTmux::Workspace;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace"},{"apiScope":"exported","doc":{"body":"\n## EXCEPTIONS\n\n","summary":"Workspace configuration and partial-load failures"},"id":"LibTmux::Workspace::X","kind":"class","modifiers":[],"name":"X","package":"LibTmux-Workspace","product":"workspace","publicId":"LibTmux::Workspace::X","qualifiedName":"LibTmux::Workspace::X","signatures":[{"params":[],"raw":"package LibTmux::Workspace::X;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace/X.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x"},{"apiScope":"exported","doc":{"summary":"Invalid versioned configuration. `path` identifies the rejected input."},"extends":["LibTmux::X"],"id":"LibTmux::Workspace::X::Config","kind":"exception","modifiers":[],"name":"Config","package":"LibTmux-Workspace","product":"workspace","publicId":"LibTmux::Workspace::X::Config","qualifiedName":"LibTmux::Workspace::X::Config","signatures":[{"params":[],"raw":"package LibTmux::Workspace::X::Config;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace/X.pm","line":5,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::Workspace::X::Config::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::count","qualifiedName":"LibTmux::Workspace::X::Config::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::Workspace::X::Config::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::details","qualifiedName":"LibTmux::Workspace::X::Config::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::Workspace::X::Config::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::dispatched","qualifiedName":"LibTmux::Workspace::X::Config::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::Workspace::X::Config::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::entity","qualifiedName":"LibTmux::Workspace::X::Config::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::Workspace::X::Config::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::expected","qualifiedName":"LibTmux::Workspace::X::Config::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::Workspace::X::Config::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::matched_ids","qualifiedName":"LibTmux::Workspace::X::Config::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::Workspace::X::Config::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::message","qualifiedName":"LibTmux::Workspace::X::Config::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::Workspace::X::Config::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::new","qualifiedName":"LibTmux::Workspace::X::Config::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::Workspace::X::Config::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::path","qualifiedName":"LibTmux::Workspace::X::Config::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::Workspace::X::Config::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::received","qualifiedName":"LibTmux::Workspace::X::Config::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::Workspace::X::Config::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::result","qualifiedName":"LibTmux::Workspace::X::Config::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::Workspace::X::Config::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Config","product":"workspace","publicId":"LibTmux::Workspace::X::Config::throw","qualifiedName":"LibTmux::Workspace::X::Config::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-config-throw"},{"apiScope":"exported","doc":{"summary":"An existing session conflicts with the selected repeat-application policy. No session is created until all names pass the conflict check."},"extends":["LibTmux::X"],"id":"LibTmux::Workspace::X::Conflict","kind":"exception","modifiers":[],"name":"Conflict","package":"LibTmux-Workspace","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict","qualifiedName":"LibTmux::Workspace::X::Conflict","signatures":[{"params":[],"raw":"package LibTmux::Workspace::X::Conflict;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace/X.pm","line":7,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::Workspace::X::Conflict::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::count","qualifiedName":"LibTmux::Workspace::X::Conflict::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::Workspace::X::Conflict::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::details","qualifiedName":"LibTmux::Workspace::X::Conflict::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::Workspace::X::Conflict::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::dispatched","qualifiedName":"LibTmux::Workspace::X::Conflict::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::Workspace::X::Conflict::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::entity","qualifiedName":"LibTmux::Workspace::X::Conflict::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::Workspace::X::Conflict::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::expected","qualifiedName":"LibTmux::Workspace::X::Conflict::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::Workspace::X::Conflict::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::matched_ids","qualifiedName":"LibTmux::Workspace::X::Conflict::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::Workspace::X::Conflict::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::message","qualifiedName":"LibTmux::Workspace::X::Conflict::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::Workspace::X::Conflict::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::new","qualifiedName":"LibTmux::Workspace::X::Conflict::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::Workspace::X::Conflict::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::path","qualifiedName":"LibTmux::Workspace::X::Conflict::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::Workspace::X::Conflict::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::received","qualifiedName":"LibTmux::Workspace::X::Conflict::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::Workspace::X::Conflict::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::result","qualifiedName":"LibTmux::Workspace::X::Conflict::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::Workspace::X::Conflict::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Conflict","product":"workspace","publicId":"LibTmux::Workspace::X::Conflict::throw","qualifiedName":"LibTmux::Workspace::X::Conflict::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-conflict-throw"},{"apiScope":"exported","doc":{"summary":"`cause` retains the original exception. `report` records completed steps, the failed step, dispatch uncertainty, and cleanup errors. Rollback affects only sessions whose creation was proven by returned core handles. See :obj:`\"load\" in LibTmux::Workspace ` and :obj:`LibTmux::X `."},"extends":["LibTmux::X"],"id":"LibTmux::Workspace::X::Load","kind":"exception","modifiers":[],"name":"Load","package":"LibTmux-Workspace","product":"workspace","publicId":"LibTmux::Workspace::X::Load","qualifiedName":"LibTmux::Workspace::X::Load","signatures":[{"params":[],"raw":"package LibTmux::Workspace::X::Load;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load"},{"apiScope":"exported","doc":{"summary":"For Load exceptions, return the original core or orchestration failure object."},"id":"LibTmux::Workspace::X::Load::cause","kind":"method","modifiers":[],"name":"cause","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::cause","qualifiedName":"LibTmux::Workspace::X::Load::cause","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub cause($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-cause"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::Workspace::X::Load::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::count","qualifiedName":"LibTmux::Workspace::X::Load::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::Workspace::X::Load::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::details","qualifiedName":"LibTmux::Workspace::X::Load::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::Workspace::X::Load::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::dispatched","qualifiedName":"LibTmux::Workspace::X::Load::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::Workspace::X::Load::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::entity","qualifiedName":"LibTmux::Workspace::X::Load::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::Workspace::X::Load::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::expected","qualifiedName":"LibTmux::Workspace::X::Load::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::Workspace::X::Load::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::matched_ids","qualifiedName":"LibTmux::Workspace::X::Load::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::Workspace::X::Load::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::message","qualifiedName":"LibTmux::Workspace::X::Load::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::Workspace::X::Load::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::new","qualifiedName":"LibTmux::Workspace::X::Load::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::Workspace::X::Load::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::path","qualifiedName":"LibTmux::Workspace::X::Load::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::Workspace::X::Load::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::received","qualifiedName":"LibTmux::Workspace::X::Load::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-received"},{"apiScope":"exported","doc":{"summary":"For Load exceptions, return the partial-load report. It contains created IDs, completed and failed steps, dispatch uncertainty, and cleanup failures."},"id":"LibTmux::Workspace::X::Load::report","kind":"method","modifiers":[],"name":"report","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::report","qualifiedName":"LibTmux::Workspace::X::Load::report","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub report($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-report"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::Workspace::X::Load::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::result","qualifiedName":"LibTmux::Workspace::X::Load::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::Workspace::X::Load::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux-Workspace","parent":"LibTmux::Workspace::X::Load","product":"workspace","publicId":"LibTmux::Workspace::X::Load::throw","qualifiedName":"LibTmux::Workspace::X::Load::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-x-load-throw"},{"apiScope":"exported","doc":{"summary":"Decode bounded UTF-8 JSON octets with core [JSON::PP](https://perldoc.perl.org/5.44.0/JSON::PP) and call :obj:`\"new\" `. Reject unsupported versions, unknown keys, invalid commands, and duplicate names. YAML is not part of this distribution."},"id":"LibTmux::Workspace::from_json","kind":"method","modifiers":[],"name":"from_json","package":"LibTmux-Workspace","parent":"LibTmux::Workspace","product":"workspace","publicId":"LibTmux::Workspace::from_json","qualifiedName":"LibTmux::Workspace::from_json","signatures":[{"methodKind":"call","nativeSyntax":[{"end":13,"kind":"name","start":4},{"end":27,"kind":"parameter","parameter":0,"start":22}],"params":[{"name":"json"}],"raw":"sub from_json($class, $json)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace.pm","line":146,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-from_json"},{"apiScope":"exported","doc":{"body":"Return one report containing created IDs, skipped names, and completed steps. On failure, rollback only sessions returned by successful creation, then throw :obj:`Load ` with original cause and partial-effect report. An uncertain creation without a returned ID cannot be rolled back safely. Existing resources are never rollback targets. Layouts apply after splitting; working directories and environments reach every initial process. Completion means command acceptance and captured state, not application readiness.","summary":"`load(server => $server, existing => 'error'|'skip')` uses public :obj:`LibTmux::Server ` operations. It checks all session-name conflicts before creation. `error` rejects any existing target with :obj:`Conflict `; `skip` leaves that entire session alone, so repeated application creates only absent sessions. A missing server permits explicit creation; other acquisition failures propagate.","examples":[{"lang":"perl","code":"use v5.44;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse LibTmuxFixture;\nuse LibTmux::Workspace;\nLibTmuxFixture->run(\n sub ($server, $root) {\n my $workspace = LibTmux::Workspace->new(\n config => {\n schema => 'libtmux.workspace/v1',\n sessions => [\n {\n name => 'workspace-example',\n windows => [\n {\n name => 'api',\n cwd => $root,\n layout => 'even-horizontal',\n panes => [\n {command => ['/bin/sleep', '120']},\n {\n command => ['/bin/sleep', '120'],\n horizontal => true\n },\n ],\n }\n ],\n }\n ],\n }\n );\n die 'plan mutated state' if $workspace->plan->{mutates};\n my $loaded = $workspace->load(server => $server);\n die 'load failed' unless $loaded->{status} eq 'loaded';\n die 'panes missing' unless $server->snapshot->panes->count == 2;\n die 'repeat did not skip'\n unless $workspace->load(server => $server, existing => 'skip')\n ->{skipped}->@* == 1;\n say 'workspace load and repeat: ok';\n }\n);\n","intro":"Complete installed-package program with an owned tmux fixture and result/cleanup assertions.","sourceUrl":"https://github.com/libtmux/libtmux-perl/blob/36b978c5eb6aa33873229046037e7d26136ca2cf/examples/workspace.pl"}]},"id":"LibTmux::Workspace::load","kind":"method","modifiers":[],"name":"load","package":"LibTmux-Workspace","parent":"LibTmux::Workspace","product":"workspace","publicId":"LibTmux::Workspace::load","qualifiedName":"LibTmux::Workspace::load","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4},{"end":21,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub load($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace.pm","line":179,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-load"},{"apiScope":"exported","doc":{"summary":"`new(config => $hashref)` validates and copies a `libtmux.workspace/v1` configuration. No I/O occurs. Sessions contain named windows with nonempty pane arrays. Each pane requires literal `command` arguments or an explicit `shell_command`. Environment values inherit from workspace, session, and window, with pane values taking precedence. All configuration errors throw :obj:`Config `."},"id":"LibTmux::Workspace::new","kind":"method","modifiers":[],"name":"new","package":"LibTmux-Workspace","parent":"LibTmux::Workspace","product":"workspace","publicId":"LibTmux::Workspace::new","qualifiedName":"LibTmux::Workspace::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":21,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub new($class, %args)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace.pm","line":47,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-new"},{"apiScope":"exported","doc":{"summary":"`plan(existing => 'error'|'skip')` returns a fresh data plan in input order. It performs no tmux I/O or mutations. A dry-run does not prove live availability or command success. Exports share no mutable arrays with the loader. No context-dependent return values are used."},"id":"LibTmux::Workspace::plan","kind":"method","modifiers":[],"name":"plan","package":"LibTmux-Workspace","parent":"LibTmux::Workspace","product":"workspace","publicId":"LibTmux::Workspace::plan","qualifiedName":"LibTmux::Workspace::plan","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4},{"end":21,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"args","variadic":"keyword"}],"raw":"sub plan($self, %args)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/workspace/lib/LibTmux/Workspace.pm","line":165,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-workspace-plan"},{"apiScope":"exported","doc":{"body":"\n## DESCRIPTION\n\nErrors stringify with class, path, and message. :obj:`\"Creation\" ` retains its original acquisition exception separately through `cause`. `details` returns diagnostic fields. Acquisition failures never represent an empty selection.\n\n\n## CARDINALITY AND DATA FAILURES\n\n\n## DIAGNOSTICS\n\n`message`, `path`, `entity`, `expected`, `received`, `matched_ids`, `count`, `result`, `dispatched`, and `details` expose applicable fields. See :obj:`\"one\" in LibTmux::Selection `, :obj:`\"new\" in LibTmux::Filter `, and :obj:`LibTmux::Server ` for failure boundaries.\n\n","summary":"Typed failures with readable diagnostics"},"id":"LibTmux::X","kind":"class","modifiers":[],"name":"X","package":"LibTmux","product":"core","publicId":"LibTmux::X","qualifiedName":"LibTmux::X","signatures":[{"params":[],"raw":"package LibTmux::X;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":1,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x"},{"apiScope":"exported","doc":{"summary":"Observed generations, topology, or candidate results disagree."},"extends":["LibTmux::X"],"id":"LibTmux::X::AcquisitionRace","kind":"exception","modifiers":[],"name":"AcquisitionRace","package":"LibTmux","product":"core","publicId":"LibTmux::X::AcquisitionRace","qualifiedName":"LibTmux::X::AcquisitionRace","signatures":[{"params":[],"raw":"package LibTmux::X::AcquisitionRace;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":55,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::AcquisitionRace::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::count","qualifiedName":"LibTmux::X::AcquisitionRace::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::AcquisitionRace::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::details","qualifiedName":"LibTmux::X::AcquisitionRace::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::AcquisitionRace::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::dispatched","qualifiedName":"LibTmux::X::AcquisitionRace::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::AcquisitionRace::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::entity","qualifiedName":"LibTmux::X::AcquisitionRace::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::AcquisitionRace::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::expected","qualifiedName":"LibTmux::X::AcquisitionRace::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::AcquisitionRace::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::matched_ids","qualifiedName":"LibTmux::X::AcquisitionRace::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::AcquisitionRace::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::message","qualifiedName":"LibTmux::X::AcquisitionRace::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::AcquisitionRace::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::new","qualifiedName":"LibTmux::X::AcquisitionRace::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::AcquisitionRace::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::path","qualifiedName":"LibTmux::X::AcquisitionRace::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::AcquisitionRace::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::received","qualifiedName":"LibTmux::X::AcquisitionRace::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::AcquisitionRace::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::result","qualifiedName":"LibTmux::X::AcquisitionRace::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::AcquisitionRace::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::AcquisitionRace","product":"core","publicId":"LibTmux::X::AcquisitionRace::throw","qualifiedName":"LibTmux::X::AcquisitionRace::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-acquisitionrace-throw"},{"apiScope":"exported","doc":{"summary":"Execution was cancelled; cancellation does not roll back effects."},"extends":["LibTmux::X"],"id":"LibTmux::X::Cancelled","kind":"exception","modifiers":[],"name":"Cancelled","package":"LibTmux","product":"core","publicId":"LibTmux::X::Cancelled","qualifiedName":"LibTmux::X::Cancelled","signatures":[{"params":[],"raw":"package LibTmux::X::Cancelled;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":41,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::Cancelled::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::count","qualifiedName":"LibTmux::X::Cancelled::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::Cancelled::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::details","qualifiedName":"LibTmux::X::Cancelled::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::Cancelled::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::dispatched","qualifiedName":"LibTmux::X::Cancelled::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::Cancelled::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::entity","qualifiedName":"LibTmux::X::Cancelled::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::Cancelled::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::expected","qualifiedName":"LibTmux::X::Cancelled::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::Cancelled::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::matched_ids","qualifiedName":"LibTmux::X::Cancelled::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::Cancelled::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::message","qualifiedName":"LibTmux::X::Cancelled::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::Cancelled::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::new","qualifiedName":"LibTmux::X::Cancelled::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::Cancelled::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::path","qualifiedName":"LibTmux::X::Cancelled::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::Cancelled::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::received","qualifiedName":"LibTmux::X::Cancelled::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::Cancelled::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::result","qualifiedName":"LibTmux::X::Cancelled::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::Cancelled::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::Cancelled","product":"core","publicId":"LibTmux::X::Cancelled::throw","qualifiedName":"LibTmux::X::Cancelled::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-cancelled-throw"},{"apiScope":"exported","doc":{"summary":"A tmux record or field could not be decoded."},"extends":["LibTmux::X"],"id":"LibTmux::X::Codec","kind":"exception","modifiers":[],"name":"Codec","package":"LibTmux","product":"core","publicId":"LibTmux::X::Codec","qualifiedName":"LibTmux::X::Codec","signatures":[{"params":[],"raw":"package LibTmux::X::Codec;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":47,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::Codec::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::count","qualifiedName":"LibTmux::X::Codec::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::Codec::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::details","qualifiedName":"LibTmux::X::Codec::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::Codec::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::dispatched","qualifiedName":"LibTmux::X::Codec::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::Codec::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::entity","qualifiedName":"LibTmux::X::Codec::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::Codec::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::expected","qualifiedName":"LibTmux::X::Codec::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::Codec::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::matched_ids","qualifiedName":"LibTmux::X::Codec::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::Codec::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::message","qualifiedName":"LibTmux::X::Codec::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::Codec::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::new","qualifiedName":"LibTmux::X::Codec::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::Codec::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::path","qualifiedName":"LibTmux::X::Codec::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::Codec::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::received","qualifiedName":"LibTmux::X::Codec::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::Codec::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::result","qualifiedName":"LibTmux::X::Codec::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::Codec::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::Codec","product":"core","publicId":"LibTmux::X::Codec::throw","qualifiedName":"LibTmux::X::Codec::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-codec-throw"},{"apiScope":"exported","doc":{"summary":"tmux reported nonzero status; result retains stdout/stderr/status."},"extends":["LibTmux::X"],"id":"LibTmux::X::Command","kind":"exception","modifiers":[],"name":"Command","package":"LibTmux","product":"core","publicId":"LibTmux::X::Command","qualifiedName":"LibTmux::X::Command","signatures":[{"params":[],"raw":"package LibTmux::X::Command;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":49,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::Command::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::count","qualifiedName":"LibTmux::X::Command::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::Command::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::details","qualifiedName":"LibTmux::X::Command::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::Command::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::dispatched","qualifiedName":"LibTmux::X::Command::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::Command::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::entity","qualifiedName":"LibTmux::X::Command::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::Command::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::expected","qualifiedName":"LibTmux::X::Command::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::Command::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::matched_ids","qualifiedName":"LibTmux::X::Command::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::Command::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::message","qualifiedName":"LibTmux::X::Command::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::Command::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::new","qualifiedName":"LibTmux::X::Command::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::Command::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::path","qualifiedName":"LibTmux::X::Command::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::Command::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::received","qualifiedName":"LibTmux::X::Command::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::Command::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::result","qualifiedName":"LibTmux::X::Command::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::Command::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::Command","product":"core","publicId":"LibTmux::X::Command::throw","qualifiedName":"LibTmux::X::Command::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-command-throw"},{"apiScope":"exported","doc":{"summary":"A creation command succeeded but subsequent receipt decoding or capture failed. `created` returns a minimal generation-scoped entity handle when the command's receipt was decoded; other fields remain unloaded. `cause` preserves the original acquisition failure. `dispatched` is true. The returned handle permits explicit, generation-checked cleanup; absent receipts leave effects uncertain. See :obj:`\"new_session\" in LibTmux::Server `."},"extends":["LibTmux::X"],"id":"LibTmux::X::Creation","kind":"exception","modifiers":[],"name":"Creation","package":"LibTmux","product":"core","publicId":"LibTmux::X::Creation","qualifiedName":"LibTmux::X::Creation","signatures":[{"params":[],"raw":"package LibTmux::X::Creation;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":57,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation"},{"apiScope":"exported","doc":{"summary":"Return the original acquisition exception for :obj:`\"Creation\" in LibTmux::X `."},"id":"LibTmux::X::Creation::cause","kind":"method","modifiers":[],"name":"cause","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::cause","qualifiedName":"LibTmux::X::Creation::cause","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub cause($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":60,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-cause"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::Creation::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::count","qualifiedName":"LibTmux::X::Creation::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-count"},{"apiScope":"exported","doc":{"summary":"Creation failures expose a minimal generation-scoped entity receipt, or undef. Only :obj:`\"Creation\" in LibTmux::X ` provides this method."},"id":"LibTmux::X::Creation::created","kind":"method","modifiers":[],"name":"created","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::created","qualifiedName":"LibTmux::X::Creation::created","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub created($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":59,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-created"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::Creation::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::details","qualifiedName":"LibTmux::X::Creation::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::Creation::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::dispatched","qualifiedName":"LibTmux::X::Creation::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::Creation::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::entity","qualifiedName":"LibTmux::X::Creation::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::Creation::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::expected","qualifiedName":"LibTmux::X::Creation::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::Creation::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::matched_ids","qualifiedName":"LibTmux::X::Creation::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::Creation::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::message","qualifiedName":"LibTmux::X::Creation::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::Creation::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::new","qualifiedName":"LibTmux::X::Creation::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::Creation::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::path","qualifiedName":"LibTmux::X::Creation::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::Creation::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::received","qualifiedName":"LibTmux::X::Creation::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::Creation::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::result","qualifiedName":"LibTmux::X::Creation::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::Creation::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::Creation","product":"core","publicId":"LibTmux::X::Creation::throw","qualifiedName":"LibTmux::X::Creation::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-creation-throw"},{"apiScope":"exported","doc":{"summary":"Invalid operation or transport argument before dispatch."},"extends":["LibTmux::X"],"id":"LibTmux::X::InvalidArgument","kind":"exception","modifiers":[],"name":"InvalidArgument","package":"LibTmux","product":"core","publicId":"LibTmux::X::InvalidArgument","qualifiedName":"LibTmux::X::InvalidArgument","signatures":[{"params":[],"raw":"package LibTmux::X::InvalidArgument;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":21,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::InvalidArgument::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::count","qualifiedName":"LibTmux::X::InvalidArgument::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::InvalidArgument::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::details","qualifiedName":"LibTmux::X::InvalidArgument::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::InvalidArgument::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::dispatched","qualifiedName":"LibTmux::X::InvalidArgument::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::InvalidArgument::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::entity","qualifiedName":"LibTmux::X::InvalidArgument::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::InvalidArgument::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::expected","qualifiedName":"LibTmux::X::InvalidArgument::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::InvalidArgument::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::matched_ids","qualifiedName":"LibTmux::X::InvalidArgument::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::InvalidArgument::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::message","qualifiedName":"LibTmux::X::InvalidArgument::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::InvalidArgument::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::new","qualifiedName":"LibTmux::X::InvalidArgument::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::InvalidArgument::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::path","qualifiedName":"LibTmux::X::InvalidArgument::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::InvalidArgument::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::received","qualifiedName":"LibTmux::X::InvalidArgument::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::InvalidArgument::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::result","qualifiedName":"LibTmux::X::InvalidArgument::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::InvalidArgument::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::InvalidArgument","product":"core","publicId":"LibTmux::X::InvalidArgument::throw","qualifiedName":"LibTmux::X::InvalidArgument::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidargument-throw"},{"apiScope":"exported","doc":{"summary":"Invalid criteria data; path, expected, and received describe the boundary."},"extends":["LibTmux::X"],"id":"LibTmux::X::InvalidFilter","kind":"exception","modifiers":[],"name":"InvalidFilter","package":"LibTmux","product":"core","publicId":"LibTmux::X::InvalidFilter","qualifiedName":"LibTmux::X::InvalidFilter","signatures":[{"params":[],"raw":"package LibTmux::X::InvalidFilter;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":25,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::InvalidFilter::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::count","qualifiedName":"LibTmux::X::InvalidFilter::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::InvalidFilter::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::details","qualifiedName":"LibTmux::X::InvalidFilter::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::InvalidFilter::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::dispatched","qualifiedName":"LibTmux::X::InvalidFilter::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::InvalidFilter::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::entity","qualifiedName":"LibTmux::X::InvalidFilter::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::InvalidFilter::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::expected","qualifiedName":"LibTmux::X::InvalidFilter::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::InvalidFilter::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::matched_ids","qualifiedName":"LibTmux::X::InvalidFilter::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::InvalidFilter::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::message","qualifiedName":"LibTmux::X::InvalidFilter::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::InvalidFilter::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::new","qualifiedName":"LibTmux::X::InvalidFilter::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::InvalidFilter::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::path","qualifiedName":"LibTmux::X::InvalidFilter::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::InvalidFilter::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::received","qualifiedName":"LibTmux::X::InvalidFilter::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::InvalidFilter::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::result","qualifiedName":"LibTmux::X::InvalidFilter::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::InvalidFilter::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::InvalidFilter","product":"core","publicId":"LibTmux::X::InvalidFilter::throw","qualifiedName":"LibTmux::X::InvalidFilter::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidfilter-throw"},{"apiScope":"exported","doc":{"summary":"Undefined, hole, wrong-kind, or incompatible-generation membership."},"extends":["LibTmux::X"],"id":"LibTmux::X::InvalidSelection","kind":"exception","modifiers":[],"name":"InvalidSelection","package":"LibTmux","product":"core","publicId":"LibTmux::X::InvalidSelection","qualifiedName":"LibTmux::X::InvalidSelection","signatures":[{"params":[],"raw":"package LibTmux::X::InvalidSelection;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":23,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::InvalidSelection::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::count","qualifiedName":"LibTmux::X::InvalidSelection::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::InvalidSelection::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::details","qualifiedName":"LibTmux::X::InvalidSelection::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::InvalidSelection::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::dispatched","qualifiedName":"LibTmux::X::InvalidSelection::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::InvalidSelection::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::entity","qualifiedName":"LibTmux::X::InvalidSelection::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::InvalidSelection::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::expected","qualifiedName":"LibTmux::X::InvalidSelection::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::InvalidSelection::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::matched_ids","qualifiedName":"LibTmux::X::InvalidSelection::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::InvalidSelection::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::message","qualifiedName":"LibTmux::X::InvalidSelection::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::InvalidSelection::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::new","qualifiedName":"LibTmux::X::InvalidSelection::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::InvalidSelection::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::path","qualifiedName":"LibTmux::X::InvalidSelection::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::InvalidSelection::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::received","qualifiedName":"LibTmux::X::InvalidSelection::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::InvalidSelection::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::result","qualifiedName":"LibTmux::X::InvalidSelection::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::InvalidSelection::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::InvalidSelection","product":"core","publicId":"LibTmux::X::InvalidSelection::throw","qualifiedName":"LibTmux::X::InvalidSelection::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-invalidselection-throw"},{"apiScope":"exported","doc":{"summary":"At least two occurrences matched. matched_ids preserves occurrence diagnostics."},"extends":["LibTmux::X"],"id":"LibTmux::X::MultipleMatches","kind":"exception","modifiers":[],"name":"MultipleMatches","package":"LibTmux","product":"core","publicId":"LibTmux::X::MultipleMatches","qualifiedName":"LibTmux::X::MultipleMatches","signatures":[{"params":[],"raw":"package LibTmux::X::MultipleMatches;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":29,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::MultipleMatches::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::count","qualifiedName":"LibTmux::X::MultipleMatches::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::MultipleMatches::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::details","qualifiedName":"LibTmux::X::MultipleMatches::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::MultipleMatches::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::dispatched","qualifiedName":"LibTmux::X::MultipleMatches::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::MultipleMatches::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::entity","qualifiedName":"LibTmux::X::MultipleMatches::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::MultipleMatches::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::expected","qualifiedName":"LibTmux::X::MultipleMatches::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::MultipleMatches::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::matched_ids","qualifiedName":"LibTmux::X::MultipleMatches::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::MultipleMatches::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::message","qualifiedName":"LibTmux::X::MultipleMatches::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::MultipleMatches::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::new","qualifiedName":"LibTmux::X::MultipleMatches::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::MultipleMatches::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::path","qualifiedName":"LibTmux::X::MultipleMatches::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::MultipleMatches::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::received","qualifiedName":"LibTmux::X::MultipleMatches::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::MultipleMatches::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::result","qualifiedName":"LibTmux::X::MultipleMatches::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::MultipleMatches::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::MultipleMatches","product":"core","publicId":"LibTmux::X::MultipleMatches::throw","qualifiedName":"LibTmux::X::MultipleMatches::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-multiplematches-throw"},{"apiScope":"exported","doc":{"summary":"No occurrence matched one()."},"extends":["LibTmux::X"],"id":"LibTmux::X::NoMatch","kind":"exception","modifiers":[],"name":"NoMatch","package":"LibTmux","product":"core","publicId":"LibTmux::X::NoMatch","qualifiedName":"LibTmux::X::NoMatch","signatures":[{"params":[],"raw":"package LibTmux::X::NoMatch;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":27,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::NoMatch::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::count","qualifiedName":"LibTmux::X::NoMatch::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::NoMatch::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::details","qualifiedName":"LibTmux::X::NoMatch::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::NoMatch::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::dispatched","qualifiedName":"LibTmux::X::NoMatch::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::NoMatch::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::entity","qualifiedName":"LibTmux::X::NoMatch::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::NoMatch::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::expected","qualifiedName":"LibTmux::X::NoMatch::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::NoMatch::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::matched_ids","qualifiedName":"LibTmux::X::NoMatch::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::NoMatch::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::message","qualifiedName":"LibTmux::X::NoMatch::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::NoMatch::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::new","qualifiedName":"LibTmux::X::NoMatch::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::NoMatch::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::path","qualifiedName":"LibTmux::X::NoMatch::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::NoMatch::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::received","qualifiedName":"LibTmux::X::NoMatch::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::NoMatch::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::result","qualifiedName":"LibTmux::X::NoMatch::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::NoMatch::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::NoMatch","product":"core","publicId":"LibTmux::X::NoMatch::throw","qualifiedName":"LibTmux::X::NoMatch::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nomatch-throw"},{"apiScope":"exported","doc":{"summary":"The selected server cannot be reached."},"extends":["LibTmux::X"],"id":"LibTmux::X::NoServer","kind":"exception","modifiers":[],"name":"NoServer","package":"LibTmux","product":"core","publicId":"LibTmux::X::NoServer","qualifiedName":"LibTmux::X::NoServer","signatures":[{"params":[],"raw":"package LibTmux::X::NoServer;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":51,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::NoServer::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::count","qualifiedName":"LibTmux::X::NoServer::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::NoServer::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::details","qualifiedName":"LibTmux::X::NoServer::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::NoServer::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::dispatched","qualifiedName":"LibTmux::X::NoServer::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::NoServer::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::entity","qualifiedName":"LibTmux::X::NoServer::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::NoServer::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::expected","qualifiedName":"LibTmux::X::NoServer::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::NoServer::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::matched_ids","qualifiedName":"LibTmux::X::NoServer::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::NoServer::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::message","qualifiedName":"LibTmux::X::NoServer::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::NoServer::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::new","qualifiedName":"LibTmux::X::NoServer::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::NoServer::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::path","qualifiedName":"LibTmux::X::NoServer::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::NoServer::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::received","qualifiedName":"LibTmux::X::NoServer::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::NoServer::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::result","qualifiedName":"LibTmux::X::NoServer::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::NoServer::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::NoServer","product":"core","publicId":"LibTmux::X::NoServer::throw","qualifiedName":"LibTmux::X::NoServer::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-noserver-throw"},{"apiScope":"exported","doc":{"summary":"The selected stable target no longer exists. Native result diagnostics are retained. This differs from a stale generation and from an arbitrary command failure; acquire a new snapshot before choosing recovery."},"extends":["LibTmux::X"],"id":"LibTmux::X::NoSuchTarget","kind":"exception","modifiers":[],"name":"NoSuchTarget","package":"LibTmux","product":"core","publicId":"LibTmux::X::NoSuchTarget","qualifiedName":"LibTmux::X::NoSuchTarget","signatures":[{"params":[],"raw":"package LibTmux::X::NoSuchTarget;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":63,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::NoSuchTarget::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::count","qualifiedName":"LibTmux::X::NoSuchTarget::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::NoSuchTarget::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::details","qualifiedName":"LibTmux::X::NoSuchTarget::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::NoSuchTarget::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::dispatched","qualifiedName":"LibTmux::X::NoSuchTarget::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::NoSuchTarget::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::entity","qualifiedName":"LibTmux::X::NoSuchTarget::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::NoSuchTarget::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::expected","qualifiedName":"LibTmux::X::NoSuchTarget::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::NoSuchTarget::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::matched_ids","qualifiedName":"LibTmux::X::NoSuchTarget::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::NoSuchTarget::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::message","qualifiedName":"LibTmux::X::NoSuchTarget::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::NoSuchTarget::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::new","qualifiedName":"LibTmux::X::NoSuchTarget::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::NoSuchTarget::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::path","qualifiedName":"LibTmux::X::NoSuchTarget::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::NoSuchTarget::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::received","qualifiedName":"LibTmux::X::NoSuchTarget::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::NoSuchTarget::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::result","qualifiedName":"LibTmux::X::NoSuchTarget::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::NoSuchTarget::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::NoSuchTarget","product":"core","publicId":"LibTmux::X::NoSuchTarget::throw","qualifiedName":"LibTmux::X::NoSuchTarget::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-nosuchtarget-throw"},{"apiScope":"exported","doc":{"summary":"Retained process output exceeded the configured bound."},"extends":["LibTmux::X"],"id":"LibTmux::X::OutputLimit","kind":"exception","modifiers":[],"name":"OutputLimit","package":"LibTmux","product":"core","publicId":"LibTmux::X::OutputLimit","qualifiedName":"LibTmux::X::OutputLimit","signatures":[{"params":[],"raw":"package LibTmux::X::OutputLimit;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":43,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::OutputLimit::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::count","qualifiedName":"LibTmux::X::OutputLimit::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::OutputLimit::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::details","qualifiedName":"LibTmux::X::OutputLimit::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::OutputLimit::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::dispatched","qualifiedName":"LibTmux::X::OutputLimit::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::OutputLimit::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::entity","qualifiedName":"LibTmux::X::OutputLimit::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::OutputLimit::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::expected","qualifiedName":"LibTmux::X::OutputLimit::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::OutputLimit::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::matched_ids","qualifiedName":"LibTmux::X::OutputLimit::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::OutputLimit::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::message","qualifiedName":"LibTmux::X::OutputLimit::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::OutputLimit::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::new","qualifiedName":"LibTmux::X::OutputLimit::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::OutputLimit::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::path","qualifiedName":"LibTmux::X::OutputLimit::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::OutputLimit::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::received","qualifiedName":"LibTmux::X::OutputLimit::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::OutputLimit::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::result","qualifiedName":"LibTmux::X::OutputLimit::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::OutputLimit::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::OutputLimit","product":"core","publicId":"LibTmux::X::OutputLimit::throw","qualifiedName":"LibTmux::X::OutputLimit::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-outputlimit-throw"},{"apiScope":"exported","doc":{"summary":"The executable could not start; dispatch is distinguished from command failure."},"extends":["LibTmux::X"],"id":"LibTmux::X::Spawn","kind":"exception","modifiers":[],"name":"Spawn","package":"LibTmux","product":"core","publicId":"LibTmux::X::Spawn","qualifiedName":"LibTmux::X::Spawn","signatures":[{"params":[],"raw":"package LibTmux::X::Spawn;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":37,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::Spawn::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::count","qualifiedName":"LibTmux::X::Spawn::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::Spawn::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::details","qualifiedName":"LibTmux::X::Spawn::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::Spawn::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::dispatched","qualifiedName":"LibTmux::X::Spawn::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::Spawn::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::entity","qualifiedName":"LibTmux::X::Spawn::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::Spawn::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::expected","qualifiedName":"LibTmux::X::Spawn::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::Spawn::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::matched_ids","qualifiedName":"LibTmux::X::Spawn::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::Spawn::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::message","qualifiedName":"LibTmux::X::Spawn::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::Spawn::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::new","qualifiedName":"LibTmux::X::Spawn::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::Spawn::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::path","qualifiedName":"LibTmux::X::Spawn::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::Spawn::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::received","qualifiedName":"LibTmux::X::Spawn::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::Spawn::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::result","qualifiedName":"LibTmux::X::Spawn::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::Spawn::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::Spawn","product":"core","publicId":"LibTmux::X::Spawn::throw","qualifiedName":"LibTmux::X::Spawn::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-spawn-throw"},{"apiScope":"exported","doc":{"summary":"A captured generation or contextual target no longer identifies the same resource."},"extends":["LibTmux::X"],"id":"LibTmux::X::StaleReference","kind":"exception","modifiers":[],"name":"StaleReference","package":"LibTmux","product":"core","publicId":"LibTmux::X::StaleReference","qualifiedName":"LibTmux::X::StaleReference","signatures":[{"params":[],"raw":"package LibTmux::X::StaleReference;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":53,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::StaleReference::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::count","qualifiedName":"LibTmux::X::StaleReference::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::StaleReference::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::details","qualifiedName":"LibTmux::X::StaleReference::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::StaleReference::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::dispatched","qualifiedName":"LibTmux::X::StaleReference::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::StaleReference::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::entity","qualifiedName":"LibTmux::X::StaleReference::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::StaleReference::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::expected","qualifiedName":"LibTmux::X::StaleReference::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::StaleReference::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::matched_ids","qualifiedName":"LibTmux::X::StaleReference::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::StaleReference::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::message","qualifiedName":"LibTmux::X::StaleReference::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::StaleReference::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::new","qualifiedName":"LibTmux::X::StaleReference::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::StaleReference::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::path","qualifiedName":"LibTmux::X::StaleReference::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::StaleReference::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::received","qualifiedName":"LibTmux::X::StaleReference::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::StaleReference::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::result","qualifiedName":"LibTmux::X::StaleReference::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::StaleReference::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::StaleReference","product":"core","publicId":"LibTmux::X::StaleReference::throw","qualifiedName":"LibTmux::X::StaleReference::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-stalereference-throw"},{"apiScope":"exported","doc":{"summary":"Execution exceeded its deadline; effects may already have occurred."},"extends":["LibTmux::X"],"id":"LibTmux::X::Timeout","kind":"exception","modifiers":[],"name":"Timeout","package":"LibTmux","product":"core","publicId":"LibTmux::X::Timeout","qualifiedName":"LibTmux::X::Timeout","signatures":[{"params":[],"raw":"package LibTmux::X::Timeout;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":39,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::Timeout::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::count","qualifiedName":"LibTmux::X::Timeout::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::Timeout::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::details","qualifiedName":"LibTmux::X::Timeout::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::Timeout::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::dispatched","qualifiedName":"LibTmux::X::Timeout::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::Timeout::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::entity","qualifiedName":"LibTmux::X::Timeout::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::Timeout::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::expected","qualifiedName":"LibTmux::X::Timeout::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::Timeout::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::matched_ids","qualifiedName":"LibTmux::X::Timeout::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::Timeout::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::message","qualifiedName":"LibTmux::X::Timeout::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::Timeout::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::new","qualifiedName":"LibTmux::X::Timeout::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::Timeout::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::path","qualifiedName":"LibTmux::X::Timeout::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::Timeout::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::received","qualifiedName":"LibTmux::X::Timeout::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::Timeout::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::result","qualifiedName":"LibTmux::X::Timeout::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::Timeout::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::Timeout","product":"core","publicId":"LibTmux::X::Timeout::throw","qualifiedName":"LibTmux::X::Timeout::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-timeout-throw"},{"apiScope":"exported","doc":{"summary":"Process supervision or result framing failed."},"extends":["LibTmux::X"],"id":"LibTmux::X::Transport","kind":"exception","modifiers":[],"name":"Transport","package":"LibTmux","product":"core","publicId":"LibTmux::X::Transport","qualifiedName":"LibTmux::X::Transport","signatures":[{"params":[],"raw":"package LibTmux::X::Transport;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":45,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::Transport::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::count","qualifiedName":"LibTmux::X::Transport::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::Transport::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::details","qualifiedName":"LibTmux::X::Transport::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::Transport::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::dispatched","qualifiedName":"LibTmux::X::Transport::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::Transport::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::entity","qualifiedName":"LibTmux::X::Transport::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::Transport::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::expected","qualifiedName":"LibTmux::X::Transport::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::Transport::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::matched_ids","qualifiedName":"LibTmux::X::Transport::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::Transport::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::message","qualifiedName":"LibTmux::X::Transport::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::Transport::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::new","qualifiedName":"LibTmux::X::Transport::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::Transport::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::path","qualifiedName":"LibTmux::X::Transport::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::Transport::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::received","qualifiedName":"LibTmux::X::Transport::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::Transport::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::result","qualifiedName":"LibTmux::X::Transport::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::Transport::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::Transport","product":"core","publicId":"LibTmux::X::Transport::throw","qualifiedName":"LibTmux::X::Transport::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-transport-throw"},{"apiScope":"exported","doc":{"summary":"A required field or relation is not available in captured data."},"extends":["LibTmux::X"],"id":"LibTmux::X::Unloaded","kind":"exception","modifiers":[],"name":"Unloaded","package":"LibTmux","product":"core","publicId":"LibTmux::X::Unloaded","qualifiedName":"LibTmux::X::Unloaded","signatures":[{"params":[],"raw":"package LibTmux::X::Unloaded;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":31,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::Unloaded::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::count","qualifiedName":"LibTmux::X::Unloaded::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::Unloaded::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::details","qualifiedName":"LibTmux::X::Unloaded::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::Unloaded::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::dispatched","qualifiedName":"LibTmux::X::Unloaded::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::Unloaded::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::entity","qualifiedName":"LibTmux::X::Unloaded::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::Unloaded::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::expected","qualifiedName":"LibTmux::X::Unloaded::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::Unloaded::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::matched_ids","qualifiedName":"LibTmux::X::Unloaded::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::Unloaded::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::message","qualifiedName":"LibTmux::X::Unloaded::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::Unloaded::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::new","qualifiedName":"LibTmux::X::Unloaded::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::Unloaded::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::path","qualifiedName":"LibTmux::X::Unloaded::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::Unloaded::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::received","qualifiedName":"LibTmux::X::Unloaded::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::Unloaded::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::result","qualifiedName":"LibTmux::X::Unloaded::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::Unloaded::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::Unloaded","product":"core","publicId":"LibTmux::X::Unloaded::throw","qualifiedName":"LibTmux::X::Unloaded::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unloaded-throw"},{"apiScope":"exported","doc":{"summary":"A daemon or execution capability is unavailable."},"extends":["LibTmux::X"],"id":"LibTmux::X::Unsupported","kind":"exception","modifiers":[],"name":"Unsupported","package":"LibTmux","product":"core","publicId":"LibTmux::X::Unsupported","qualifiedName":"LibTmux::X::Unsupported","signatures":[{"params":[],"raw":"package LibTmux::X::Unsupported;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":35,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::Unsupported::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::count","qualifiedName":"LibTmux::X::Unsupported::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::Unsupported::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::details","qualifiedName":"LibTmux::X::Unsupported::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::Unsupported::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::dispatched","qualifiedName":"LibTmux::X::Unsupported::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::Unsupported::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::entity","qualifiedName":"LibTmux::X::Unsupported::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::Unsupported::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::expected","qualifiedName":"LibTmux::X::Unsupported::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::Unsupported::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::matched_ids","qualifiedName":"LibTmux::X::Unsupported::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::Unsupported::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::message","qualifiedName":"LibTmux::X::Unsupported::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::Unsupported::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::new","qualifiedName":"LibTmux::X::Unsupported::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::Unsupported::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::path","qualifiedName":"LibTmux::X::Unsupported::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::Unsupported::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::received","qualifiedName":"LibTmux::X::Unsupported::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::Unsupported::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::result","qualifiedName":"LibTmux::X::Unsupported::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::Unsupported::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::Unsupported","product":"core","publicId":"LibTmux::X::Unsupported::throw","qualifiedName":"LibTmux::X::Unsupported::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupported-throw"},{"apiScope":"exported","doc":{"summary":"A local value has no supported portable wire representation."},"extends":["LibTmux::X"],"id":"LibTmux::X::UnsupportedValue","kind":"exception","modifiers":[],"name":"UnsupportedValue","package":"LibTmux","product":"core","publicId":"LibTmux::X::UnsupportedValue","qualifiedName":"LibTmux::X::UnsupportedValue","signatures":[{"params":[],"raw":"package LibTmux::X::UnsupportedValue;"}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":33,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::UnsupportedValue::count","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::count","qualifiedName":"LibTmux::X::UnsupportedValue::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::UnsupportedValue::details","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::details","qualifiedName":"LibTmux::X::UnsupportedValue::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::UnsupportedValue::dispatched","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::dispatched","qualifiedName":"LibTmux::X::UnsupportedValue::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::UnsupportedValue::entity","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::entity","qualifiedName":"LibTmux::X::UnsupportedValue::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::UnsupportedValue::expected","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::expected","qualifiedName":"LibTmux::X::UnsupportedValue::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::UnsupportedValue::matched_ids","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::matched_ids","qualifiedName":"LibTmux::X::UnsupportedValue::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::UnsupportedValue::message","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::message","qualifiedName":"LibTmux::X::UnsupportedValue::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::UnsupportedValue::new","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::new","qualifiedName":"LibTmux::X::UnsupportedValue::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::UnsupportedValue::path","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::path","qualifiedName":"LibTmux::X::UnsupportedValue::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::UnsupportedValue::received","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::received","qualifiedName":"LibTmux::X::UnsupportedValue::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::UnsupportedValue::result","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::result","qualifiedName":"LibTmux::X::UnsupportedValue::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::UnsupportedValue::throw","inheritedFrom":"LibTmux::X","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X::UnsupportedValue","product":"core","publicId":"LibTmux::X::UnsupportedValue::throw","qualifiedName":"LibTmux::X::UnsupportedValue::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-unsupportedvalue-throw"},{"apiScope":"exported","doc":{"summary":"Return the observed cardinality lower bound where applicable."},"id":"LibTmux::X::count","kind":"method","modifiers":[],"name":"count","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::count","qualifiedName":"LibTmux::X::count","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4}],"params":[],"raw":"sub count($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":16,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-count"},{"apiScope":"exported","doc":{"summary":"Return a fresh shallow hashref of diagnostic fields. Causes and entity handles retain their identity."},"id":"LibTmux::X::details","kind":"method","modifiers":[],"name":"details","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::details","qualifiedName":"LibTmux::X::details","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub details($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":19,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-details"},{"apiScope":"exported","doc":{"summary":"Return whether the request was submitted where known; undef means no dispatch evidence was recorded. This never proves rollback."},"id":"LibTmux::X::dispatched","kind":"method","modifiers":[],"name":"dispatched","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::dispatched","qualifiedName":"LibTmux::X::dispatched","signatures":[{"methodKind":"call","nativeSyntax":[{"end":14,"kind":"name","start":4}],"params":[],"raw":"sub dispatched($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":18,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-dispatched"},{"apiScope":"exported","doc":{"summary":"Return the entity kind, or undef when inapplicable."},"id":"LibTmux::X::entity","kind":"method","modifiers":[],"name":"entity","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::entity","qualifiedName":"LibTmux::X::entity","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub entity($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":12,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-entity"},{"apiScope":"exported","doc":{"summary":"Return the expected operand description, or undef."},"id":"LibTmux::X::expected","kind":"method","modifiers":[],"name":"expected","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::expected","qualifiedName":"LibTmux::X::expected","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub expected($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":13,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-expected"},{"apiScope":"exported","doc":{"summary":"Return a fresh arrayref of observed matching IDs, including duplicate occurrences."},"id":"LibTmux::X::matched_ids","kind":"method","modifiers":[],"name":"matched_ids","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::matched_ids","qualifiedName":"LibTmux::X::matched_ids","signatures":[{"methodKind":"call","nativeSyntax":[{"end":15,"kind":"name","start":4}],"params":[],"raw":"sub matched_ids($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":15,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-matched_ids"},{"apiScope":"exported","doc":{"summary":"Return the human-readable failure description."},"id":"LibTmux::X::message","kind":"method","modifiers":[],"name":"message","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::message","qualifiedName":"LibTmux::X::message","signatures":[{"methodKind":"call","nativeSyntax":[{"end":11,"kind":"name","start":4}],"params":[],"raw":"sub message($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":10,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-message"},{"apiScope":"exported","doc":{"summary":"`new(%details)` constructs an exception object without throwing or I/O."},"id":"LibTmux::X::new","kind":"method","modifiers":[],"name":"new","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::new","qualifiedName":"LibTmux::X::new","signatures":[{"methodKind":"constructor","nativeSyntax":[{"end":7,"kind":"name","start":4},{"end":24,"kind":"parameter","parameter":0,"start":16}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub new($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":8,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-new"},{"apiScope":"exported","doc":{"summary":"Return the criterion or argument path, or undef when inapplicable."},"id":"LibTmux::X::path","kind":"method","modifiers":[],"name":"path","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::path","qualifiedName":"LibTmux::X::path","signatures":[{"methodKind":"call","nativeSyntax":[{"end":8,"kind":"name","start":4}],"params":[],"raw":"sub path($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":11,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-path"},{"apiScope":"exported","doc":{"summary":"Return the received operand description, or undef."},"id":"LibTmux::X::received","kind":"method","modifiers":[],"name":"received","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::received","qualifiedName":"LibTmux::X::received","signatures":[{"methodKind":"call","nativeSyntax":[{"end":12,"kind":"name","start":4}],"params":[],"raw":"sub received($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":14,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-received"},{"apiScope":"exported","doc":{"summary":"Return a completed or bounded partial :obj:`LibTmux::CommandResult `, or undef before process dispatch."},"id":"LibTmux::X::result","kind":"method","modifiers":[],"name":"result","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::result","qualifiedName":"LibTmux::X::result","signatures":[{"methodKind":"call","nativeSyntax":[{"end":10,"kind":"name","start":4}],"params":[],"raw":"sub result($self)","receiver":{"name":"self"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":17,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-result"},{"apiScope":"exported","doc":{"summary":"`throw(%details)` throws one exception object of the receiving class."},"id":"LibTmux::X::throw","kind":"method","modifiers":[],"name":"throw","package":"LibTmux","parent":"LibTmux::X","product":"core","publicId":"LibTmux::X::throw","qualifiedName":"LibTmux::X::throw","signatures":[{"methodKind":"call","nativeSyntax":[{"end":9,"kind":"name","start":4},{"end":26,"kind":"parameter","parameter":0,"start":18}],"params":[{"name":"details","variadic":"keyword"}],"raw":"sub throw($class, %details)","receiver":{"name":"class"}}],"source":{"extractedRevision":"36b978c5eb6aa33873229046037e7d26136ca2cf","file":"packages/core/lib/LibTmux/X.pm","line":9,"repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf"},"slug":"libtmux-x-throw"}]} diff --git a/site/src/data/api/perl.nav.json b/site/src/data/api/perl.nav.json new file mode 100644 index 000000000..031041ee4 --- /dev/null +++ b/site/src/data/api/perl.nav.json @@ -0,0 +1 @@ +{"port":"perl","buckets":[{"id":"server","label":"Server","collapsed":false},{"id":"session","label":"Session","collapsed":false},{"id":"window","label":"Window","collapsed":false},{"id":"pane","label":"Pane","collapsed":false},{"id":"client","label":"Client","collapsed":false},{"id":"hooks","label":"Hooks","collapsed":false},{"id":"options","label":"Options","collapsed":false,"children":[{"id":"options-functions","label":"Functions","collapsed":false},{"id":"options-constants","label":"Constants and variables","collapsed":false}]},{"id":"keys","label":"Keys and bindings","collapsed":false},{"id":"buffers","label":"Buffers","collapsed":false},{"id":"layout","label":"Layout and geometry","collapsed":false},{"id":"environment","label":"Environment","collapsed":false},{"id":"capabilities","label":"Terminal capabilities","collapsed":false},{"id":"version","label":"Versions","collapsed":false},{"id":"commands","label":"Commands","collapsed":false},{"id":"control","label":"Control mode","collapsed":false},{"id":"formats","label":"Formats","collapsed":false},{"id":"queries","label":"Queries","collapsed":false,"children":[{"id":"queries-fields","label":"Fields","collapsed":false},{"id":"queries-operators","label":"Operators","collapsed":false},{"id":"queries-expressions","label":"Expressions","collapsed":false}]},{"id":"snapshots","label":"Snapshots","collapsed":false},{"id":"workspace","label":"Workspaces","collapsed":false,"children":[{"id":"workspace-plan","label":"Plans","collapsed":false},{"id":"workspace-steps","label":"Steps","collapsed":false},{"id":"workspace-targets","label":"Targets and slots","collapsed":false},{"id":"workspace-session","label":"Session","collapsed":false},{"id":"workspace-window","label":"Window","collapsed":false},{"id":"workspace-pane","label":"Pane","collapsed":false},{"id":"workspace-functions","label":"Functions","collapsed":false},{"id":"workspace-constants","label":"Constants and variables","collapsed":false}]},{"id":"requests","label":"Requests","collapsed":true,"children":[{"id":"requests-server","label":"Server","collapsed":false},{"id":"requests-session","label":"Session","collapsed":false},{"id":"requests-window","label":"Window","collapsed":false},{"id":"requests-pane","label":"Pane","collapsed":false},{"id":"requests-client","label":"Client","collapsed":false}]},{"id":"errors","label":"Errors","collapsed":true,"children":[{"id":"errors-server","label":"Server","collapsed":false},{"id":"errors-session","label":"Session","collapsed":false},{"id":"errors-window","label":"Window","collapsed":false},{"id":"errors-pane","label":"Pane","collapsed":false}]},{"id":"constants","label":"Constants and enums","collapsed":true,"children":[{"id":"constants-server","label":"Server","collapsed":false},{"id":"constants-session","label":"Session","collapsed":false},{"id":"constants-window","label":"Window","collapsed":false},{"id":"constants-pane","label":"Pane","collapsed":false},{"id":"constants-client","label":"Client","collapsed":false}]},{"id":"runtime","label":"Runtime adapters","collapsed":false},{"id":"async","label":"Async","collapsed":false},{"id":"mcp","label":"MCP","collapsed":true,"children":[{"id":"mcp-functions","label":"Functions","collapsed":false},{"id":"mcp-constants","label":"Constants and variables","collapsed":false}]},{"id":"testing","label":"Testing utilities","collapsed":true},{"id":"internal","label":"Internal","collapsed":true,"children":[{"id":"internal-commands","label":"Commands","collapsed":false},{"id":"internal-options","label":"Options","collapsed":false}]}],"assignments":{"server":[{"id":"LibTmux::Server","name":"Server","slug":"libtmux-server","kind":"class"}],"session":[{"id":"LibTmux::Session","name":"Session","slug":"libtmux-session","kind":"class"}],"window":[{"id":"LibTmux::Window","name":"Window","slug":"libtmux-window","kind":"class"},{"id":"LibTmux::WindowLink","name":"WindowLink","slug":"libtmux-windowlink","kind":"class"}],"pane":[{"id":"LibTmux::Pane","name":"Pane","slug":"libtmux-pane","kind":"class"}],"client":[{"id":"LibTmux::Client","name":"Client","slug":"libtmux-client","kind":"class"}],"hooks":[],"options":[],"options-functions":[],"options-constants":[],"keys":[],"buffers":[],"layout":[],"environment":[],"capabilities":[],"version":[],"commands":[{"id":"LibTmux::Operation","name":"Operation","slug":"libtmux-operation","kind":"class"},{"id":"LibTmux::ProcessJob","name":"ProcessJob","slug":"libtmux-processjob","kind":"class"},{"id":"LibTmux::Transport","name":"Transport","slug":"libtmux-transport","kind":"class"}],"control":[],"formats":[],"queries":[{"id":"LibTmux::ClientSelection","name":"ClientSelection","slug":"libtmux-clientselection","kind":"class"},{"id":"LibTmux::Filter","name":"Filter","slug":"libtmux-filter","kind":"class"},{"id":"LibTmux::PaneSelection","name":"PaneSelection","slug":"libtmux-paneselection","kind":"class"},{"id":"LibTmux::QueryPlan","name":"QueryPlan","slug":"libtmux-queryplan","kind":"class"},{"id":"LibTmux::Schema","name":"Schema","slug":"libtmux-schema","kind":"class"},{"id":"LibTmux::Selection","name":"Selection","slug":"libtmux-selection","kind":"class"},{"id":"LibTmux::Selection::Iterator","name":"Iterator","slug":"libtmux-selection-iterator-cvun","kind":"class"},{"id":"LibTmux::SessionSelection","name":"SessionSelection","slug":"libtmux-sessionselection","kind":"class"},{"id":"LibTmux::WindowLinkSelection","name":"WindowLinkSelection","slug":"libtmux-windowlinkselection","kind":"class"},{"id":"LibTmux::WindowSelection","name":"WindowSelection","slug":"libtmux-windowselection","kind":"class"}],"queries-fields":[],"queries-operators":[],"queries-expressions":[],"snapshots":[{"id":"LibTmux::Snapshot","name":"Snapshot","slug":"libtmux-snapshot","kind":"class"}],"workspace":[],"workspace-plan":[{"id":"LibTmux::Workspace","name":"Workspace","slug":"libtmux-workspace","kind":"class"}],"workspace-steps":[],"workspace-targets":[],"workspace-session":[],"workspace-window":[],"workspace-pane":[],"workspace-functions":[],"workspace-constants":[],"requests":[],"requests-server":[],"requests-session":[],"requests-window":[],"requests-pane":[],"requests-client":[],"errors":[{"id":"LibTmux::Async::X","name":"X","slug":"libtmux-async-x","kind":"class"},{"id":"LibTmux::Async::X::Closed","name":"Closed","slug":"libtmux-async-x-closed","kind":"exception"},{"id":"LibTmux::Async::X::QueueFull","name":"QueueFull","slug":"libtmux-async-x-queuefull","kind":"exception"},{"id":"LibTmux::Workspace::X","name":"X","slug":"libtmux-workspace-x","kind":"class"},{"id":"LibTmux::Workspace::X::Config","name":"Config","slug":"libtmux-workspace-x-config","kind":"exception"},{"id":"LibTmux::Workspace::X::Conflict","name":"Conflict","slug":"libtmux-workspace-x-conflict","kind":"exception"},{"id":"LibTmux::Workspace::X::Load","name":"Load","slug":"libtmux-workspace-x-load","kind":"exception"},{"id":"LibTmux::X","name":"X","slug":"libtmux-x","kind":"class"},{"id":"LibTmux::X::AcquisitionRace","name":"AcquisitionRace","slug":"libtmux-x-acquisitionrace","kind":"exception"},{"id":"LibTmux::X::Cancelled","name":"Cancelled","slug":"libtmux-x-cancelled","kind":"exception"},{"id":"LibTmux::X::Codec","name":"Codec","slug":"libtmux-x-codec","kind":"exception"},{"id":"LibTmux::X::Command","name":"Command","slug":"libtmux-x-command","kind":"exception"},{"id":"LibTmux::X::Creation","name":"Creation","slug":"libtmux-x-creation","kind":"exception"},{"id":"LibTmux::X::InvalidArgument","name":"InvalidArgument","slug":"libtmux-x-invalidargument","kind":"exception"},{"id":"LibTmux::X::InvalidFilter","name":"InvalidFilter","slug":"libtmux-x-invalidfilter","kind":"exception"},{"id":"LibTmux::X::InvalidSelection","name":"InvalidSelection","slug":"libtmux-x-invalidselection","kind":"exception"},{"id":"LibTmux::X::MultipleMatches","name":"MultipleMatches","slug":"libtmux-x-multiplematches","kind":"exception"},{"id":"LibTmux::X::NoMatch","name":"NoMatch","slug":"libtmux-x-nomatch","kind":"exception"},{"id":"LibTmux::X::NoSuchTarget","name":"NoSuchTarget","slug":"libtmux-x-nosuchtarget","kind":"exception"},{"id":"LibTmux::X::OutputLimit","name":"OutputLimit","slug":"libtmux-x-outputlimit","kind":"exception"},{"id":"LibTmux::X::Spawn","name":"Spawn","slug":"libtmux-x-spawn","kind":"exception"},{"id":"LibTmux::X::StaleReference","name":"StaleReference","slug":"libtmux-x-stalereference","kind":"exception"},{"id":"LibTmux::X::Timeout","name":"Timeout","slug":"libtmux-x-timeout","kind":"exception"},{"id":"LibTmux::X::Transport","name":"Transport","slug":"libtmux-x-transport","kind":"exception"},{"id":"LibTmux::X::Unloaded","name":"Unloaded","slug":"libtmux-x-unloaded","kind":"exception"},{"id":"LibTmux::X::Unsupported","name":"Unsupported","slug":"libtmux-x-unsupported","kind":"exception"},{"id":"LibTmux::X::UnsupportedValue","name":"UnsupportedValue","slug":"libtmux-x-unsupportedvalue","kind":"exception"}],"errors-server":[{"id":"LibTmux::X::NoServer","name":"NoServer","slug":"libtmux-x-noserver","kind":"exception"}],"errors-session":[],"errors-window":[],"errors-pane":[],"constants":[{"id":"LibTmux::CommandResult","name":"CommandResult","slug":"libtmux-commandresult","kind":"class"}],"constants-server":[],"constants-session":[],"constants-window":[],"constants-pane":[],"constants-client":[],"runtime":[],"async":[{"id":"LibTmux::Async","name":"Async","slug":"libtmux-async","kind":"module"},{"id":"LibTmux::Async::Server","name":"Server","slug":"libtmux-async-server","kind":"class"},{"id":"LibTmux::Async::Transport","name":"Transport","slug":"libtmux-async-transport","kind":"class"}],"mcp":[],"mcp-functions":[],"mcp-constants":[],"testing":[],"internal":[],"internal-commands":[],"internal-options":[]},"placement":{"LibTmux::Server":"server","LibTmux::Session":"session","LibTmux::Window":"window","LibTmux::WindowLink":"window","LibTmux::Pane":"pane","LibTmux::Client":"client","LibTmux::Operation":"commands","LibTmux::ProcessJob":"commands","LibTmux::Transport":"commands","LibTmux::ClientSelection":"queries","LibTmux::Filter":"queries","LibTmux::PaneSelection":"queries","LibTmux::QueryPlan":"queries","LibTmux::Schema":"queries","LibTmux::Selection":"queries","LibTmux::Selection::Iterator":"queries","LibTmux::SessionSelection":"queries","LibTmux::WindowLinkSelection":"queries","LibTmux::WindowSelection":"queries","LibTmux::Snapshot":"snapshots","LibTmux::Workspace":"workspace-plan","LibTmux::Async::X":"errors","LibTmux::Async::X::Closed":"errors","LibTmux::Async::X::QueueFull":"errors","LibTmux::Workspace::X":"errors","LibTmux::Workspace::X::Config":"errors","LibTmux::Workspace::X::Conflict":"errors","LibTmux::Workspace::X::Load":"errors","LibTmux::X":"errors","LibTmux::X::AcquisitionRace":"errors","LibTmux::X::Cancelled":"errors","LibTmux::X::Codec":"errors","LibTmux::X::Command":"errors","LibTmux::X::Creation":"errors","LibTmux::X::InvalidArgument":"errors","LibTmux::X::InvalidFilter":"errors","LibTmux::X::InvalidSelection":"errors","LibTmux::X::MultipleMatches":"errors","LibTmux::X::NoMatch":"errors","LibTmux::X::NoSuchTarget":"errors","LibTmux::X::OutputLimit":"errors","LibTmux::X::Spawn":"errors","LibTmux::X::StaleReference":"errors","LibTmux::X::Timeout":"errors","LibTmux::X::Transport":"errors","LibTmux::X::Unloaded":"errors","LibTmux::X::Unsupported":"errors","LibTmux::X::UnsupportedValue":"errors","LibTmux::X::NoServer":"errors-server","LibTmux::CommandResult":"constants","LibTmux::Async":"async","LibTmux::Async::Server":"async","LibTmux::Async::Transport":"async","LibTmux":"__unplaced","LibTmux::Entity":"__unplaced"},"unplaced":[{"id":"LibTmux","name":"LibTmux","slug":"libtmux","kind":"module"},{"id":"LibTmux::Entity","name":"Entity","slug":"libtmux-entity","kind":"class"}],"diagnostics":{"unmatched":[],"deadBuckets":["hooks","options","options-functions","options-constants","keys","buffers","layout","environment","capabilities","version","control","formats","queries-fields","queries-operators","queries-expressions","workspace-steps","workspace-targets","workspace-session","workspace-window","workspace-pane","workspace-functions","workspace-constants","requests","requests-server","requests-session","requests-window","requests-pane","requests-client","errors-session","errors-window","errors-pane","constants-server","constants-session","constants-window","constants-pane","constants-client","runtime","mcp","mcp-functions","mcp-constants","testing","internal","internal-commands","internal-options"],"ambiguous":[],"staleUnsettled":[]}} diff --git a/site/src/data/api/perl.paths.json b/site/src/data/api/perl.paths.json new file mode 100644 index 000000000..9709192e5 --- /dev/null +++ b/site/src/data/api/perl.paths.json @@ -0,0 +1 @@ +{"port":"perl","repo":"libtmux/libtmux-perl","revision":"36b978c5eb6aa33873229046037e7d26136ca2cf","paths":[".github/CONTRIBUTING.md",".github/PERL.md",".github/WRITING.md",".github/dependabot.yml",".github/repository.json",".github/social-preview.png",".github/workflows/scaffold.yml",".gitignore",".perltidyrc",".tool-versions","AGENTS.md","CLAUDE.md","LICENSE","Makefile","README.md","conformance/where-v1.json","cpanfile","docs/architecture.md","docs/assets/app-icon-1024-dark.png","docs/assets/app-icon-1024-light.png","docs/assets/apple-touch-icon-dark.png","docs/assets/apple-touch-icon-light.png","docs/assets/browserconfig-dark.xml","docs/assets/browserconfig.xml","docs/assets/favicon.ico","docs/assets/logo-1024.png","docs/assets/logo-128.png","docs/assets/logo-144.png","docs/assets/logo-152.png","docs/assets/logo-16.png","docs/assets/logo-167.png","docs/assets/logo-180.png","docs/assets/logo-192.png","docs/assets/logo-24.png","docs/assets/logo-256.png","docs/assets/logo-32.png","docs/assets/logo-384.png","docs/assets/logo-48.png","docs/assets/logo-512.png","docs/assets/logo-64.png","docs/assets/logo-96.png","docs/assets/logo.svg","docs/assets/maskable-192-dark.png","docs/assets/maskable-192-light.png","docs/assets/maskable-512-dark.png","docs/assets/maskable-512-light.png","docs/assets/mstile-150-dark.png","docs/assets/mstile-150-light.png","docs/assets/mstile-310-dark.png","docs/assets/mstile-310-light.png","docs/assets/opengraph-dark.jpg","docs/assets/opengraph-dark.png","docs/assets/opengraph-light.jpg","docs/assets/opengraph-light.png","docs/assets/safari-pinned-tab.svg","docs/assets/site-dark.webmanifest","docs/assets/site.webmanifest","docs/assets/social-square-dark.png","docs/assets/social-square-light.png","docs/assets/source.json","docs/assets/twitter-dark.png","docs/assets/twitter-light.png","docs/async.md","docs/behavior-inventory.json","docs/branding.md","docs/compatibility.md","docs/errors.md","docs/fields.md","docs/filtering.md","docs/graph.md","docs/installation.md","docs/orchestration.md","docs/python-behavior-inventory.json","docs/query-planning.md","docs/workspace.md","examples/async.pl","examples/await.pl","examples/quickstart.pl","examples/selection.pl","examples/workspace.pl","packages/async/LICENSE","packages/async/MANIFEST.SKIP","packages/async/Makefile.PL","packages/async/README.md","packages/async/cpanfile","packages/async/lib/LibTmux/Async.pm","packages/async/lib/LibTmux/Async/Server.pm","packages/async/lib/LibTmux/Async/Transport.pm","packages/async/lib/LibTmux/Async/X.pm","packages/async/t/integration/parent-loss.t","packages/async/t/integration/tmux.t","packages/async/t/unit/server.t","packages/async/t/unit/transport.t","packages/core/LICENSE","packages/core/MANIFEST.SKIP","packages/core/Makefile.PL","packages/core/README.md","packages/core/cpanfile","packages/core/lib/LibTmux.pm","packages/core/lib/LibTmux/Client.pm","packages/core/lib/LibTmux/ClientSelection.pm","packages/core/lib/LibTmux/Codec.pm","packages/core/lib/LibTmux/CommandResult.pm","packages/core/lib/LibTmux/Entity.pm","packages/core/lib/LibTmux/Filter.pm","packages/core/lib/LibTmux/Operation.pm","packages/core/lib/LibTmux/Pane.pm","packages/core/lib/LibTmux/PaneSelection.pm","packages/core/lib/LibTmux/Platform/Linux.pm","packages/core/lib/LibTmux/ProcessJob.pm","packages/core/lib/LibTmux/QueryPlan.pm","packages/core/lib/LibTmux/Schema.pm","packages/core/lib/LibTmux/Selection.pm","packages/core/lib/LibTmux/Selection/Iterator.pm","packages/core/lib/LibTmux/Server.pm","packages/core/lib/LibTmux/Session.pm","packages/core/lib/LibTmux/SessionSelection.pm","packages/core/lib/LibTmux/Snapshot.pm","packages/core/lib/LibTmux/Transport.pm","packages/core/lib/LibTmux/Window.pm","packages/core/lib/LibTmux/WindowLink.pm","packages/core/lib/LibTmux/WindowLinkSelection.pm","packages/core/lib/LibTmux/WindowSelection.pm","packages/core/lib/LibTmux/X.pm","packages/core/lib/LibTmux/schema.json","packages/core/t/integration/fixture.t","packages/core/t/integration/input-client.t","packages/core/t/integration/lifecycle.t","packages/core/t/integration/operands.t","packages/core/t/integration/operations.t","packages/core/t/integration/query-planning.t","packages/core/t/integration/tmux.t","packages/core/t/unit/availability.t","packages/core/t/unit/codec.t","packages/core/t/unit/operation.t","packages/core/t/unit/selection.t","packages/core/t/unit/server.t","packages/core/t/unit/transport.t","packages/workspace/LICENSE","packages/workspace/MANIFEST.SKIP","packages/workspace/Makefile.PL","packages/workspace/README.md","packages/workspace/bin/libtmux-workspace","packages/workspace/cpanfile","packages/workspace/lib/LibTmux/Workspace.pm","packages/workspace/lib/LibTmux/Workspace/X.pm","packages/workspace/t/integration/creation-failure.t","packages/workspace/t/integration/load.t","packages/workspace/t/unit/config.t","scripts/benchmark.pl","scripts/check-artifacts.pl","scripts/check-pod.pl","scripts/check-snippets.pl","scripts/compatibility.py","scripts/conformance-reference.json","scripts/conformance.py","scripts/count-tmux-process.py","scripts/evidence.py","scripts/export-api.pl","scripts/filter-fixtures.pl","scripts/format.pl","scripts/generate.pl","scripts/installed-consumer.pl","scripts/inventory.py","scripts/lib/LibTmuxDev.pm","scripts/lib/LibTmuxFixture.pm","scripts/provision-consumer.py","scripts/pty-client.py","scripts/run-examples.pl","scripts/tmux-lock.json","scripts/with-subreaper.py"]} diff --git a/site/src/data/core-home.json b/site/src/data/core-home.json index 65d8dde3f..ebccc1117 100644 --- a/site/src/data/core-home.json +++ b/site/src/data/core-home.json @@ -322,5 +322,27 @@ "control-mode": "ControlSession", "capture": "Server.capture(_:includingHistory:)" } + }, + "perl": { + "objects": { + "server": "LibTmux::Server", + "session": "LibTmux::Session", + "window": "LibTmux::Window", + "pane": "LibTmux::Pane" + }, + "association": "LibTmux::WindowLink", + "capabilities": { + "objects": "LibTmux::Pane", + "ids": "LibTmux::Pane::id", + "queries": "LibTmux::Selection::where", + "errors": "LibTmux::X::InvalidFilter", + "servers": "LibTmux::Server::new", + "traversal": "LibTmux::Server::snapshot", + "send-keys": "LibTmux::Server::send_keys", + "capture": "LibTmux::Server::capture_pane", + "argv": "LibTmux::Server::cmd", + "version-gate": "LibTmux::X::Unsupported", + "async": "LibTmux::Async" + } } } diff --git a/site/src/data/destination-evidence.json b/site/src/data/destination-evidence.json index bcf528df9..abcfb147f 100644 --- a/site/src/data/destination-evidence.json +++ b/site/src/data/destination-evidence.json @@ -1508,6 +1508,111 @@ "lua:libtmux" ] }, + { + "url": "https://github.com/libtmux/libtmux-perl", + "kinds": [ + "source" + ], + "host": "github", + "ok": true, + "status": 200, + "requested": "https://github.com/libtmux/libtmux-perl", + "identity": "libtmux/libtmux-perl", + "versionChecks": [ + { + "check": "unsupported", + "note": "a branch link names no release" + } + ], + "checkedAt": "2026-11-07", + "entries": [ + "perl:repository" + ] + }, + { + "url": "https://github.com/libtmux/libtmux-perl/blob/master/packages/workspace/bin/libtmux-workspace", + "kinds": [ + "source" + ], + "host": "github", + "ok": true, + "status": 200, + "requested": "https://github.com/libtmux/libtmux-perl/blob/master/packages/workspace/bin/libtmux-workspace", + "identity": "libtmux/libtmux-perl/packages/workspace/bin/libtmux-workspace", + "versionChecks": [ + { + "check": "unsupported", + "note": "a branch link names no release" + } + ], + "checkedAt": "2026-11-07", + "entries": [ + "perl:libtmux-workspace" + ] + }, + { + "url": "https://github.com/libtmux/libtmux-perl/tree/master/packages/async", + "kinds": [ + "source" + ], + "host": "github", + "ok": true, + "status": 200, + "requested": "https://github.com/libtmux/libtmux-perl/tree/master/packages/async", + "identity": "libtmux/libtmux-perl/packages/async", + "versionChecks": [ + { + "check": "unsupported", + "note": "a branch link names no release" + } + ], + "checkedAt": "2026-11-07", + "entries": [ + "perl:LibTmux-Async" + ] + }, + { + "url": "https://github.com/libtmux/libtmux-perl/tree/master/packages/core", + "kinds": [ + "source" + ], + "host": "github", + "ok": true, + "status": 200, + "requested": "https://github.com/libtmux/libtmux-perl/tree/master/packages/core", + "identity": "libtmux/libtmux-perl/packages/core", + "versionChecks": [ + { + "check": "unsupported", + "note": "a branch link names no release" + } + ], + "checkedAt": "2026-11-07", + "entries": [ + "perl:LibTmux" + ] + }, + { + "url": "https://github.com/libtmux/libtmux-perl/tree/master/packages/workspace", + "kinds": [ + "source" + ], + "host": "github", + "ok": true, + "status": 200, + "requested": "https://github.com/libtmux/libtmux-perl/tree/master/packages/workspace", + "identity": "libtmux/libtmux-perl/packages/workspace", + "versionChecks": [ + { + "check": "unsupported", + "note": "a branch link names no release" + } + ], + "checkedAt": "2026-11-07", + "entries": [ + "perl:LibTmux-Workspace" + ] + }, { "url": "https://github.com/libtmux/libtmux-powershell", "kinds": [ diff --git a/site/src/data/home-examples.json b/site/src/data/home-examples.json index dd6366fc8..559f8679a 100644 --- a/site/src/data/home-examples.json +++ b/site/src/data/home-examples.json @@ -599,5 +599,41 @@ "errors": "Mix.install([{:libtmux, \"0.1.1\"}])\n\nalias LibTmux.{Command, Pane, Ref, Selection, Server, Session, Snapshot, Window}\n\ntmux = System.find_executable(\"tmux\") || raise \"tmux is not on PATH\"\nid = Base.encode16(:crypto.strong_rand_bytes(8), case: :lower)\ndir = Path.join(System.tmp_dir!(), \"libtmux-\" <> id)\nsocket = Path.join(dir, \"tmux.sock\")\nFile.mkdir!(dir)\nFile.chmod!(dir, 0o700)\n\n# libtmux works on a running server, so tmux itself starts the private one.\ncreate = [\"new-session\", \"-d\", \"-s\", \"demo\"]\n{_, 0} = System.cmd(tmux, [\"-S\", socket, \"-f\", \"/dev/null\" | create])\nserver = Server.new(executable: tmux, socket: socket)\n\n# Lay out the session: name its window, split it, add a second window.\nsnapshot = Server.snapshot!(server)\nsession = snapshot |> Snapshot.sessions() |> Selection.one!()\neditor = Session.active_window(snapshot, session)\n{:ok, session_ref} = Ref.from_observation(session)\n{:ok, editor_ref} = Ref.from_observation(editor)\nWindow.rename!(server, editor_ref, \"editor\")\nleft =\n snapshot\n |> Snapshot.panes()\n |> Selection.one!(window_id: editor.id, active: true)\n{:ok, left_ref} = Ref.from_observation(left)\n%{id: right_id} = Pane.split!(server, left_ref, axis: :horizontal)\n%{id: logs_id} = Session.new_window!(server, session_ref, \"logs\")\n{:ok, right} = Ref.new(:pane, right_id, session.server_instance)\n\n# Type a command into the new pane and wait for what it prints.\nPane.send_text!(server, right, \"printf 'hello from %s\\\\n' tmux\")\nPane.send_keys!(server, right, [\"Enter\"])\n\nshown =\n Enum.find_value(1..250, fn _ ->\n screen = Pane.capture!(server, right)\n screen =~ \"hello from tmux\" || (Process.sleep(20) && nil)\n end)\n\nshown || raise \"the pane did not print hello from tmux\"\n\n# Move the focus an attached client sees: the pane, then the window.\nselect_pane = Command.new(\"select-pane\", [\"-t\", right_id])\nselect_window = Command.new(\"select-window\", [\"-t\", logs_id])\n{:ok, _} = Server.run(server, select_pane)\n{:ok, _} = Server.run(server, select_window)\n\n# Walk the objects: down from the server, then up from one pane.\nsnapshot = Server.snapshot!(server)\nsessions = Snapshot.sessions(snapshot)\n\nfor each <- sessions do\n IO.puts(\"session #{each.name}\")\n links = Snapshot.related(snapshot, :session, each.id, :window_links)\n\n for link <- Enum.sort_by(links, & &1.index) do\n {:ok, window} = Snapshot.fetch(snapshot, :window, link.window_id)\n panes = Window.panes(snapshot, window)\n ids = Enum.map_join(panes, \" \", & &1.id)\n IO.puts(\" window #{link.index}:#{window.name}: #{ids}\")\n end\nend\n\npane = snapshot |> Snapshot.panes() |> Selection.one!(id: right_id)\nwindow = Snapshot.related(snapshot, :pane, pane.id, :window)\n[owner] = Snapshot.related(snapshot, :window, window.id, :sessions)\nIO.puts(\"#{pane.id} is in window #{window.name} of session #{owner.name}\")\n", "cleanup": "Mix.install([{:libtmux, \"0.1.1\"}])\n\nalias LibTmux.{Command, Pane, Ref, Selection, Server, Session, Snapshot, Window}\n\ntmux = System.find_executable(\"tmux\") || raise \"tmux is not on PATH\"\nid = Base.encode16(:crypto.strong_rand_bytes(8), case: :lower)\ndir = Path.join(System.tmp_dir!(), \"libtmux-\" <> id)\nsocket = Path.join(dir, \"tmux.sock\")\nFile.mkdir!(dir)\nFile.chmod!(dir, 0o700)\n\ntry do\n # libtmux works on a running server, so tmux itself starts the private one.\n create = [\"new-session\", \"-d\", \"-s\", \"demo\"]\n {_, 0} = System.cmd(tmux, [\"-S\", socket, \"-f\", \"/dev/null\" | create])\n server = Server.new(executable: tmux, socket: socket)\n\n # Lay out the session: name its window, split it, add a second window.\n snapshot = Server.snapshot!(server)\n session = snapshot |> Snapshot.sessions() |> Selection.one!()\n editor = Session.active_window(snapshot, session)\n {:ok, session_ref} = Ref.from_observation(session)\n {:ok, editor_ref} = Ref.from_observation(editor)\n Window.rename!(server, editor_ref, \"editor\")\n left =\n snapshot\n |> Snapshot.panes()\n |> Selection.one!(window_id: editor.id, active: true)\n {:ok, left_ref} = Ref.from_observation(left)\n %{id: right_id} = Pane.split!(server, left_ref, axis: :horizontal)\n %{id: logs_id} = Session.new_window!(server, session_ref, \"logs\")\n {:ok, right} = Ref.new(:pane, right_id, session.server_instance)\n\n # Type a command into the new pane and wait for what it prints.\n Pane.send_text!(server, right, \"printf 'hello from %s\\\\n' tmux\")\n Pane.send_keys!(server, right, [\"Enter\"])\n\n shown =\n Enum.find_value(1..250, fn _ ->\n screen = Pane.capture!(server, right)\n screen =~ \"hello from tmux\" || (Process.sleep(20) && nil)\n end)\n\n shown || raise \"the pane did not print hello from tmux\"\n\n # Move the focus an attached client sees: the pane, then the window.\n select_pane = Command.new(\"select-pane\", [\"-t\", right_id])\n select_window = Command.new(\"select-window\", [\"-t\", logs_id])\n {:ok, _} = Server.run(server, select_pane)\n {:ok, _} = Server.run(server, select_window)\n\n # Walk the objects: down from the server, then up from one pane.\n snapshot = Server.snapshot!(server)\n sessions = Snapshot.sessions(snapshot)\n\n for each <- sessions do\n IO.puts(\"session #{each.name}\")\n links = Snapshot.related(snapshot, :session, each.id, :window_links)\n\n for link <- Enum.sort_by(links, & &1.index) do\n {:ok, window} = Snapshot.fetch(snapshot, :window, link.window_id)\n panes = Window.panes(snapshot, window)\n ids = Enum.map_join(panes, \" \", & &1.id)\n IO.puts(\" window #{link.index}:#{window.name}: #{ids}\")\n end\n end\n\n pane = snapshot |> Snapshot.panes() |> Selection.one!(id: right_id)\n window = Snapshot.related(snapshot, :pane, pane.id, :window)\n [owner] = Snapshot.related(snapshot, :window, window.id, :sessions)\n IO.puts(\"#{pane.id} is in window #{window.name} of session #{owner.name}\")\nafter\n System.cmd(tmux, [\"-S\", socket, \"kill-server\"], stderr_to_stdout: true)\n File.rm_rf(dir)\nend\n" } + }, + "perl": { + "lang": "perl", + "sourceRepository": "libtmux/libtmux-perl", + "sourceRevision": "36b978c5eb6aa33873229046037e7d26136ca2cf", + "sourceTree": "269782d0ba1403af082abe05736ade4e31b5aa53", + "program": "examples/quickstart.pl", + "excerpt": { + "startLine": 1, + "endLine": 75, + "dedent": 0, + "importsEndLine": 15 + }, + "files": [ + { + "name": "examples/quickstart.pl", + "lang": "perl", + "code": "use v5.44;\nuse Config;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse LibTmuxFixture;\n\n# This complete demo owns a Linux child-reaping scope, including tmux panes.\nBEGIN {\n die 'Requires Linux x86_64 LP64'\n unless $^O eq 'linux'\n && $Config::Config{archname} =~ /x86_64/\n && $Config::Config{ptrsize} == 8\n && $Config::Config{ivsize} == 8;\n syscall(157, 36, 1, 0, 0, 0) == 0 or die \"subreaper: $!\";\n}\n\ntry {\n LibTmuxFixture->run(\n sub ($server, $root) {\n my $session = $server->new_session(\n name => 'demo',\n command => ['/bin/cat']\n );\n my $failure;\n try {\n my $editor = $session->window_links->one->window;\n $server->rename_window(window => $editor, name => 'editor');\n my $right = $server->split_pane(\n pane => $editor->panes->one,\n horizontal => true,\n command => ['/bin/cat']\n );\n my $logs = $server->new_window(\n session => $session,\n name => 'logs',\n command => ['/bin/cat']\n );\n $server->select_pane(pane => $right);\n my $snapshot = $server->snapshot;\n my $link = $snapshot->window_links->one(\n {\n window => {-is => {id => $logs->id}}\n }\n );\n $server->select_window(link => $link);\n $snapshot = $server->snapshot;\n\n for my $entry ($snapshot->sessions->@*) {\n say 'session ', $entry->name;\n for my $link ($entry->window_links->@*) {\n my $window = $link->window;\n my $ids = join ' ', map { $_->id } $window->panes->@*;\n my $label = $link->index . ':' . $window->name;\n say ' window ', $label, ': ', $ids;\n }\n }\n my $panes =\n $snapshot->windows->one({name => 'editor'})\n ->panes->where({width => {-gte => 1}})\n ->grep(sub ($pane) { $pane->height >= 1 });\n my $selected = $panes->one({active => true});\n die 'unexpected pane membership' unless $panes->count == 2;\n my $name = $selected->window->name;\n say $selected->id, ' is in window ', $name;\n }\n catch ($error) { $failure = $error }\n $server->kill_session(session => $session);\n die $failure if defined $failure;\n }\n );\n}\ncatch ($error) {\n warn \"tmux quickstart failed: $error\\n\";\n die $error;\n}\n" + }, + { + "name": "scripts/lib/LibTmuxFixture.pm", + "lang": "perl", + "code": "package LibTmuxFixture;\nuse v5.44;\nuse File::Temp qw(tempdir);\nuse File::Path qw(remove_tree);\nuse LibTmux::Server;\nuse Errno qw(ECHILD EINTR);\n\nsub _children ($pid) {\n open my $in, '<', \"/proc/$pid/task/$pid/children\" or return ();\n my $line = do { local $/; <$in> };\n close $in;\n return grep { length } split /\\s+/, $line;\n}\n\nsub _stamp ($pid) {\n open my $in, '<', \"/proc/$pid/stat\" or return undef;\n my $line = do { local $/; <$in> };\n close $in;\n return undef unless $line =~ /\\A[0-9]+ \\(.*\\) (.*)\\z/s;\n my @fields = split /\\s+/, $1;\n return $fields[19];\n}\n\nsub _tree ($pid, $owned, $order) {\n return if exists $owned->{$pid};\n my $stamp = _stamp($pid);\n return unless defined $stamp;\n $owned->{$pid} = $stamp;\n push @$order, $pid;\n _tree($_, $owned, $order) for _children($pid);\n}\n\nsub run ($class, $code, %args) {\n my %allowed = map { $_ => true } qw(executable timeout max_output env);\n die 'fixture selectors/configuration cannot be overridden'\n if grep { !$allowed{$_} } keys %args;\n my %baseline = map { $_ => true } _children($$);\n my $root = tempdir('libtmux-perl-fixture-XXXX', TMPDIR => 1, CLEANUP => 0);\n my $server = LibTmuxFixture::Server->new(\n socket_path => \"$root/s\",\n config_file => '/dev/null',\n executable => $ENV{LIBTMUX_TEST_TMUX} // 'tmux',\n timeout => 0.8,\n %args\n );\n my ($result, $failure);\n local $SIG{TERM} = sub { die 'fixture interrupted by TERM' };\n local $SIG{INT} = sub { die 'fixture interrupted by INT' };\n try { $result = $code->($server, $root) } catch ($error) {\n $failure = $error\n }\n my $cleanup_error;\n {\n local $SIG{TERM} = 'IGNORE';\n local $SIG{INT} = 'IGNORE';\n try {\n my (%owned, @order);\n my $pid = $server->{fixture_pid};\n if (!$pid && -S \"$root/s\") {\n try {\n $pid = 0 +\n $server->cmd('display-message', '-p', '#{pid}')->stdout\n }\n catch ($error) {\n die $error\n unless ref($error)\n && $error->isa('LibTmux::X::NoServer')\n }\n }\n _tree($pid, \\%owned, \\@order) if $pid;\n if (-S \"$root/s\") {\n try { $server->kill_server }\n catch ($error) {\n die $error\n unless ref($error)\n && $error->isa('LibTmux::X::NoServer')\n }\n }\n\n # This author fixture runs in an isolated test process. Preserve children\n # that existed before its scope, including nested/borrowed fixtures.\n _tree($_, \\%owned, \\@order)\n for grep { !$baseline{$_} } _children($$);\n for my $child (@order) {\n my $stamp = _stamp($child);\n kill 'KILL', $child\n if defined($stamp) && $stamp eq $owned{$child};\n }\n local $SIG{ALRM} = sub { die 'owned fixture child did not exit' };\n alarm 1;\n for my $child (@order) {\n my $waited;\n do { $waited = waitpid($child, 0) }\n while ($waited < 0 && $! == EINTR);\n my $wait_error = 0 + $!;\n my $stamp = _stamp($child);\n die 'owned fixture process remained after teardown'\n if defined($stamp) && $stamp eq $owned{$child};\n die 'fixture child exit was not observed'\n if $waited < 0 && $wait_error != ECHILD;\n }\n alarm 0;\n }\n catch ($error) { alarm 0; $cleanup_error = $error }\n }\n remove_tree($root);\n if (defined $failure) {\n if (ref($failure) && $failure isa LibTmux::X::Creation) {\n my $cause = $failure->cause;\n warn \"fixture acquisition cause: $cause\\n\" if defined $cause;\n }\n warn \"fixture cleanup also failed: $cleanup_error\"\n if defined $cleanup_error;\n die $failure;\n }\n die $cleanup_error if defined $cleanup_error;\n return $result;\n}\n\npackage LibTmuxFixture::Server;\nuse parent 'LibTmux::Server';\n\nsub new_session ($self, %args) {\n my $session = $self->SUPER::new_session(%args);\n $self->{fixture_pid} =\n 0 + $self->cmd('display-message', '-p', '#{pid}')->stdout\n unless $self->{fixture_pid};\n return $session;\n}\n1;\n" + } + ], + "prerequisites": "Linux x86_64 LP64, Perl 5.44.0, tmux 3.3a or newer, and the LibTmux core distribution installed from source. Save both files with the displayed directories. No CPAN release is claimed.", + "commands": [ + "perl examples/quickstart.pl" + ], + "expectedOutput": "session demo\n window 0:editor: %0 %1\n window 1:logs: %2\n%1 is in window editor\n", + "variants": { + "concise": "use v5.44;\nuse Config;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse LibTmuxFixture;\n\n# This complete demo owns a Linux child-reaping scope, including tmux panes.\nBEGIN {\n die 'Requires Linux x86_64 LP64'\n unless $^O eq 'linux'\n && $Config::Config{archname} =~ /x86_64/\n && $Config::Config{ptrsize} == 8 && $Config::Config{ivsize} == 8;\n syscall(157, 36, 1, 0, 0, 0) == 0 or die \"subreaper: $!\";\n}\n\nLibTmuxFixture->run(\n sub ($server, $root) {\n my $session = $server->new_session(\n name => 'demo', command => ['/bin/cat']\n );\n my $editor = $session->window_links->one->window;\n $server->rename_window(window => $editor, name => 'editor');\n my $right = $server->split_pane(\n pane => $editor->panes->one, horizontal => true,\n command => ['/bin/cat']\n );\n my $logs = $server->new_window(\n session => $session, name => 'logs', command => ['/bin/cat']\n );\n $server->select_pane(pane => $right);\n my $snapshot = $server->snapshot;\n my $link = $snapshot->window_links->one({\n window => {-is => {id => $logs->id}}\n });\n $server->select_window(link => $link);\n $snapshot = $server->snapshot;\n\n for my $entry ($snapshot->sessions->@*) {\n say 'session ', $entry->name;\n for my $link ($entry->window_links->@*) {\n my $window = $link->window;\n my $ids = join ' ', map { $_->id } $window->panes->@*;\n my $label = $link->index . ':' . $window->name;\n say ' window ', $label, ': ', $ids;\n }\n }\n my $panes = $snapshot->windows->one({name => 'editor'})->panes\n ->where({width => {-gte => 1}})\n ->grep(sub ($pane) { $pane->height >= 1 });\n my $selected = $panes->one({active => true});\n die 'unexpected pane membership' unless $panes->count == 2;\n my $name = $selected->window->name;\n say $selected->id, ' is in window ', $name;\n }\n);\n", + "errors": "use v5.44;\nuse Config;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse LibTmuxFixture;\n\n# This complete demo owns a Linux child-reaping scope, including tmux panes.\nBEGIN {\n die 'Requires Linux x86_64 LP64'\n unless $^O eq 'linux'\n && $Config::Config{archname} =~ /x86_64/\n && $Config::Config{ptrsize} == 8 && $Config::Config{ivsize} == 8;\n syscall(157, 36, 1, 0, 0, 0) == 0 or die \"subreaper: $!\";\n}\n\ntry {\n LibTmuxFixture->run(\n sub ($server, $root) {\n my $session = $server->new_session(\n name => 'demo', command => ['/bin/cat']\n );\n my $editor = $session->window_links->one->window;\n $server->rename_window(window => $editor, name => 'editor');\n my $right = $server->split_pane(\n pane => $editor->panes->one, horizontal => true,\n command => ['/bin/cat']\n );\n my $logs = $server->new_window(\n session => $session, name => 'logs', command => ['/bin/cat']\n );\n $server->select_pane(pane => $right);\n my $snapshot = $server->snapshot;\n my $link = $snapshot->window_links->one({\n window => {-is => {id => $logs->id}}\n });\n $server->select_window(link => $link);\n $snapshot = $server->snapshot;\n\n for my $entry ($snapshot->sessions->@*) {\n say 'session ', $entry->name;\n for my $link ($entry->window_links->@*) {\n my $window = $link->window;\n my $ids = join ' ', map { $_->id } $window->panes->@*;\n my $label = $link->index . ':' . $window->name;\n say ' window ', $label, ': ', $ids;\n }\n }\n my $panes = $snapshot->windows->one({name => 'editor'})->panes\n ->where({width => {-gte => 1}})\n ->grep(sub ($pane) { $pane->height >= 1 });\n my $selected = $panes->one({active => true});\n die 'unexpected pane membership' unless $panes->count == 2;\n my $name = $selected->window->name;\n say $selected->id, ' is in window ', $name;\n }\n );\n}\ncatch ($error) {\n warn \"tmux quickstart failed: $error\\n\";\n die $error;\n}\n", + "cleanup": "use v5.44;\nuse Config;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse LibTmuxFixture;\n\n# This complete demo owns a Linux child-reaping scope, including tmux panes.\nBEGIN {\n die 'Requires Linux x86_64 LP64'\n unless $^O eq 'linux'\n && $Config::Config{archname} =~ /x86_64/\n && $Config::Config{ptrsize} == 8 && $Config::Config{ivsize} == 8;\n syscall(157, 36, 1, 0, 0, 0) == 0 or die \"subreaper: $!\";\n}\n\nLibTmuxFixture->run(\n sub ($server, $root) {\n my $session = $server->new_session(\n name => 'demo', command => ['/bin/cat']\n );\n my $failure;\n try {\n my $editor = $session->window_links->one->window;\n $server->rename_window(window => $editor, name => 'editor');\n my $right = $server->split_pane(\n pane => $editor->panes->one, horizontal => true,\n command => ['/bin/cat']\n );\n my $logs = $server->new_window(\n session => $session, name => 'logs', command => ['/bin/cat']\n );\n $server->select_pane(pane => $right);\n my $snapshot = $server->snapshot;\n my $link = $snapshot->window_links->one({\n window => {-is => {id => $logs->id}}\n });\n $server->select_window(link => $link);\n $snapshot = $server->snapshot;\n\n for my $entry ($snapshot->sessions->@*) {\n say 'session ', $entry->name;\n for my $link ($entry->window_links->@*) {\n my $window = $link->window;\n my $ids = join ' ', map { $_->id } $window->panes->@*;\n my $label = $link->index . ':' . $window->name;\n say ' window ', $label, ': ', $ids;\n }\n }\n my $panes = $snapshot->windows->one({name => 'editor'})->panes\n ->where({width => {-gte => 1}})\n ->grep(sub ($pane) { $pane->height >= 1 });\n my $selected = $panes->one({active => true});\n die 'unexpected pane membership' unless $panes->count == 2;\n my $name = $selected->window->name;\n say $selected->id, ' is in window ', $name;\n }\n catch ($error) { $failure = $error }\n $server->kill_session(session => $session);\n die $failure if defined $failure;\n }\n);\n" + }, + "automaticCleanup": "The included standard-library fixture owns its private socket and verifies child exit. Cleanup also tears down the created session explicitly." } } diff --git a/site/src/data/manifest-packages.json b/site/src/data/manifest-packages.json index 1ed815c1e..c232859f7 100644 --- a/site/src/data/manifest-packages.json +++ b/site/src/data/manifest-packages.json @@ -142,14 +142,14 @@ }, "elixir": { "repo": "libtmux/libtmux-elixir", - "revision": "149565c9f04e043836191c8a7ff32a8ac39572ab", + "revision": "6e6e88e886bdd9267fcd8be66f561dc5d5462476", "distributions": [ { "name": "libtmux", "version": "0.0.1-alpha.1", "manifest": "mix.exs", "repo": "libtmux/libtmux-elixir", - "revision": "149565c9f04e043836191c8a7ff32a8ac39572ab" + "revision": "6e6e88e886bdd9267fcd8be66f561dc5d5462476" } ], "units": [] @@ -735,6 +735,41 @@ "name": "TmuxWorkspace" } ] + }, + "perl": { + "repo": "libtmux/libtmux-perl", + "revision": "fa3df0ceb4320442064ef738c2ea37df187af582", + "distributions": [ + { + "name": "LibTmux", + "version": "0.001_001", + "manifest": "packages/core/Makefile.PL", + "repo": "libtmux/libtmux-perl", + "revision": "fa3df0ceb4320442064ef738c2ea37df187af582" + }, + { + "name": "LibTmux-Async", + "version": "0.001_001", + "manifest": "packages/async/Makefile.PL", + "repo": "libtmux/libtmux-perl", + "revision": "fa3df0ceb4320442064ef738c2ea37df187af582" + }, + { + "name": "LibTmux-Workspace", + "version": "0.001_001", + "manifest": "packages/workspace/Makefile.PL", + "repo": "libtmux/libtmux-perl", + "revision": "fa3df0ceb4320442064ef738c2ea37df187af582" + } + ], + "units": [ + { + "unit": "command", + "name": "libtmux-workspace", + "path": "packages/workspace/bin/libtmux-workspace", + "file": true + } + ] } } } diff --git a/site/src/data/mentions.json b/site/src/data/mentions.json index 086eaf2b6..692486d50 100644 --- a/site/src/data/mentions.json +++ b/site/src/data/mentions.json @@ -8372,6 +8372,76 @@ "title": "Topology operations", "section": "guides" }, + { + "port": "perl", + "symbol": "LibTmux", + "page": "/perl/latest/guides/getting-started/", + "title": "Getting started", + "section": "guides" + }, + { + "port": "perl", + "symbol": "LibTmux::Filter", + "page": "/perl/latest/guides/filtering/", + "title": "Filtering", + "section": "guides" + }, + { + "port": "perl", + "symbol": "LibTmux::Server", + "page": "/perl/latest/examples/orchestration/", + "title": "Create sessions, windows, and panes", + "section": "examples" + }, + { + "port": "perl", + "symbol": "LibTmux::Snapshot::windows", + "page": "/perl/latest/concepts/graph/", + "title": "Snapshot graph and identity", + "section": "concepts" + }, + { + "port": "perl", + "symbol": "LibTmux::WindowLink", + "page": "/perl/latest/concepts/graph/", + "title": "Snapshot graph and identity", + "section": "concepts" + }, + { + "port": "perl", + "symbol": "LibTmux::X", + "page": "/perl/latest/topics/errors/", + "title": "Errors and recovery", + "section": "topics" + }, + { + "port": "perl", + "symbol": "LibTmux::X::Creation", + "page": "/perl/latest/topics/errors/", + "title": "Errors and recovery", + "section": "topics" + }, + { + "port": "perl", + "symbol": "LibTmux::X::Creation::cause", + "page": "/perl/latest/topics/errors/", + "title": "Errors and recovery", + "section": "topics" + }, + { + "port": "perl", + "symbol": "LibTmux::X::InvalidSelection", + "page": "/perl/latest/concepts/graph/", + "title": "Snapshot graph and identity", + "section": "concepts" + }, + { + "port": "perl", + "symbol": "LibTmux::X::Unloaded", + "page": "/perl/latest/topics/errors/", + "title": "Errors and recovery", + "section": "topics" + }, { "port": "powershell", "symbol": "LibTmux", @@ -14996,6 +15066,34 @@ "line": 33, "why": "not defined in the stated port" }, + { + "port": "perl", + "text": "IO::Async::Loop", + "page": "/perl/latest/guides/async/", + "line": 14, + "why": "not defined in the stated port" + }, + { + "port": "perl", + "text": "libtmux.where/v1", + "page": "/perl/latest/guides/filtering/", + "line": 43, + "why": "not defined in the stated port" + }, + { + "port": "perl", + "text": "LibTmux-Async", + "page": "/perl/latest/guides/getting-started/", + "line": 34, + "why": "not defined in the stated port" + }, + { + "port": "perl", + "text": "LibTmux-Workspace", + "page": "/perl/latest/guides/getting-started/", + "line": 35, + "why": "not defined in the stated port" + }, { "port": "ruby", "text": "Enumerable", diff --git a/site/src/data/port-guides/perl.json b/site/src/data/port-guides/perl.json new file mode 100644 index 000000000..f50d3694e --- /dev/null +++ b/site/src/data/port-guides/perl.json @@ -0,0 +1,52 @@ +{ + "source": { + "repository": "libtmux/libtmux-perl", + "revision": "36b978c5eb6aa33873229046037e7d26136ca2cf" + }, + "guides": [ + { + "path": "README.md", + "content": "\n
\n \n \n \"libtmux\n \n
\n\n\n
\n\n# libtmux for Perl\n\n
\n\nControl tmux with explicit commands, captured graphs, and ordinary Perl arrays.\nTargets stable Perl 5.44.0 and Linux x86_64, including WSL. These development\ndistributions are not published on CPAN.\n\n```perl\nuse v5.44;\nuse LibTmux::Server;\n\nmy $server = LibTmux::Server->new(socket_name => 'example');\nmy $snapshot = $server->snapshot; # Explicit I/O; server must already exist.\nmy $active = $snapshot->panes\n ->where({ active => true, width => { -gte => 80 } })\n ->grep(sub ($pane) { $pane->current_command eq 'sleep' });\n\nfor my $pane ($active->@*) {\n say $pane->id, ' ', $pane->window->name;\n}\n```\n\n| Distribution | Location | Runtime dependencies |\n| --- | --- | --- |\n| `LibTmux` | [packages/core](packages/core) | Perl standard library. |\n| `LibTmux-Async` | [packages/async](packages/async) | Versioned core, Future, IO::Async; caller-owned loop. |\n| `LibTmux-Workspace` | [packages/workspace](packages/workspace) | Versioned core; packaged JSON loader CLI. |\n\nStart with [installation](docs/installation.md),\n[basic orchestration](docs/orchestration.md), and\n[filtering](docs/filtering.md). Read [graph identity](docs/graph.md) before\nworking with linked windows, [query planning](docs/query-planning.md) for\nexplicit native filters, [errors and recovery](docs/errors.md),\n[async execution](docs/async.md), and [workspace loading](docs/workspace.md).\nInstalled API documentation uses native POD; for example `perldoc\nLibTmux::Server` and `perldoc LibTmux::Selection`.\n\n[Complete examples](examples) run against uniquely owned tmux sockets and\nassert results and cleanup. [Compatibility](docs/compatibility.md) records the\nrequired release cells and qualification limits. Captured selections perform\nno tmux I/O; their methods preserve order and duplicates and return one fixed\ntype in every calling context. Native array access remains available.\n\nMCP is excluded. Persistent control mode, streaming APIs, tmux command lists,\nserialized regexes, and relation pushdown are deferred. Package publication\nand shared-site deployment require separate authority.\n\nSee [contributing](.github/CONTRIBUTING.md) for exact checks and tool setup,\n[Perl choices](.github/PERL.md) for source-backed decisions, and\n[branding assets](docs/branding.md) for logos and social cards.\n" + }, + { + "path": "docs/installation.md", + "content": "---\ntitle: Install from source\ndescription: Install from source with the Perl libtmux distributions.\n---\n\nThese distributions are unpublished. Use Perl 5.44.0 and install core before\nworkspace or optional async. Use the repository's pinned cpm author setup,\nor an existing cpm installation. From the repository root:\n\n```console\n$ cpm install \\\n --global \\\n ./packages/core\n```\n\n```console\n$ cpm install \\\n --global \\\n ./packages/workspace\n```\n\n```console\n$ cpm install \\\n --global \\\n ./packages/async\n```\n\nCore and workspace need only the Perl standard library at runtime. Async\nadds Future and IO::Async. Configure/test/develop requirements remain separate.\nTo inspect installed documentation:\n\n```console\n$ perldoc LibTmux::Server\n```\n\nThe [contributor guide](../.github/CONTRIBUTING.md) documents pinned local\nprovisioning, archive builds, and isolated installed-consumer verification.\nNo PAUSE upload, tag, or release is implied by source installation.\n" + }, + { + "path": "docs/orchestration.md", + "content": "---\ntitle: Create and observe tmux resources\ndescription: Create and observe tmux resources with the Perl libtmux distributions.\n---\n\nConstructing `LibTmux::Server` records connection settings without I/O. Pass a\nsocket name or socket path; the library clears inherited `TMUX` and\n`TMUX_PANE` in subprocess environments. Acquisition and mutations are explicit.\n\n```perl\nuse v5.44;\nuse LibTmux::Server;\nmy $server = LibTmux::Server->new(socket_name => 'example');\nmy $session = $server->new_session(\n name => 'main', command => ['/bin/sleep', '120'],\n);\nmy $window = $server->new_window(\n session => $session, name => 'api', command => ['/bin/sleep', '120'],\n);\nmy $pane = $window->panes->one;\nmy $split = $server->split_pane(\n pane => $pane, horizontal => true, command => ['/bin/sleep', '120'],\n);\n$server->select_layout(window => $window, layout => 'even-horizontal');\nmy $observed = $server->snapshot;\n$server->kill_session(session => $session);\n```\n\nThis example creates a session and explicitly removes it. Complete executed\nprograms in [examples](../examples) add exception-safe owned fixture cleanup.\nLiteral argv does not select a shell. `shell_command` explicitly requests\nshell interpretation; one-element literal commands use the core exec shim.\n\nAll mutations live on Server. Entity readers are captured and read-only;\nrenaming a window does not change an old Window handle. Use a new snapshot.\n`capture_pane` returns bytes including tmux's final newline. `send_text`\nsends literal text with optional Enter; `send_keys` accepts named tmux keys.\n\nUse `set_option`/`get_option`/`unset_option` for explicit scopes, including\ninherited reads, and environment methods for global or session values. Hooks\nretain sparse indexes in native output. Buffers use stdin for binary payloads.\n`cmd` is the checked literal command escape hatch; `execute` retains nonzero\ncommand results. Ordered `batch` returns one `{result, error}` record per\nindependent request, not per command inside a tmux command list.\n\nInteractive terminal ownership stays with the caller: `attach_argv` returns\nargv for a caller-owned terminal; `clients` captures client data and\n`detach_client` reports command acceptance. Observe client exit separately.\n\nThe complete [quickstart program](../examples/quickstart.pl) creates a session,\nsplits a pane, adds a window, selects a window link, and filters captured\npanes. Install core first, then run it from the source checkout:\n\n```console\n$ perl examples/quickstart.pl\n```\n\nThe included standard-library fixture owns its private socket and verifies\nchild exit. The standalone demo enables Linux x86_64 LP64 child reaping; the\nborrowed Server connection API does not change the application's reaper.\n" + }, + { + "path": "docs/filtering.md", + "content": "---\ntitle: Filter captured selections\ndescription: Native Perl arrays, strict criteria, graph quantifiers, and wire filters.\n---\n\nUse `where({...})` for query data and `grep(sub ($pane) {...})` for arbitrary\nPerl behavior. Native `->@*`, indexing, `grep`, `map`, `sort`, and List::Util\nremain available. `to_array` returns a fresh unblessed array reference.\n\nFields select comparison semantics: text, safe decimal integers, booleans,\nnullability, allowed operators, and relation cardinality come from one catalog.\nFalse, zero, \"0\", empty text, and undef remain distinct. Integer operands are\nbounded to +/-9007199254740991; invalid numeric text never becomes zero.\n\n| Grammar | Meaning |\n| --- | --- |\n| scalar or `-eq`, `-ne` | Schema-directed equality and complement. |\n| `-in`, `-not_in` arrays | Explicit membership; empty arrays mean false/true. |\n| `-lt`, `-lte`, `-gt`, `-gte` | Authorized numeric ordering. |\n| `-contains`, `-starts_with`, `-ends_with` | Literal, case-sensitive text. |\n| `-and`, `-or` arrays; `-not` node | Complete criteria nodes. |\n| `-some`, `-every`, `-none` | To-many quantifiers over the complete captured domain. |\n| `-is`, `-is_not` | To-one criteria or explicit nullable absence. |\n\nFields/operators in a hash are conjoined. Duplicate Perl hash keys overwrite;\nuse multiple operators or explicit `-and`. Empty criteria and empty AND are\ntrue; empty OR is false. On a loaded empty relation, some is false and\nevery/none true. Conditions inside one some apply to the same child; separate\nexistentials may match different children. Unloaded relations never prove empty.\n\nFull compilation precedes evaluation, even on empty selections. Hash keys\ntraverse lexically; logical arrays preserve their order. Short-circuiting may\navoid unavailable reads once a result is known. Known-null ordering/text is\nfalse; negation reverses known results, never missing-data failures.\n\n`LibTmux::Filter` owns normalized criteria, supports plain records and explicit\nregistered readers, and exports `libtmux.where/v1` JSON. Wire names use camelCase\nand dash-free operators. Regex/coderefs/cycles/blessed values are refused at\nthat data boundary. Native Perl `qr//` remains available in callbacks.\n\nThe complete example below is copied from an executed program. The fixture\nhelper uses an owned socket, observes process exit, and cleans up on failures.\n\n\n```perl\nuse v5.44;\nuse FindBin;\nuse lib \"$FindBin::Bin/../scripts/lib\";\nuse LibTmuxFixture;\nuse LibTmux::Filter;\nuse List::Util qw(any first);\nLibTmuxFixture->run(\n sub ($server, $root) {\n my $session = $server->new_session(\n name => 'example',\n command => ['/bin/sleep', '120']\n );\n my $initial = $session->window_links->one->window->panes->one;\n $server->split_pane(\n pane => $initial,\n horizontal => true,\n command => ['/bin/sleep', '120']\n );\n my $snapshot = $server->snapshot;\n my $panes = $snapshot->panes->where({current_command => 'sleep'})\n ->grep(sub ($pane) { $pane->width >= 1 });\n die 'expected two panes' unless $panes->count == 2;\n for my $pane ($panes->@*) {\n say $pane->id . ' ' . $pane->current_command;\n }\n my $only_active = $panes->one({active => true});\n die 'active pane unavailable' unless defined $only_active;\n my $has_active = any { $_->active } $panes->@*;\n my $first_active = first { $_->active } $panes->@*;\n die 'List::Util alternatives differ'\n unless $has_active && $first_active->id eq $only_active->id;\n my @ids = map { $_->id } $panes->@*;\n my @positive = grep { $_->width > 0 } $panes->@*;\n die 'ordinary Perl arrays differ' unless @ids == 2 && @positive == 2;\n my $filter =\n LibTmux::Filter->new(entity => 'pane', where => {active => true});\n my $decoded = LibTmux::Filter->from_json($filter->to_json);\n die 'wire filter changed meaning'\n unless $panes->where($decoded)->one->id eq $only_active->id;\n my $retained = do {\n my $observed = $server->snapshot;\n $observed->pane_by_id($only_active->id);\n };\n die 'retained graph lost a relationship'\n unless $retained->window->panes->count == 2;\n my $same_child = $snapshot->windows->where(\n {panes => {-some => {-and => [{index => 0}, {index => 1}]}}});\n my $different_children = $snapshot->windows->where(\n {\n -and => [\n {panes => {-some => {index => 0}}},\n {panes => {-some => {index => 1}}}\n ]\n }\n );\n die 'quantifiers conflated children'\n unless $same_child->count == 0 && $different_children->count == 1;\n my $where = {active => true, width => {-gte => 1}};\n my $local = $server->query_panes(where => $where, pushdown => 'never');\n my $native =\n $server->query_panes(where => $where, pushdown => 'require');\n die 'native/local disagreement'\n unless join(',', map { $_->id } @$local) eq\n join(',', map { $_->id } @$native);\n say 'selection, wire, graph lifetime, quantifiers, and query: ok';\n }\n);\n```\n\n## Independent-port subset\n\nThe shared fixture vocabulary is proposed for this port. A source-pinned Python\nQueryList evaluator agrees on the advertised subset: Boolean/integer/text\nequality, literal contains/prefix/suffix, membership, and empty membership.\nThe adaptation maps wire field names to record keys and operators to native\nQueryList lookup keywords. It does not claim that Python accepts this wire API.\n\nKnown-null equality initially disagreed: the pinned Python filter rejects None\nfields before its equality lookup. That difference remains recorded. Numeric\nordering, availability errors, graph quantifiers, validation on empty data,\nand canonical-name enforcement have no equivalent declared Python contract\nand are marked unsupported, not passed. Perl fixtures cover those semantics.\nSee [the fixtures](../conformance/where-v1.json) and\n[the independent source pin](../scripts/conformance-reference.json).\n" + }, + { + "path": "docs/graph.md", + "content": "---\ntitle: Snapshots and linked-window identity\ndescription: Snapshots and linked-window identity with the Perl libtmux distributions.\n---\n\nA physical window can appear at several indexes in one session and in several\nsessions. `WindowLink` owns session-relative index and active state. A Pane's\n`window` always returns the physical Window. Session changes use explicit links.\n\nSnapshot `windows` and `panes` contain each physical identity once. Raw\n`listings` retain contextual rows and multiplicity. Selection filters retain\ntheir own input order and duplicates. Two occurrences of one identity still\nmake `one` ambiguous.\n\nSelections may combine captures from the same server generation. Each handle\nretains its own observed graph; combining them does not reconcile capture times\nor create a new snapshot. Mixing server scopes or daemon generations is an\n`InvalidSelection` error. Use one snapshot when a query needs one capture interval.\n\nIDs remain strings. Write session IDs as `'$1'` in Perl so regex captures do\nnot interpolate. Identity includes server, daemon generation, kind, and ID.\nCaptured handles prevent silent retargeting after a restart; probes and\ncommands remain separate observations, so they do not form a transaction.\n\nThe store owns scalar records and ID adjacency. Handles strongly retain that\nstore, which does not strongly own handles. A retained pane keeps its observed\nwindow even when the Snapshot wrapper leaves scope. Retaining one handle can\nretain the graph; `to_record` exports detached scalar data instead.\n\nAcquisition records start/end and completeness. Strict live capture rejects\nmissing required topology. Unloaded fields and relations throw when needed;\nnull and loaded-empty relations remain distinct. Accessors return independent\nmembership arrays. Query methods are nonmutating, while native arrays remain\nmutable and every library query validates their members.\n" + }, + { + "path": "docs/query-planning.md", + "content": "---\ntitle: Explicit acquisition and native filters\ndescription: Explicit acquisition and native filters with the Perl libtmux distributions.\n---\n\n`$snapshot->panes->where($criteria)` and callbacks evaluate eagerly without\nI/O. `query_panes` explicitly acquires a graph and returns a PaneSelection.\n`explain_panes` creates a local plan using support-floor capabilities; it does\nnot connect. Execution binds capabilities to the captured daemon generation.\n\n| Policy | Behavior |\n| --- | --- |\n| `never` | Acquire and evaluate locally. |\n| `auto` | Verify safe scalar native candidates; fall back to captured local results on disagreement. |\n| `require` | Require complete exact lowering and native/captured agreement. |\n\nThe current implementation captures and evaluates the complete graph before\ncandidate verification, preserving local error behavior. It makes no I/O-saving\nclaim. Plans identify commands, lowered filters, residual reasons, and capability\nrequirements. Numeric lowering uses tmux numeric expressions. Literal operands\nare escaped for the tmux grammar independently of argument-vector safety.\n\nA partial AND conjunct can prune candidates. Partial OR/NOT cannot. Relations,\nnull, bytes, and unsupported scalar operators remain local. Relation pushdown\nand serialized regex dialects are deferred. Complete relation domains are never\npruned before `every` or `none` evaluation.\n\n`native_filter` is an explicit expert escape hatch, exclusive with portable\ncriteria and pushdown policy. It selects captured root IDs and rejects new IDs\nthat appeared outside capture. It has native tmux semantics, not wire semantics.\n" + }, + { + "path": "docs/errors.md", + "content": "---\ntitle: Recover from failures\ndescription: Recover from failures with the Perl libtmux distributions.\n---\n\nErrors are typed `LibTmux::X` objects with readable stringification and\napplicable fields such as path, expected/received types, IDs, dispatch state,\nand process result. Catch objects with stable Perl try/catch and isa:\n\n```perl\ntry {\n my $only = $snapshot->panes->one({ active => true });\n}\ncatch ($error) {\n if ($error isa LibTmux::X::NoMatch) {\n say 'No active pane in this captured selection';\n }\n else {\n die $error;\n }\n}\n```\n\n`one_or_undef` handles absence and still rejects ambiguity. Acquisition errors\nnever become empty selections. `Unloaded` differs from known null. Complete\ncriteria validation runs before matching, including on empty input and in\nbranches that later short-circuit.\n\nProcess results distinguish stdout, stderr, exit status, signal, timeout,\nspawn failure, output limit, cancellation, and dispatch uncertainty. Lifecycle\nerrors retain bounded partial results; unknown status remains undef.\nCancellation does not imply rollback or nonexecution. The isolated Linux\nsupervisor reaps its owned process group; intentionally detached daemons have\nseparate ownership. The current verified ABI is x86_64 LP64.\n\n`Creation` preserves a generation-scoped minimal created handle when the\ncommand succeeded but subsequent capture failed. Inspect `created` and `cause`\nbefore deciding cleanup. Other fields on that handle are unloaded. Workspace\nuses this evidence for owned rollback and records cleanup failures separately.\n" + }, + { + "path": "docs/compatibility.md", + "content": "---\ntitle: Linux compatibility and qualification\ndescription: Linux compatibility and qualification with the Perl libtmux distributions.\n---\n\nThe baseline is stable Perl 5.44.0 on Linux x86_64 LP64, including WSL. Plain\ntmux 3.3 is below the support floor; its separate rejection gate must pass.\nOther operating systems and Linux ABIs have not been qualified. The supervisor\nrefuses unsupported ABIs before dispatch instead of assuming syscall numbers.\n\nRequired tmux cells: 3.3a, 3.4, 3.5, 3.5a, 3.6, 3.6a, 3.6b, 3.7, 3.7a, 3.7b,\n3.7c, and 3.8. [The source lock](../scripts/tmux-lock.json) pins official assets,\narchive hashes, source commits, and configure flags. Per-build provenance adds\ncompiler and executable hashes. Exact per-cell results are recorded by the\ncompatibility command; a missing or skipped cell remains unverified.\n\n```console\n$ mise exec -- make compatibility\n```\n\nThe original 3.3a run exposed tmux's invalid-layout error-pointer defect.\nThe public select_layout wrapper now rejects unknown/ambiguous names lacking\na custom-layout checksum prefix before dispatch. The raw command escape hatch\nretains native behavior. See the contributor guide for archive consumers,\nexamples, units, and the network-free check/provision split.\n\nA local test or build is not hosted CI, a CPAN publication, or a deployed site.\nNo unrun final-revision gate is implied by these requirements.\n" + }, + { + "path": "docs/fields.md", + "content": "# Entity fields\n\nGenerated from the packaged field catalog. Missing fields throw; known null is explicit.\n\n| Entity | Field | Wire | Type | Nullable | tmux source / minimum |\n| --- | --- | --- | --- | --- | --- |\n| client | height | height | integer | no | client_height / 3.3a |\n| client | id | id | string | no | client_name / 3.3a |\n| client | name | name | string | no | client_name / 3.3a |\n| client | pid | pid | integer | no | client_pid / 3.3a |\n| client | session | session | relation | yes | captured graph |\n| client | tty | tty | bytes | no | client_tty / 3.3a |\n| client | width | width | integer | no | client_width / 3.3a |\n| pane | active | active | boolean | no | pane_active / 3.3a |\n| pane | current_command | currentCommand | string | no | pane_current_command / 3.3a |\n| pane | current_path | currentPath | bytes | no | pane_current_path / 3.3a |\n| pane | cursor_shape | cursorShape | string | no | cursor_shape / 3.6 |\n| pane | dead | dead | boolean | no | pane_dead / 3.3a |\n| pane | exit_status | exitStatus | integer | yes | pane_dead_status / 3.3a |\n| pane | height | height | integer | no | pane_height / 3.3a |\n| pane | id | id | string | no | pane_id / 3.3a |\n| pane | index | index | integer | no | pane_index / 3.3a |\n| pane | pid | pid | integer | no | pane_pid / 3.3a |\n| pane | title | title | string | no | pane_title / 3.3a |\n| pane | width | width | integer | no | pane_width / 3.3a |\n| pane | window | window | relation | no | captured graph |\n| session | attached | attached | integer | no | session_attached / 3.3a |\n| session | created | created | integer | no | session_created / 3.3a |\n| session | id | id | string | no | session_id / 3.3a |\n| session | name | name | string | no | session_name / 3.3a |\n| session | path | path | bytes | no | session_path / 3.3a |\n| session | window_links | windowLinks | relation | no | captured graph |\n| window | active_pane | activePane | relation | yes | captured graph |\n| window | height | height | integer | no | window_height / 3.3a |\n| window | id | id | string | no | window_id / 3.3a |\n| window | layout | layout | string | no | window_layout / 3.3a |\n| window | links | links | relation | no | captured graph |\n| window | name | name | string | no | window_name / 3.3a |\n| window | panes | panes | relation | no | captured graph |\n| window | width | width | integer | no | window_width / 3.3a |\n| window_link | active | active | boolean | no | window_active / 3.3a |\n| window_link | id | id | string | no | captured graph |\n| window_link | index | index | integer | no | window_index / 3.3a |\n| window_link | session | session | relation | no | captured graph |\n| window_link | window | window | relation | no | captured graph |\n" + }, + { + "path": "docs/async.md", + "content": "---\ntitle: Optional Future execution\ndescription: Optional Future execution with the Perl libtmux distributions.\n---\n\nInstall the separate LibTmux-Async distribution to use an injected\n`IO::Async::Loop` and Future-returning Server facade. Core and workspace do not\nload this dependency. Caller-side Future::AsyncAwait syntax is optional.\n\nThe caller owns and drives the loop. Each operation resolves to one value;\nvoid methods yield one undef. Command preparation, framing, identity, and\nparsing are shared with core. Captured selections stay synchronous and local.\n\nTransport bounds concurrent jobs and pending requests. Queue overflow fails\nbefore dispatch. Cancellation suppresses subsequent continuations and requests\ncleanup; it cannot undo accepted effects. Close cancels queued/running work,\nrejects new admissions, and returns a fresh cleanup observer. Only successful\n`is_done` proves cleanup. Cancelling that observer cannot cancel private cleanup.\nKeep driving the borrowed loop through shutdown; closing preserves the server.\n\nPersistent control, streaming subscriptions, and tmux command lists are deferred.\nOrdered batch requests are independent submissions with individual attribution.\n" + }, + { + "path": "docs/workspace.md", + "content": "---\ntitle: Load a JSON workspace\ndescription: Load a JSON workspace with the Perl libtmux distributions.\n---\n\nThe separate distribution packages the `libtmux-workspace` CLI. Validate and\nplan without tmux I/O; load explicitly through public core APIs.\n\n```json\n{\n \"schema\": \"libtmux.workspace/v1\",\n \"sessions\": [{\n \"name\": \"main\",\n \"windows\": [{\n \"name\": \"api\",\n \"layout\": \"even-horizontal\",\n \"panes\": [\n {\"command\": [\"/bin/sleep\", \"120\"]},\n {\"command\": [\"/bin/sleep\", \"120\"], \"horizontal\": true}\n ]\n }]\n }]\n}\n```\n\n```console\n$ libtmux-workspace validate workspace.json\n```\n\n```console\n$ libtmux-workspace plan workspace.json\n```\n\n```console\n$ libtmux-workspace load workspace.json \\\n --socket-name example \\\n --existing skip\n```\n\n`--dry-run` selects a nonmutating plan. Default `existing=error` checks all\nsession-name conflicts before creation. `skip` preserves the entire existing\nsession; repeated loads create only absent sessions. This is not convergence\nor reconciliation of an existing layout.\n\nEach pane requires literal `command` argv or explicit `shell_command`.\nEnvironment inherits workspace → session → window → pane; cwd inherits from\nwindow unless overridden. Layout applies after splitting. Configuration is\nversioned JSON; no YAML adapter or MCP consumer is selected.\n\nOn failure, inspect completed steps, failed step, created IDs, dispatch\nuncertainty, and cleanup errors. Rollback targets only sessions proven created\nby this invocation. Application readiness requires caller-specific assertions.\nCLI exit statuses: success 0; usage/configuration 2; loading 3; conflict 4.\n" + } + ] +} diff --git a/site/src/data/registry.json b/site/src/data/registry.json index 86e3a7125..3c2d9c77f 100644 --- a/site/src/data/registry.json +++ b/site/src/data/registry.json @@ -157,6 +157,36 @@ "version": "0.1.0", "release": "0.1.0", "tag": "0.1.0" + }, + "perl": { + "status": "unpublished", + "version": null, + "release": null, + "tag": null, + "maturity": "unreleased", + "packages": { + "LibTmux": { + "status": "unpublished", + "version": null, + "release": null, + "tag": null, + "maturity": "unreleased" + }, + "LibTmux-Async": { + "status": "unpublished", + "version": null, + "release": null, + "tag": null, + "maturity": "unreleased" + }, + "LibTmux-Workspace": { + "status": "unpublished", + "version": null, + "release": null, + "tag": null, + "maturity": "unreleased" + } + } } } } diff --git a/site/src/data/tmux-usage/perl.json b/site/src/data/tmux-usage/perl.json new file mode 100644 index 000000000..23d767ade --- /dev/null +++ b/site/src/data/tmux-usage/perl.json @@ -0,0 +1,2173 @@ +{ + "commands": [ + "attach-session", + "bind-key", + "break-pane", + "capture-pane", + "choose-buffer", + "choose-client", + "choose-tree", + "clear-history", + "clear-prompt-history", + "clock-mode", + "command-prompt", + "confirm-before", + "copy-mode", + "customize-mode", + "delete-buffer", + "detach-client", + "display-menu", + "display-message", + "display-panes", + "display-popup", + "find-window", + "has-session", + "if-shell", + "join-pane", + "kill-pane", + "kill-server", + "kill-session", + "kill-window", + "last-pane", + "last-window", + "link-window", + "list-buffers", + "list-clients", + "list-commands", + "list-keys", + "list-panes", + "list-sessions", + "list-windows", + "load-buffer", + "lock-client", + "lock-server", + "lock-session", + "move-pane", + "move-window", + "new-pane", + "new-session", + "new-window", + "next-layout", + "next-window", + "paste-buffer", + "pipe-pane", + "previous-layout", + "previous-window", + "refresh-client", + "rename-session", + "rename-window", + "resize-pane", + "resize-window", + "respawn-pane", + "respawn-window", + "rotate-window", + "run-shell", + "save-buffer", + "select-layout", + "select-pane", + "select-window", + "send-keys", + "send-prefix", + "server-access", + "set-buffer", + "set-environment", + "set-hook", + "set-option", + "set-window-option", + "show-buffer", + "show-environment", + "show-hooks", + "show-messages", + "show-options", + "show-prompt-history", + "show-window-options", + "source-file", + "split-window", + "start-server", + "suspend-client", + "swap-pane", + "swap-window", + "switch-client", + "unbind-key", + "unlink-window", + "wait-for" + ], + "port": "perl", + "repo": "libtmux/libtmux-perl", + "revision": "36b978c5eb6aa33873229046037e7d26136ca2cf", + "schemaVersion": 1, + "symbols": { + "LibTmux::Async::Server::capture_pane": [ + { + "command": "capture-pane", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:82", + "packages/core/lib/LibTmux/Server.pm:671" + ], + "reviewed": true, + "scope": null + }, + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:82", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + } + ], + "LibTmux::Async::Server::clients": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:87", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:87", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-panes", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:87", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:87", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-windows", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:87", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server" + } + ], + "LibTmux::Async::Server::delete_buffer": [ + { + "command": "delete-buffer", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:103", + "packages/core/lib/LibTmux/Server.pm:757" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::detach_client": [ + { + "command": "detach-client", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:89", + "packages/core/lib/LibTmux/Server.pm:614" + ], + "reviewed": true, + "scope": null + }, + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:89", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + } + ], + "LibTmux::Async::Server::get_environment": [ + { + "command": "show-environment", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:96", + "packages/core/lib/LibTmux/Server.pm:730" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::get_option": [ + { + "command": "show-options", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:91", + "packages/core/lib/LibTmux/Server.pm:697" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::kill_pane": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:83", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "kill-pane", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:83", + "packages/core/lib/LibTmux/Server.pm:611" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::kill_server": [ + { + "command": "kill-server", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:86", + "packages/core/lib/LibTmux/Server.pm:634" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::kill_session": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:85", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "kill-session", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:85", + "packages/core/lib/LibTmux/Server.pm:613" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::kill_window": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:84", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "kill-window", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:84", + "packages/core/lib/LibTmux/Server.pm:612" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::link_window": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:72", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "link-window", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:72", + "packages/core/lib/LibTmux/Server.pm:577" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::listings": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:61", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:61", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null, + "when": "kind is client" + }, + { + "command": "list-panes", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:61", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server", + "when": "kind is pane" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:61", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null, + "when": "kind is session" + }, + { + "command": "list-windows", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:61", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server", + "when": "kind is window" + } + ], + "LibTmux::Async::Server::move_window": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:74", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "move-window", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:74", + "packages/core/lib/LibTmux/Server.pm:593" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::new_session": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:64", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:64", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-panes", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:64", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:64", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-windows", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:64", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "new-session", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:64", + "packages/core/lib/LibTmux/Server.pm:522" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::new_window": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:65", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:65", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-panes", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:65", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:65", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-windows", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:65", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "new-window", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:65", + "packages/core/lib/LibTmux/Server.pm:547" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::query_panes": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:68", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:68", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-panes", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:68", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:68", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-windows", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:68", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server" + } + ], + "LibTmux::Async::Server::rename_session": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:70", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "rename-session", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:70", + "packages/core/lib/LibTmux/Server.pm:604" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::rename_window": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:71", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "rename-window", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:71", + "packages/core/lib/LibTmux/Server.pm:606" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::resize_pane": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:78", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "resize-pane", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:78", + "packages/core/lib/LibTmux/Server.pm:646" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::select_layout": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:77", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "select-layout", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:77", + "packages/core/lib/LibTmux/Server.pm:610" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::select_pane": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:76", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "select-pane", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:76", + "packages/core/lib/LibTmux/Server.pm:609" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::select_window": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:75", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "select-window", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:75", + "packages/core/lib/LibTmux/Server.pm:608" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::send_keys": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:80", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "send-keys", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:80", + "packages/core/lib/LibTmux/Server.pm:661" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::send_text": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:81", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "send-keys", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:81", + "packages/core/lib/LibTmux/Server.pm:661" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::set_buffer": [ + { + "command": "load-buffer", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:101", + "packages/core/lib/LibTmux/Server.pm:755" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::set_environment": [ + { + "command": "set-environment", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:95", + "packages/core/lib/LibTmux/Server.pm:731" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::set_hook": [ + { + "command": "set-hook", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:93", + "packages/core/lib/LibTmux/Server.pm:716" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::set_option": [ + { + "command": "set-option", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:90", + "packages/core/lib/LibTmux/Server.pm:697" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::set_title": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:79", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "select-pane", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:79", + "packages/core/lib/LibTmux/Server.pm:609" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::show_buffer": [ + { + "command": "show-buffer", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:102", + "packages/core/lib/LibTmux/Server.pm:756" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::show_hooks": [ + { + "command": "show-hooks", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:94", + "packages/core/lib/LibTmux/Server.pm:716" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::snapshot": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:67", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:67", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-panes", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:67", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:67", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-windows", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:67", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server" + } + ], + "LibTmux::Async::Server::split_pane": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:66", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:66", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-panes", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:66", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:66", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-windows", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:66", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "split-window", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:66", + "packages/core/lib/LibTmux/Server.pm:547" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::unlink_window": [ + { + "command": "display-message", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:73", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "unlink-window", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:73", + "packages/core/lib/LibTmux/Server.pm:607" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::unset_environment": [ + { + "command": "set-environment", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:99", + "packages/core/lib/LibTmux/Server.pm:731" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Async::Server::unset_option": [ + { + "command": "set-option", + "evidence": [ + "packages/async/lib/LibTmux/Async/Server.pm:42", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/async/lib/LibTmux/Async/Server.pm:92", + "packages/core/lib/LibTmux/Server.pm:697" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::capture_pane": [ + { + "command": "capture-pane", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1036", + "packages/core/lib/LibTmux/Server.pm:671" + ], + "reviewed": true, + "scope": null + }, + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1036", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + } + ], + "LibTmux::Server::clients": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1054", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1054", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-panes", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1054", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1054", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-windows", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1054", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server" + } + ], + "LibTmux::Server::delete_buffer": [ + { + "command": "delete-buffer", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1098", + "packages/core/lib/LibTmux/Server.pm:757" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::detach_client": [ + { + "command": "detach-client", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1057", + "packages/core/lib/LibTmux/Server.pm:614" + ], + "reviewed": true, + "scope": null + }, + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1057", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + } + ], + "LibTmux::Server::get_environment": [ + { + "command": "show-environment", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1082", + "packages/core/lib/LibTmux/Server.pm:730" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::get_option": [ + { + "command": "show-options", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1065", + "packages/core/lib/LibTmux/Server.pm:697" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::kill_pane": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1040", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "kill-pane", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1040", + "packages/core/lib/LibTmux/Server.pm:611" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::kill_server": [ + { + "command": "kill-server", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1052", + "packages/core/lib/LibTmux/Server.pm:634" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::kill_session": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1048", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "kill-session", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1048", + "packages/core/lib/LibTmux/Server.pm:613" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::kill_window": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1044", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "kill-window", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1044", + "packages/core/lib/LibTmux/Server.pm:612" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::link_window": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:996", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "link-window", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:996", + "packages/core/lib/LibTmux/Server.pm:577" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::listings": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:948", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:948", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null, + "when": "kind is client" + }, + { + "command": "list-panes", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:948", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server", + "when": "kind is pane" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:948", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null, + "when": "kind is session" + }, + { + "command": "list-windows", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:948", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server", + "when": "kind is window" + } + ], + "LibTmux::Server::move_window": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1004", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "move-window", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1004", + "packages/core/lib/LibTmux/Server.pm:593" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::new_session": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:967", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:967", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-panes", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:967", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:967", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-windows", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:967", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "new-session", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:967", + "packages/core/lib/LibTmux/Server.pm:522" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::new_window": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:971", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:971", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-panes", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:971", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:971", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-windows", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:971", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "new-window", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:971", + "packages/core/lib/LibTmux/Server.pm:547" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::query_panes": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:980", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:980", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-panes", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:980", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:980", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-windows", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:980", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server" + } + ], + "LibTmux::Server::rename_session": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:988", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "rename-session", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:988", + "packages/core/lib/LibTmux/Server.pm:604" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::rename_window": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:992", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "rename-window", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:992", + "packages/core/lib/LibTmux/Server.pm:606" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::resize_pane": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1020", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "resize-pane", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1020", + "packages/core/lib/LibTmux/Server.pm:646" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::select_layout": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1016", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "select-layout", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1016", + "packages/core/lib/LibTmux/Server.pm:610" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::select_pane": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1012", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "select-pane", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1012", + "packages/core/lib/LibTmux/Server.pm:609" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::select_window": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1008", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "select-window", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1008", + "packages/core/lib/LibTmux/Server.pm:608" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::send_keys": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1028", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "send-keys", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1028", + "packages/core/lib/LibTmux/Server.pm:661" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::send_text": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1032", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "send-keys", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1032", + "packages/core/lib/LibTmux/Server.pm:661" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::set_buffer": [ + { + "command": "load-buffer", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1090", + "packages/core/lib/LibTmux/Server.pm:755" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::set_environment": [ + { + "command": "set-environment", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1078", + "packages/core/lib/LibTmux/Server.pm:731" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::set_hook": [ + { + "command": "set-hook", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1071", + "packages/core/lib/LibTmux/Server.pm:716" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::set_option": [ + { + "command": "set-option", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1061", + "packages/core/lib/LibTmux/Server.pm:697" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::set_title": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1024", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "select-pane", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1024", + "packages/core/lib/LibTmux/Server.pm:609" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::show_buffer": [ + { + "command": "show-buffer", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1094", + "packages/core/lib/LibTmux/Server.pm:756" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::show_hooks": [ + { + "command": "show-hooks", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1074", + "packages/core/lib/LibTmux/Server.pm:716" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::snapshot": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:977", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:977", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-panes", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:977", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:977", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null + }, + { + "command": "list-windows", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:977", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server" + } + ], + "LibTmux::Server::split_pane": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:975", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "list-clients", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:975", + "packages/core/lib/LibTmux/Server.pm:157" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-panes", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:975", + "packages/core/lib/LibTmux/Server.pm:156" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "list-sessions", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:975", + "packages/core/lib/LibTmux/Server.pm:154" + ], + "reviewed": true, + "scope": null, + "when": "after accepted creation" + }, + { + "command": "list-windows", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:975", + "packages/core/lib/LibTmux/Server.pm:155" + ], + "reviewed": true, + "scope": "server", + "when": "after accepted creation" + }, + { + "command": "split-window", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:975", + "packages/core/lib/LibTmux/Server.pm:547" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::unlink_window": [ + { + "command": "display-message", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1000", + "packages/core/lib/LibTmux/Server.pm:130" + ], + "reviewed": true, + "scope": null, + "when": "daemon identity or target preflight" + }, + { + "command": "unlink-window", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1000", + "packages/core/lib/LibTmux/Server.pm:607" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::unset_environment": [ + { + "command": "set-environment", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1086", + "packages/core/lib/LibTmux/Server.pm:731" + ], + "reviewed": true, + "scope": null + } + ], + "LibTmux::Server::unset_option": [ + { + "command": "set-option", + "evidence": [ + "packages/core/lib/LibTmux/Server.pm:932", + "packages/core/lib/LibTmux/Server.pm:845", + "packages/core/lib/LibTmux/Server.pm:1069", + "packages/core/lib/LibTmux/Server.pm:697" + ], + "reviewed": true, + "scope": null + } + ] + } +} diff --git a/site/src/db/seed.ts b/site/src/db/seed.ts index b66c91e4e..1d098100d 100644 --- a/site/src/db/seed.ts +++ b/site/src/db/seed.ts @@ -1,7 +1,7 @@ import { DatabaseSync } from 'node:sqlite' import { existsSync, mkdirSync, readFileSync, renameSync, rmSync } from 'node:fs' import { dirname, join } from 'node:path' -import { CONCEPTS } from '@libtmux/api-model' +import { CONCEPTS } from '@libtmux/api-model/reference' import { DB_PATH, MODEL_DIR, SCHEMA_PATH, SITE_ROOT } from './paths' import { PORTS } from '../lib/ports' diff --git a/site/src/lib/api-glossary-routes.ts b/site/src/lib/api-glossary-routes.ts index 927454a23..832489bab 100644 --- a/site/src/lib/api-glossary-routes.ts +++ b/site/src/lib/api-glossary-routes.ts @@ -1,5 +1,5 @@ /** The glossary pages served beside each available API reference. */ -import { symbolsForProduct } from '@libtmux/api-model' +import { symbolsForProduct } from '@libtmux/api-model/reference' import { API_MODELS } from './api-models.ts' import { apiGlossary, API_GLOSSARY_PATH } from './api-glossary.ts' import { buildLocale, DEFAULT_LOCALE } from '../i18n/locales.ts' diff --git a/site/src/lib/api-models.ts b/site/src/lib/api-models.ts index 5bf18a561..299b6d723 100644 --- a/site/src/lib/api-models.ts +++ b/site/src/lib/api-models.ts @@ -1,4 +1,6 @@ -import { conceptsFor, isMemberOwner, OWNER_KINDS, parameterId, parentInventory, sourceUrl, SymbolIndex, type ApiModel, type ApiModelBase, type ApiSymbol, type InventoryEntry } from '@libtmux/api-model' +import perlModel from '../data/api/perl.json' +import perlNav from '../data/api/perl.nav.json' +import { conceptsFor, isMemberOwner, OWNER_KINDS, parameterId, parentInventory, sourceUrl, SymbolIndex, type ApiModel, type ApiModelBase, type ApiSymbol, type InventoryEntry } from '@libtmux/api-model/reference' import mentionIndex from '../data/mentions.json' import domInv from '../data/inventories/dom.entries.json' import jdkInv from '../data/inventories/jdk.entries.json' @@ -52,6 +54,7 @@ import fsharpNav from '../data/api/fsharp.nav.json' * passed. Imports are visible to both. */ export const API_MODELS: Record = { + perl: perlModel as unknown as ApiModel, powershell: powershellModel as unknown as ApiModel, julia: juliaModel as unknown as ApiModel, elixir: elixirModel as unknown as ApiModel, @@ -115,6 +118,7 @@ export interface PortNavData { * what a page renders cannot disagree. */ export const API_NAV: Record = { + perl: perlNav as unknown as PortNavData, powershell: powershellNav as unknown as PortNavData, julia: juliaNav as unknown as PortNavData, elixir: elixirNav as unknown as PortNavData, @@ -133,9 +137,10 @@ export const API_NAV: Record = { fsharp: fsharpNav as unknown as PortNavData, } -export { isMemberOwner, OWNER_KINDS } from '@libtmux/api-model' +export { isMemberOwner, OWNER_KINDS } from '@libtmux/api-model/reference' export const PORT_NAME: Record = { + perl: 'Perl', powershell: 'PowerShell', julia: 'Julia', elixir: 'Elixir', diff --git a/site/src/lib/api-relationships.ts b/site/src/lib/api-relationships.ts index 1b03c698f..ef0ff1b78 100644 --- a/site/src/lib/api-relationships.ts +++ b/site/src/lib/api-relationships.ts @@ -1,5 +1,5 @@ import type { ApiModelBase, ApiSymbol } from '@libtmux/api-model' -import { sourceUrl } from '@libtmux/api-model' +import { sourceUrl } from '@libtmux/api-model/products' type Reference = NonNullable[number] export interface ApiRelationship { diff --git a/site/src/lib/api-sections.ts b/site/src/lib/api-sections.ts index 982fd64ee..bc424522d 100644 --- a/site/src/lib/api-sections.ts +++ b/site/src/lib/api-sections.ts @@ -1,5 +1,5 @@ import { createHash } from 'node:crypto' -import { commandFacts, memberTier, moduleOf, parameterBindingFacts, parameterBindingText, qualifiedNameOf, typeParametersOf, type ApiModelBase, type ApiSymbol, type MemberSignals, type Param, type Signature, type SymbolIndex } from '@libtmux/api-model' +import { commandFacts, memberTier, moduleOf, parameterBindingFacts, parameterBindingText, qualifiedNameOf, typeParametersOf, type ApiModelBase, type ApiSymbol, type MemberSignals, type Param, type Signature, type SymbolIndex } from '@libtmux/api-model/reference' import { apiGlossaryHref } from './api-glossary' import { relatedLabels } from './api-labels' import { csharpParameters, supportsCSharpSignatures, supportsElixirSignatures, supportsGoSignatures, supportsJavaSignatures, supportsLuaSignatures, supportsRubySignatures, supportsRustSignatures, supportsTypeScriptSignatures, swiftBaseName } from './code-layout' @@ -228,7 +228,7 @@ export function aliasDeclaration(symbol: ApiSymbol, language?: string): { name: /** Keep native declaration syntax consistent in HTML and copied Markdown. */ export function usesNativeSignatures(symbol: ApiSymbol, port?: string): boolean { - return (port === 'rs' && Boolean(symbol.variant)) || supportsRustSignatures(symbol, port) || supportsTypeScriptSignatures(symbol, port) || supportsGoSignatures(symbol, port) || supportsJavaSignatures(symbol, port) || supportsCSharpSignatures(symbol, port) || supportsRubySignatures(symbol, port) || supportsLuaSignatures(symbol, port) || supportsElixirSignatures(symbol, port) || ['kotlin', 'scala', 'fsharp', 'c', 'powershell', 'julia'].includes(port ?? '') || + return (port === 'rs' && Boolean(symbol.variant)) || supportsRustSignatures(symbol, port) || supportsTypeScriptSignatures(symbol, port) || supportsGoSignatures(symbol, port) || supportsJavaSignatures(symbol, port) || supportsCSharpSignatures(symbol, port) || supportsRubySignatures(symbol, port) || supportsLuaSignatures(symbol, port) || supportsElixirSignatures(symbol, port) || ['perl', 'kotlin', 'scala', 'fsharp', 'c', 'powershell', 'julia'].includes(port ?? '') || (port === 'cxx' && symbol.signatures.length > 0 && symbol.signatures.every((signature) => Boolean(signature.raw))) } @@ -416,7 +416,7 @@ export function apiMethodDetails(symbol: ApiSymbol) { const labels = signatureLabels(symbol) return symbol.signatures.flatMap((signature, i) => signature.methodKind ? [{ signature, - id: `${symbol.publicId ?? symbol.id}.method-${createHash('sha256').update(signature.identity!).digest('hex').slice(0, 16)}`, + id: `${symbol.publicId ?? symbol.id}.method-${createHash('sha256').update(apiOverloadIdentity(signature)).digest('hex').slice(0, 16)}`, label: signature.raw ?? signature.label ?? symbol.name, overloadLabel: labels[i], }] : []) diff --git a/site/src/lib/api-tmux-sections.ts b/site/src/lib/api-tmux-sections.ts index 823c16414..2153ef08c 100644 --- a/site/src/lib/api-tmux-sections.ts +++ b/site/src/lib/api-tmux-sections.ts @@ -4,7 +4,7 @@ * One derivation feeds the HTML sections (`ApiTmuxSections.astro`), the "On this page" entries and the Markdown export, * so the three cannot list different rows. A section with nothing to say is not returned. */ -import { qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model' +import { qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS, PORT_NAME, mentionsOf, referenceAlternatives } from './api-models' import { proseHref } from './docs-paths' import type { ApiRelationshipPath } from './api-relationships' diff --git a/site/src/lib/api-tree.ts b/site/src/lib/api-tree.ts index 4e9379ebe..766cb0c7c 100644 --- a/site/src/lib/api-tree.ts +++ b/site/src/lib/api-tree.ts @@ -5,7 +5,7 @@ * Buckets and their contents are decided once per port in * `scripts/gen-api-model.mjs`; this only shapes them for a tree. */ -import { membersOf, memberSignals, symbolsForProduct, type ApiModel, type ApiModelBase, type ApiSymbol } from '@libtmux/api-model' +import { membersOf, memberSignals, symbolsForProduct, type ApiModel, type ApiModelBase, type ApiSymbol } from '@libtmux/api-model/reference' import mentions from '../data/mentions.json' import { API_MODELS, API_NAV, OWNER_KINDS, isMemberOwner, pageSlug, referenceHref, topLevelTypesOf, type NavEntry, type PortNavData, type NavBucket } from './api-models' import type { ApiTreeBucket, ApiTreeJson } from './api-search' diff --git a/site/src/lib/brand-palettes.json b/site/src/lib/brand-palettes.json index 786aa18b1..630efa099 100644 --- a/site/src/lib/brand-palettes.json +++ b/site/src/lib/brand-palettes.json @@ -414,5 +414,31 @@ "solid": "#54167b", "onSolid": "#ffffff" } + }, + "perl": { + "name": "Perl", + "color": "#0298C3", + "light": { + "background": "#fafbfc", + "surface": "#f3f5f7", + "hover": "#e9edf1", + "border": "#d6dce3", + "text": "#202830", + "muted": "#53606d", + "link": "#045c77", + "solid": "#045c77", + "onSolid": "#ffffff" + }, + "dark": { + "background": "#15191d", + "surface": "#1c2229", + "hover": "#29323d", + "border": "#3e4a57", + "text": "#e7edf3", + "muted": "#b7c1cd", + "link": "#a6def0", + "solid": "#045c77", + "onSolid": "#ffffff" + } } } diff --git a/site/src/lib/code-language.ts b/site/src/lib/code-language.ts new file mode 100644 index 000000000..f5944d955 --- /dev/null +++ b/site/src/lib/code-language.ts @@ -0,0 +1,32 @@ +/** Unsupported doc-comment labels retain a plain-text frame instead of failing builds. */ +const EC_LANGS = new Set([ + 'perl', 'python', 'ruby', 'lua', 'rust', 'ts', 'tsx', 'js', 'jsx', 'java', 'kotlin', 'scala', 'fsharp', 'swift', + 'csharp', 'cpp', 'c', 'go', 'bash', 'shell', 'console', 'json', 'yaml', + 'toml', 'xml', 'diff', 'text', 'tmux-usage', 'tmux-shell', 'tmux-config', 'powershell', 'julia', 'elixir', 'properties', 'ini', + 'cmake', +]) + +const EC_ALIASES: Record = { + typescript: 'ts', + javascript: 'js', + 'c++': 'cpp', + cxx: 'cpp', + py: 'python', + rs: 'rust', + 'c#': 'csharp', + cs: 'csharp', + ex: 'elixir', + exs: 'elixir', + sh: 'bash', + zsh: 'bash', + shellsession: 'console', + tmux: 'tmux-config', + plaintext: 'text', + '': 'text', +} + +export function codeLang(lang?: string): string { + const name = (lang ?? '').trim().toLowerCase() + const resolved = EC_ALIASES[name] ?? name + return EC_LANGS.has(resolved) ? resolved : 'text' +} diff --git a/site/src/lib/code-layout.ts b/site/src/lib/code-layout.ts index 7abe54eb8..b0a2a0454 100644 --- a/site/src/lib/code-layout.ts +++ b/site/src/lib/code-layout.ts @@ -1,4 +1,6 @@ -import { parameterId, qualifiedNameOf, type ApiSymbol, type Signature, type SymbolIndex } from '@libtmux/api-model' +import type { ApiSymbol, Signature, SymbolIndex } from '@libtmux/api-model' +import { parameterId } from '@libtmux/api-model/link' +import { qualifiedNameOf } from '@libtmux/api-model/modules' /** Documentation surface budgets, independent of a port's source formatter. */ export const CODE_COLUMNS = { api: 60, example: 80 } as const @@ -292,6 +294,13 @@ export function supportsCSignatures(symbol: ApiSymbol, language?: string): boole /** Prepare one layout per overload for both HTML and the Markdown twin. */ export async function apiSignatureLayouts(symbol: ApiSymbol, language?: string): Promise> { + if (language === 'perl' && symbol.signatures.length) { + return new Map(await Promise.all(symbol.signatures.map(async (signature) => { + if (!signature.raw) throw new Error(`Missing native Perl declaration: ${symbol.id}`) + return [signature, { text: signature.raw, limit: CODE_COLUMNS.api, + failures: await codeWidthFailures(signature.raw, 'api'), syntax: signature.nativeSyntax }] as const + }))) + } if (language === 'rs' && ['method', 'function'].includes(symbol.kind) && symbol.signatures.length && !supportsRustSignatures(symbol, language)) { throw new Error(`Unavailable native Rust callable header: ${symbol.id}`) } diff --git a/site/src/lib/core-home.ts b/site/src/lib/core-home.ts index 7afb58085..9f8245a0e 100644 --- a/site/src/lib/core-home.ts +++ b/site/src/lib/core-home.ts @@ -9,7 +9,8 @@ * `test/core-home.test.ts`) instead of rendering a dead link or a claim * nothing backs. A capability a port lacks has no entry and is not listed. */ -import { qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model' +import type { ApiSymbol } from '@libtmux/api-model' +import { qualifiedNameOf } from '@libtmux/api-model/modules' import DATA from '../data/core-home.json' import { API_MODELS, referenceHref } from './api-models.ts' import { PORT_BY_SLUG } from './ports.ts' @@ -59,7 +60,7 @@ const CAPABILITY_EVIDENCE: Record ['class', 'struct', 'interface', 'enum', 'trait', 'module', 'typealias', 'function'].includes(symbol.kind) }, ids: { needs: 'an ID type or accessor', test: (symbol) => /\b(id|ID)\b|Id\b|ID\b/.test(symbol.name) }, queries: { needs: 'a filter, query or selection', test: (symbol) => /filter|query|select|where|expr/i.test(symbol.name) }, - errors: { needs: 'an error, exception or failure type', test: (symbol) => /error|exception|failure/i.test(symbol.name) }, + errors: { needs: 'an error, exception or failure type', test: (symbol) => symbol.kind === 'exception' || /error|exception|failure/i.test(symbol.name) }, traversal: { needs: 'a panes, windows, sessions or snapshot accessor', test: (symbol) => /panes|windows|sessions|snapshot/i.test(symbol.name) }, argv: { needs: 'a command or run symbol', test: (symbol) => /cmd|command|run|exec|invoke/i.test(symbol.name) }, 'version-gate': { needs: 'a version or unsupported-feature error', test: (symbol) => /version|unsupported|capabilit/i.test(symbol.name) }, @@ -74,6 +75,8 @@ const CAPABILITY_EVIDENCE: Record capabilities: Partial> } @@ -87,6 +90,7 @@ export interface CoreSymbolLink { } export interface CoreHome { + association?: CoreSymbolLink summary: string objects: (CoreSymbolLink & { role: CoreRole; wraps: string; tmuxId: string })[] capabilities: Record @@ -114,7 +118,7 @@ export function resolveCoreHome(port: string, version: string, entry: CoreHomeEn if (!entry) throw new Error(`core-home: ${port} has no entry`) const objects = CORE_ROLES.map((role) => { if (!entry.objects[role]) throw new Error(`core-home: ${port} names no ${role} type`) - return { role, ...link(port, entry.objects[role], version, role), wraps: TMUX_OBJECTS[role].wraps, tmuxId: TMUX_OBJECTS[role].id } + return { role, ...link(port, entry.objects[role], version, role), wraps: role === 'window' && entry.association ? 'A physical window linked into sessions' : TMUX_OBJECTS[role].wraps, tmuxId: TMUX_OBJECTS[role].id } }) const capabilities: CoreHome['capabilities'] = { typed: [], cli: [] } for (const [key, id] of Object.entries(entry.capabilities)) { @@ -124,7 +128,8 @@ export function resolveCoreHome(port: string, version: string, entry: CoreHomeEn } for (const group of Object.values(capabilities)) group.sort((a, b) => Object.keys(CAPABILITIES).indexOf(a.key) - Object.keys(CAPABILITIES).indexOf(b.key)) - return { summary: coreDescription(port, entry), objects, capabilities } + return { summary: coreDescription(port, entry), objects, capabilities, + ...(entry.association ? { association: link(port, entry.association, version, 'window association') } : {}) } } /** The page's facts as Markdown, for the `.md` twin and llms-full.txt. */ @@ -134,8 +139,10 @@ export function coreHomeMarkdown(port: string, version: string, origin: string): return [ coreLead(port), '## At a glance', - '| Type | Wraps |\n| ---- | ----- |\n' + home.objects.map((object) => - `| [\`${object.name}\`](${at(object.href)}) | ${object.wraps}${object.tmuxId ? `, ID \`${object.tmuxId}n\`` : ''} |`).join('\n'), + '| Type | Wraps |\n| ---- | ----- |\n' + [...home.objects.map((object) => + `| [\`${object.name}\`](${at(object.href)}) | ${object.wraps}${object.tmuxId ? `, ID \`${object.tmuxId}n\`` : ''} |`), + ...(home.association ? [`| [\`${home.association.name}\`](${at(home.association.href)}) | A session-window association, with its index and active state |`] : []), + ].join('\n'), ...Object.entries(CAPABILITY_GROUPS).flatMap(([group, title]) => { const rows = home.capabilities[group as keyof typeof CAPABILITY_GROUPS] return rows.length ? [`## ${title}`, rows.map((row) => `- ${row.label}: [\`${row.name}\`](${at(row.href)})`).join('\n')] : [] diff --git a/site/src/lib/header-links.ts b/site/src/lib/header-links.ts index 3abf04113..5d778c7e9 100644 --- a/site/src/lib/header-links.ts +++ b/site/src/lib/header-links.ts @@ -81,7 +81,7 @@ function drafts(entry: InventoryEntry, home: string): Draft[] { const terms = [entry.label, entry.coordinate, ...entry.aliases, entry.repo, repoName(entry.repo), INVENTORY_KIND_LABEL[entry.kind], ...KIND_TERMS[entry.kind], ...(entry.unit ? [entry.unit] : []), PICKER_GROUP_LABEL[entry.product]] const line = (...parts: (string | undefined)[]) => parts.filter(Boolean).join(' · ') - return entryDestinations(entry).map(({ kind, url, host }): Draft => { + return entryDestinations(entry).filter(({ kind }) => entry.status === 'published' || kind === 'source' && entry.sourceAvailable).map(({ kind, url, host }): Draft => { if (kind === 'source') { // A path in the port's own repository needs no repository name; one in another repository keeps it. const where = entry.path ? (entry.repo === home ? entry.path : `${repoName(entry.repo)}/${entry.path}`) : entry.repo @@ -127,7 +127,7 @@ function indexRows(entries: readonly InventoryEntry[], home: string): HeaderRow[ } export function portHeaderLinks(port: Port, inventory: Readonly> = INVENTORY): PortHeaderLinks { - const entries = (inventory[port.slug] ?? []).filter((entry) => entry.status === 'published') + const entries = (inventory[port.slug] ?? []).filter((entry) => entry.status === 'published' || entry.sourceAvailable) const library = entries.find((entry) => entry.kind === 'library') if (!library) return { actions: [], rows: [], indexed: false } const { source } = portDestinations({ port }) @@ -135,8 +135,8 @@ export function portHeaderLinks(port: Port, inventory: Readonly entry.id === library.reference) - if (library.package) { + const documented = library.status === 'published' && library.api ? library : entries.find((entry) => entry.status === 'published' && entry.id === library.reference) + if (library.status === 'published' && library.package) { const host = PACKAGE_HOSTS[library.package.host] // A host that serves the package page as its reference is one destination, not two, so its one link says it is both. const also = documented?.api?.url === library.package.url ? ' and API reference' : '' diff --git a/site/src/lib/highlight.ts b/site/src/lib/highlight.ts index 790f56782..dce05659b 100644 --- a/site/src/lib/highlight.ts +++ b/site/src/lib/highlight.ts @@ -1,3 +1,5 @@ +import { codeLang } from './code-language' +export { codeLang } from './code-language' import { createHighlighter, type Highlighter, type BundledLanguage } from 'shiki' import { createRenderer } from 'astro-expressive-code' import ecConfig from '../../ec.config.mjs' @@ -24,7 +26,7 @@ let instance: Promise | undefined /** Frequent languages load once; other supported grammars load on demand. */ const LANGS = [ - 'python', 'ruby', 'lua', 'rust', 'ts', 'js', 'bash', 'console', 'json', 'yaml', 'text', + 'perl', 'python', 'ruby', 'lua', 'rust', 'ts', 'js', 'bash', 'console', 'json', 'yaml', 'text', // The install widget's build-file panels: a Gradle script, a Maven POM // fragment, a Package.swift dependency and a CMakeLists block. Three of the // eight ports cannot be installed from a command line at all, so without @@ -116,39 +118,6 @@ export async function highlight(code: string, lang: string): Promise = { - typescript: 'ts', - javascript: 'js', - 'c++': 'cpp', - cxx: 'cpp', - py: 'python', - rs: 'rust', - 'c#': 'csharp', - cs: 'csharp', - ex: 'elixir', - exs: 'elixir', - sh: 'bash', - zsh: 'bash', - shellsession: 'console', - tmux: 'tmux-config', - plaintext: 'text', - '': 'text', -} - -export function codeLang(lang?: string): string { - const name = (lang ?? '').trim().toLowerCase() - const resolved = EC_ALIASES[name] ?? name - return EC_LANGS.has(resolved) ? resolved : 'text' -} - /** Inert themed tokens; browsers construct text nodes rather than parsing HTML. */ export interface CodeHighlight { language: string diff --git a/site/src/lib/inventory-publisher.ts b/site/src/lib/inventory-publisher.ts index 774a59032..0f50c999b 100644 --- a/site/src/lib/inventory-publisher.ts +++ b/site/src/lib/inventory-publisher.ts @@ -1,6 +1,6 @@ import { mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs' import { dirname, join } from 'node:path' -import { compatibilityEntries, targetEntries, targetKey, writeInventoryEntries } from '@libtmux/api-model' +import { compatibilityEntries, targetEntries, targetKey, writeInventoryEntries } from '@libtmux/api-model/reference' import { installFragmentAlias, mergeTargets, renderedTargets, type InventoryAlias, type RenderedTarget } from './inventory-targets.ts' import type { VersionManifest } from './versions.ts' diff --git a/site/src/lib/inventory-targets.ts b/site/src/lib/inventory-targets.ts index 77740a931..049873286 100644 --- a/site/src/lib/inventory-targets.ts +++ b/site/src/lib/inventory-targets.ts @@ -1,6 +1,6 @@ import { fromHtml } from 'hast-util-from-html' import { parse } from 'parse5' -import { inventoryType, qualifiedNameOf, targetKey, type ApiSymbol, type InventoryTarget, type SymbolKind } from '@libtmux/api-model' +import { inventoryType, qualifiedNameOf, targetKey, type ApiSymbol, type InventoryTarget, type SymbolKind } from '@libtmux/api-model/reference' export interface InventoryPage { scope: string diff --git a/site/src/lib/link-preview.ts b/site/src/lib/link-preview.ts index a72aee9df..dbd8cdc4e 100644 --- a/site/src/lib/link-preview.ts +++ b/site/src/lib/link-preview.ts @@ -1,9 +1,10 @@ -import { docSummaryText, sourceUrl, type ApiModel, type ApiSymbol, type SymbolIndex } from '@libtmux/api-model' +import { docSummaryText, sourceUrl, type ApiModel, type ApiSymbol, type SymbolIndex } from '@libtmux/api-model/reference' import { productApiHref, productApiIndex } from './product-api' import { nativePackageName, nativeShortName } from './native-name' import { PORT_BY_SLUG } from './ports' import { apiGlossary } from './api-glossary' -import { codeLang, highlightTokens, type CodeHighlight } from './highlight' +import { codeLang } from './code-language' +import type { CodeHighlight } from './highlight' import { linkPreviewTarget } from './link-preview-paint' import { tmuxEntityHref } from './tmux-links' import { tmuxManual, tmuxManualEntities, tmuxManualEntityHref, tmuxManualUrl, type TmuxManualEntity } from './tmux-manual-data' @@ -105,6 +106,7 @@ export function symbolPreview(model: ApiModel, symbol: ApiSymbol, version: strin /** Highlight at endpoint generation without putting a highlighter in the browser. */ export async function highlightedPreview(preview: LinkPreview): Promise { if (!preview.signature) return preview + const { highlightTokens } = await import('./highlight') return { ...preview, signatureHighlight: await highlightTokens(preview.signature, preview.signatureLanguage ?? 'text') } } diff --git a/site/src/lib/llms.ts b/site/src/lib/llms.ts index 26689f957..74c0040c8 100644 --- a/site/src/lib/llms.ts +++ b/site/src/lib/llms.ts @@ -3,7 +3,7 @@ * API references are linked, rather than inlined into the full prose export. */ import { getCollection } from 'astro:content' -import { qualifiedNameOf } from '@libtmux/api-model' +import { qualifiedNameOf } from '@libtmux/api-model/reference' import type { CollectionEntry } from 'astro:content' import { resolvePortCode } from '../plugins/remark-port-code.mjs' import { PORTS, PORT_BY_SLUG, hasReference, portPageUrl, productApiPath, productAvailable, productConceptNotice, referenceUrl, workspaceOverviewNotice } from './ports.ts' diff --git a/site/src/lib/mcp-preview.ts b/site/src/lib/mcp-preview.ts index 5e36b01a8..0b2a04b39 100644 --- a/site/src/lib/mcp-preview.ts +++ b/site/src/lib/mcp-preview.ts @@ -1,4 +1,4 @@ -import { docSummaryText, tokenizeDoc } from '@libtmux/api-model' +import { docSummaryText, tokenizeDoc } from '@libtmux/api-model/reference' import { MCP_SECTIONS, resolveMcpObject, type McpObject } from './mcp-catalog' import { previewRuns, type LinkPreview, type PreviewReference } from './link-preview' import { PORT_BY_SLUG, portPageUrl } from './ports' diff --git a/site/src/lib/mcp-reference.ts b/site/src/lib/mcp-reference.ts index b20a27af0..a1c3feefe 100644 --- a/site/src/lib/mcp-reference.ts +++ b/site/src/lib/mcp-reference.ts @@ -1,6 +1,6 @@ import { MCP_REFERENCE, MCP_SECTIONS, mcpObjects, resolveMcpObject, type McpRegistration, type McpObject, type McpSection } from './mcp-catalog' import { createMarkdownProcessor } from '@astrojs/markdown-remark' -import { docSummaryText } from '@libtmux/api-model' +import { docSummaryText } from '@libtmux/api-model/reference' import { PORT_BY_SLUG, portPageUrl } from './ports' import { restToMarkdown } from './mcp-rest' import { rehypeApiLinks } from '../plugins/rehype-api-links' diff --git a/site/src/lib/mcp-rest.ts b/site/src/lib/mcp-rest.ts index 2222071ce..509700bef 100644 --- a/site/src/lib/mcp-rest.ts +++ b/site/src/lib/mcp-rest.ts @@ -1,4 +1,4 @@ -import { tokenizeDoc } from '@libtmux/api-model' +import { tokenizeDoc } from '@libtmux/api-model/reference' import { API_MODELS } from './api-models' import { asideFor, asideMarkdown } from './aside' import { resolveMcpObject } from './mcp-catalog' diff --git a/site/src/lib/native-name.ts b/site/src/lib/native-name.ts index 0550d62be..79b7e31ef 100644 --- a/site/src/lib/native-name.ts +++ b/site/src/lib/native-name.ts @@ -1,4 +1,5 @@ -import { qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model' +import type { ApiSymbol } from '@libtmux/api-model' +import { qualifiedNameOf } from '@libtmux/api-model/modules' /** * The name a programmer writes for a declaration, in the language's own spelling. diff --git a/site/src/lib/page-port-links.ts b/site/src/lib/page-port-links.ts index 515d4adf8..3933b5187 100644 --- a/site/src/lib/page-port-links.ts +++ b/site/src/lib/page-port-links.ts @@ -1,4 +1,4 @@ -import { symbolsForProduct, type ApiSymbol } from '@libtmux/api-model' +import { symbolsForProduct, type ApiSymbol } from '@libtmux/api-model/reference' import { headingTitle } from './branding' import { API_MODELS, pageSlug, referenceAlternatives, referenceHref } from './api-models' import { DOC_PRODUCTS, PORT_BY_SLUG, PORTS, portHomeUrl, portPageUrl, productAvailable, productExcluded, referenceUrl } from './ports' diff --git a/site/src/lib/port-documentation.ts b/site/src/lib/port-documentation.ts index f290e8adc..d85bd9369 100644 --- a/site/src/lib/port-documentation.ts +++ b/site/src/lib/port-documentation.ts @@ -65,6 +65,26 @@ const libraryDomain = (description: string): DocumentationDomain => ({ }) const PORT_DOCUMENTATION: Readonly> = { + perl: { + domains: [ + libraryDomain('Use explicit tmux commands and captured graph selections with stable Perl.'), + { id: 'async', label: 'Async', kind: 'companion-package', navGroup: 'Library', route: 'guides/async', package: 'async', description: 'Optional Future execution with a caller-owned IO::Async loop.' }, + { id: 'workspace', label: 'Workspace Manager', kind: 'product', navGroup: 'Apps', route: 'workspace', package: 'workspace', product: 'workspace', description: 'Validate, plan, and load versioned JSON workspaces through public core APIs.' }, + ], + sourceGuides: [ + guide('README.md', 'guides/getting-started', 'core', { title: 'Getting started', sidebar: { group: 'Guides', order: 1 } }), + guide('docs/installation.md', 'guides/installation', 'core', { title: 'Installation', sidebar: { group: 'Guides', order: 2 } }), + guide('docs/filtering.md', 'guides/filtering', 'core', { title: 'Filtering' }), + guide('docs/orchestration.md', 'examples/orchestration', 'core', { title: 'Create sessions, windows, and panes', aliases: ['guides/orchestration'] }), + guide('docs/graph.md', 'concepts/graph', 'core', { title: 'Snapshot graph and identity', aliases: ['guides/graph'] }), + guide('docs/fields.md', 'concepts/fields', 'core', { title: 'Entity fields', aliases: ['guides/fields'] }), + guide('docs/query-planning.md', 'topics/query-planning', 'core', { title: 'Live query planning', aliases: ['guides/query-planning'] }), + guide('docs/errors.md', 'topics/errors', 'core', { title: 'Errors and recovery', aliases: ['guides/errors'] }), + guide('docs/compatibility.md', 'topics/compatibility', 'core', { title: 'Linux and tmux compatibility', aliases: ['guides/compatibility'] }), + guide('docs/async.md', 'guides/async', 'async', { package: 'async', title: 'Optional async execution' }), + guide('docs/workspace.md', 'workspace/source-guide', 'workspace', { package: 'workspace', product: 'workspace', title: 'Workspace loading', aliases: [] }), + ], + }, powershell: { domains: [ libraryDomain('Install LibTmux and use cmdlets to read and control tmux.'), diff --git a/site/src/lib/port-families.ts b/site/src/lib/port-families.ts index 7ebee4884..de11daada 100644 --- a/site/src/lib/port-families.ts +++ b/site/src/lib/port-families.ts @@ -10,7 +10,7 @@ export interface PortFamily { * by how they are built and run. A port belongs to one group. */ export const PORT_FAMILIES: readonly PortFamily[] = [ - { label: 'Scripting & web', ports: ['py', 'ruby', 'lua', 'julia', 'ts'] }, + { label: 'Scripting & web', ports: ['py', 'ruby', 'lua', 'julia', 'ts', 'perl'] }, { label: 'Compiled & native', ports: ['rs', 'go', 'cxx', 'swift'] }, { label: 'JVM', ports: ['java', 'kotlin', 'scala'] }, { label: '.NET', ports: ['csharp', 'fsharp', 'powershell'] }, diff --git a/site/src/lib/port-inventory.ts b/site/src/lib/port-inventory.ts index 261c0664b..bc8714ae6 100644 --- a/site/src/lib/port-inventory.ts +++ b/site/src/lib/port-inventory.ts @@ -164,6 +164,8 @@ export interface InventoryEntry { */ reference?: string status: PublicationStatus + /** Source exists publicly even when this distribution has no registry release. */ + sourceAvailable?: boolean /** Why a configured or planned entry has no link. */ note?: string /** @@ -285,6 +287,13 @@ const GO = 'github.com/libtmux/libtmux-go' * testing products in the order a reader reaches for them. */ export const INVENTORY: Readonly> = { + perl: [ + { id: 'LibTmux', kind: 'library', product: 'core', label: 'LibTmux', coordinate: 'LibTmux', aliases: ["LibTmux::Server"], repo: 'libtmux/libtmux-perl', ref: 'master', path: 'packages/core', status: 'configured-unpublished', sourceAvailable: true, note: 'Install from verified source; no CPAN release is published.' }, + { id: 'LibTmux-Async', kind: 'companion', product: 'core', label: 'LibTmux-Async', coordinate: 'LibTmux-Async', aliases: ["LibTmux::Async::Server"], repo: 'libtmux/libtmux-perl', ref: 'master', path: 'packages/async', status: 'configured-unpublished', sourceAvailable: true, note: 'Install from verified source; no CPAN release is published.' }, + { id: 'LibTmux-Workspace', kind: 'companion', product: 'workspace', label: 'LibTmux-Workspace', coordinate: 'LibTmux-Workspace', aliases: ["LibTmux::Workspace"], repo: 'libtmux/libtmux-perl', ref: 'master', path: 'packages/workspace', status: 'configured-unpublished', sourceAvailable: true, note: 'Install from verified source; no CPAN release is published.' }, + { id: 'repository', kind: 'source', product: 'core', label: 'libtmux-perl', coordinate: 'libtmux/libtmux-perl', aliases: [], repo: 'libtmux/libtmux-perl', ref: 'master', status: 'published' }, + { id: 'libtmux-workspace', kind: 'cli', product: 'workspace', label: 'libtmux-workspace', coordinate: 'libtmux-workspace', aliases: ['libtmux-workspace'], within: 'LibTmux-Workspace', unit: 'command', repo: 'libtmux/libtmux-perl', ref: 'master', path: 'packages/workspace/bin/libtmux-workspace', file: true, status: 'configured-unpublished', sourceAvailable: true, note: 'Install from verified source; no CPAN release is published.' }, + ], py: [ py({ id: 'libtmux', kind: 'library', product: 'core', label: 'libtmux', ...pypi('libtmux'), aliases: ['libtmux'] }), // The pytest plugin is an entry point of the libtmux distribution, not a package of its own. diff --git a/site/src/lib/ports.ts b/site/src/lib/ports.ts index 2bdc4156d..c99c034f5 100644 --- a/site/src/lib/ports.ts +++ b/site/src/lib/ports.ts @@ -1256,6 +1256,36 @@ target_link_libraries(your_target PRIVATE libtmux::libtmux)`, installNote: 'A target depends on the product, not the package: write .product(name: "LibTmux", package: "libtmux-swift"). The library is `LibTmux` while the package identity SwiftPM derives from the URL is `libtmux-swift`, which is neither the product name nor the `name:` in the package manifest.', }, + { + slug: 'perl', projectName: 'libtmux-perl', logoLanguage: 'perl', shortName: 'Pl', + name: 'Perl', language: 'Perl', packageName: 'LibTmux', + repo: 'libtmux/libtmux-perl', checkout: '~/work/libtmux/libtmux-perl', + worktree: '~/work/libtmux/libtmux-perl-docs-site', + source: { path: 'packages/core', ref: 'master' }, versionedDocs: true, + tagGrammar: 'semver', publishesOwnTree: true, + renderer: 'astro', generator: 'Perl PPI signatures and native POD', referenceKind: 'model', + workspaceCli: 'libtmux-workspace load', workspaceCliAvailability: 'local', + productAvailability: { workspace: 'available', mcp: 'excluded' }, + packages: [ + { id: 'core', name: 'LibTmux', require: 'LibTmux::Server', source: { path: 'packages/core', ref: 'master' } }, + { id: 'async', name: 'LibTmux-Async', require: 'LibTmux::Async::Server', source: { path: 'packages/async', ref: 'master' }, + installs: [{ label: 'cpm (source)', lang: 'console', code: 'cpm install --global ./packages/async', note: 'From the source checkout after core installation; adds Future and IO::Async.' }] }, + { id: 'workspace', name: 'LibTmux-Workspace', require: 'LibTmux::Workspace', executable: 'libtmux-workspace', + source: { path: 'packages/workspace', ref: 'master' }, + installs: [{ label: 'cpm (source)', lang: 'console', code: 'cpm install --global ./packages/workspace', note: 'From the source checkout after core installation. No CPAN release.' }] }, + ], + installs: [{ label: 'cpm (source)', lang: 'console', + code: 'git clone https://github.com/libtmux/libtmux-perl.git && \\\n cd libtmux-perl && \\\n cpm install --global ./packages/core', + note: 'Unpublished development distribution. Requires Perl 5.44.0, Linux x86_64 LP64, and tmux 3.3a or newer.' }], + initProject: { lang: 'text', code: 'Create a Perl program using LibTmux::Server; install from the source checkout.' }, + installForms: { + release: { lang: 'console', code: 'cpm install --global ./packages/core' }, + prerelease: { lang: 'console', code: 'cpm install --global ./packages/core' }, + git: { lang: 'console', code: 'git clone https://github.com/libtmux/libtmux-perl.git && \\\n cd libtmux-perl && \\\n cpm install --global ./packages/core' }, + }, + installNote: 'Install core before workspace or optional async. These package names do not identify published CPAN releases.', + }, + ] as const type WrapperLibrary = Omit & { diff --git a/site/src/lib/product-api.ts b/site/src/lib/product-api.ts index beb5e7ab9..27c9b7f12 100644 --- a/site/src/lib/product-api.ts +++ b/site/src/lib/product-api.ts @@ -1,4 +1,4 @@ -import { symbolsForProduct, type ApiModel, type ApiSymbol, type SymbolIndex } from '@libtmux/api-model' +import { symbolsForProduct, type ApiModel, type ApiSymbol, type SymbolIndex } from '@libtmux/api-model/reference' import { API_MODELS, createApiIndex, referenceAlternatives } from './api-models' import { PORT_BY_SLUG, portPageUrl, productApiPath, referenceUrl, type DocProduct } from './ports' import type { SidebarItem, SidebarGroupItem } from './sidebar' diff --git a/site/src/lib/prose-markdown.ts b/site/src/lib/prose-markdown.ts index 0e4f7dbfe..8f56730ba 100644 --- a/site/src/lib/prose-markdown.ts +++ b/site/src/lib/prose-markdown.ts @@ -1,6 +1,6 @@ import { fromMarkdown } from 'mdast-util-from-markdown' import { SKIP, visit } from 'unist-util-visit' -import { proseMentions, type ApiProduct } from '@libtmux/api-model' +import { proseMentions, type ApiProduct } from '@libtmux/api-model/reference' import { resolvePortContent } from './workspace-shared-slots' import { createProseLinker, PORT_BY_LABEL, protocolRunMentions } from './prose-resolver' import { PORT_BY_SLUG } from './ports' diff --git a/site/src/lib/prose-resolver.ts b/site/src/lib/prose-resolver.ts index cdaa33e19..77f9cb158 100644 --- a/site/src/lib/prose-resolver.ts +++ b/site/src/lib/prose-resolver.ts @@ -1,4 +1,4 @@ -import { Resolver, decideFilePath, decideMention, notASymbol, parentInventory, type ApiProduct, type InventoryEntry, type MentionContext, type MentionDecision } from '@libtmux/api-model' +import { Resolver, decideFilePath, decideMention, notASymbol, parentInventory, type ApiProduct, type InventoryEntry, type MentionContext, type MentionDecision } from '@libtmux/api-model/reference' import { API_MODELS, PORT_NAME, referenceHref } from './api-models' import { productApiHref } from './product-api' import { PORTS, PORT_BY_SLUG, portPageUrl, referenceUrl } from './ports' diff --git a/site/src/lib/reference-page-links.ts b/site/src/lib/reference-page-links.ts index 63b4e969b..f392cebff 100644 --- a/site/src/lib/reference-page-links.ts +++ b/site/src/lib/reference-page-links.ts @@ -1,4 +1,4 @@ -import { CONCEPTS } from '@libtmux/api-model' +import { CONCEPTS } from '@libtmux/api-model/reference' import { referenceAlternatives } from './api-models' import { PORTS, referenceUrl } from './ports' import { defaultVersionFor } from './versions' diff --git a/site/src/lib/symbol-form.ts b/site/src/lib/symbol-form.ts index b8264415a..86ced05c5 100644 --- a/site/src/lib/symbol-form.ts +++ b/site/src/lib/symbol-form.ts @@ -38,6 +38,7 @@ interface Language { /** Every port. A language missing here is a failure of this table, and the test requires one entry per port. */ export const FORMS: Record = { + perl: 'as-written', py: { qualifier: '.', call: true }, ts: { qualifier: '.', call: true }, rs: { qualifier: '::', call: true }, diff --git a/site/src/lib/symbol-markdown.ts b/site/src/lib/symbol-markdown.ts index 3427f3ebf..939b9a6a9 100644 --- a/site/src/lib/symbol-markdown.ts +++ b/site/src/lib/symbol-markdown.ts @@ -1,7 +1,7 @@ import type { ApiModel, ApiSymbol, Signature, SourceApiModel, SymbolIndex } from '@libtmux/api-model' import { fromMarkdown } from 'mdast-util-from-markdown' import { toMarkdown } from 'mdast-util-to-markdown' -import { aliasMembersTarget, aliasTarget, boundLabel, pageMembersOf, memberSignals, memberTier, moduleOf, qualifiedNameOf, typeParameterList, type TypeParameter } from '@libtmux/api-model' +import { aliasMembersTarget, aliasTarget, boundLabel, pageMembersOf, memberSignals, memberTier, moduleOf, qualifiedNameOf, typeParameterList, type TypeParameter } from '@libtmux/api-model/reference' import mentions from '../data/mentions.json' import { PORT_NAME } from './api-models' import { apiTmuxSections, type ApiTmuxSection } from './api-tmux-sections' diff --git a/site/src/lib/tmux-catalog-usage.ts b/site/src/lib/tmux-catalog-usage.ts index d9e7d10bd..514d41a69 100644 --- a/site/src/lib/tmux-catalog-usage.ts +++ b/site/src/lib/tmux-catalog-usage.ts @@ -1,5 +1,5 @@ /** Where libraries and the C source meet the catalog. */ -import { qualifiedNameOf, type ApiModel, type ApiSymbol, type SourceApiModel } from '@libtmux/api-model' +import { qualifiedNameOf, type ApiModel, type ApiSymbol, type SourceApiModel } from '@libtmux/api-model/reference' import { API_MODELS, PORT_NAME, referenceHref } from './api-models' import type { CatalogEntry } from './tmux-catalog' import { tmuxCatalogMentions, tmuxCatalogProseMentions } from './tmux-catalog-links' diff --git a/site/src/lib/tmux-catalog.ts b/site/src/lib/tmux-catalog.ts index 73e2784da..3584d759f 100644 --- a/site/src/lib/tmux-catalog.ts +++ b/site/src/lib/tmux-catalog.ts @@ -1,6 +1,6 @@ /** tmux options, hooks and format variables, extracted for each pinned release. */ import { createHash } from 'node:crypto' -import { CONCEPTS, conceptsFor, type ApiSymbol } from '@libtmux/api-model' +import { CONCEPTS, conceptsFor, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS } from './api-models' import pins from '../data/tmux/versions.json' import v32 from '../data/tmux/catalog/3.2a.json' diff --git a/site/src/lib/tmux-library-usage.ts b/site/src/lib/tmux-library-usage.ts index 66402f8be..05de60efe 100644 --- a/site/src/lib/tmux-library-usage.ts +++ b/site/src/lib/tmux-library-usage.ts @@ -6,7 +6,7 @@ * API model was extracted from. A symbol appears only where the source shows * it sending the command, so a link here is a claim about the code. */ -import { qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model' +import { qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS, PORT_NAME, referenceHref } from './api-models' import { PORTS } from './ports' import scopeTable from '../data/tmux-usage/scopes.json' @@ -20,6 +20,7 @@ import julia from '../data/tmux-usage/julia.json' import kotlin from '../data/tmux-usage/kotlin.json' import lua from '../data/tmux-usage/lua.json' import powershell from '../data/tmux-usage/powershell.json' +import perl from '../data/tmux-usage/perl.json' import py from '../data/tmux-usage/py.json' import rs from '../data/tmux-usage/rs.json' import ruby from '../data/tmux-usage/ruby.json' @@ -67,7 +68,7 @@ export interface TmuxScope { } export const TMUX_USAGE: Record = { - csharp, cxx, elixir, fsharp, go, java, julia, kotlin, lua, powershell, py, rs, ruby, scala, swift, ts, + csharp, cxx, elixir, fsharp, go, java, julia, kotlin, lua, powershell, perl, py, rs, ruby, scala, swift, ts, } as unknown as Record const SCOPES = scopeTable.commands as Record diff --git a/site/src/lib/tmux-manual-data.ts b/site/src/lib/tmux-manual-data.ts index 81498bd7d..7f004db95 100644 --- a/site/src/lib/tmux-manual-data.ts +++ b/site/src/lib/tmux-manual-data.ts @@ -1,5 +1,5 @@ /** Versioned tmux command syntax and manual text, extracted together. */ -import { CONCEPTS, conceptsFor } from '@libtmux/api-model' +import { CONCEPTS, conceptsFor } from '@libtmux/api-model/reference' import { fromHtml } from 'hast-util-from-html' import { select, selectAll, type Element, type Nodes } from 'astro-expressive-code/hast' import pins from '../data/tmux/versions.json' diff --git a/site/src/lib/tmux-reference.ts b/site/src/lib/tmux-reference.ts index 431324ec1..2a76dc238 100644 --- a/site/src/lib/tmux-reference.ts +++ b/site/src/lib/tmux-reference.ts @@ -1,5 +1,5 @@ /** tmux source data adapted to the shared API reference and navigation. */ -import { docSummaryText, navSidecarFor, pageSlug, sourceUrl, type ApiSymbol, type SourceApiModel, type SymbolIndex } from '@libtmux/api-model' +import { docSummaryText, navSidecarFor, pageSlug, sourceUrl, type ApiSymbol, type SourceApiModel, type SymbolIndex } from '@libtmux/api-model/reference' import v32 from '../data/tmux/api/3.2a.json?raw' import v37 from '../data/tmux/api/3.7c.json?raw' import pins from '../data/tmux/versions.json' diff --git a/site/src/pages/[...slug].md.ts b/site/src/pages/[...slug].md.ts index 258b1d213..f6f084c72 100644 --- a/site/src/pages/[...slug].md.ts +++ b/site/src/pages/[...slug].md.ts @@ -1,6 +1,6 @@ import type { APIRoute } from 'astro' import { getCollection, type CollectionEntry } from 'astro:content' -import { sourceUrl } from '@libtmux/api-model' +import { sourceUrl } from '@libtmux/api-model/reference' import { API_MODELS } from '../lib/api-models' import { productApiAlternatives, productApiHref, productApiRedirects, productApiRoutes } from '../lib/product-api' import { symbolMarkdownWithLayout } from '../lib/symbol-markdown' diff --git a/site/src/pages/[...slug].preview.json.ts b/site/src/pages/[...slug].preview.json.ts index 46f0b58c6..5ebd6758d 100644 --- a/site/src/pages/[...slug].preview.json.ts +++ b/site/src/pages/[...slug].preview.json.ts @@ -7,7 +7,7 @@ import { PORT_BY_SLUG, portPageUrl, referenceUrl } from '../lib/ports' import { docsPath } from '../lib/docs-paths' import { docsEntriesAvailable } from '../lib/page-port-links' import { localeOf } from '../i18n/resolve' -import { symbolsForProduct } from '@libtmux/api-model' +import { symbolsForProduct } from '@libtmux/api-model/reference' import { buildTarget } from '../lib/versions' import { buildLocale, DEFAULT_LOCALE } from '../i18n/locales' import { API_GLOSSARY_PATH } from '../lib/api-glossary' diff --git a/site/src/pages/docs.json.ts b/site/src/pages/docs.json.ts index 578f02f39..d995c9438 100644 --- a/site/src/pages/docs.json.ts +++ b/site/src/pages/docs.json.ts @@ -1,5 +1,5 @@ import type { APIRoute } from 'astro' -import { moduleOf, qualifiedNameOf } from '@libtmux/api-model' +import { moduleOf, qualifiedNameOf } from '@libtmux/api-model/reference' import { getCollection, render } from 'astro:content' import { DEFAULT_LOCALE, localeRoot } from '../i18n/locales.ts' import { buildLocale, localeOf } from '../i18n/resolve.ts' diff --git a/site/src/pages/reference/[...slug].md.ts b/site/src/pages/reference/[...slug].md.ts index 78a43e01c..fc8235f0d 100644 --- a/site/src/pages/reference/[...slug].md.ts +++ b/site/src/pages/reference/[...slug].md.ts @@ -1,6 +1,6 @@ import type { APIRoute } from 'astro' import { API_MODELS } from '../../lib/api-models' -import { pageSlug, sourceUrl, symbolsForProduct } from '@libtmux/api-model' +import { pageSlug, sourceUrl, symbolsForProduct } from '@libtmux/api-model/reference' import { symbolMarkdownWithLayout } from '../../lib/symbol-markdown' import { productApiHref } from '../../lib/product-api' import { PORT_BY_SLUG, referenceUrl } from '../../lib/ports' diff --git a/site/src/pages/tmux/[version]/reference/[...slug].md.ts b/site/src/pages/tmux/[version]/reference/[...slug].md.ts index 0c769f8a2..47134066e 100644 --- a/site/src/pages/tmux/[version]/reference/[...slug].md.ts +++ b/site/src/pages/tmux/[version]/reference/[...slug].md.ts @@ -1,5 +1,5 @@ import type { APIRoute } from 'astro' -import { sourceUrl } from '@libtmux/api-model' +import { sourceUrl } from '@libtmux/api-model/reference' import { symbolMarkdownWithLayout } from '../../../../lib/symbol-markdown' import { tmuxCatalogLinksForSource } from '../../../../lib/tmux-catalog' import { tmuxReferenceContext, tmuxReferenceIndex, tmuxReferencePaths, tmuxReferenceRoutes, tmuxReferenceUrl, tmuxSourceCommands, tmuxSourceModel } from '../../../../lib/tmux-reference' diff --git a/site/src/plugins/rehype-api-links.ts b/site/src/plugins/rehype-api-links.ts index 26331c410..f6ecfd121 100644 --- a/site/src/plugins/rehype-api-links.ts +++ b/site/src/plugins/rehype-api-links.ts @@ -1,7 +1,7 @@ import { appendFileSync, mkdirSync } from 'node:fs' import { dirname } from 'node:path' import { visit } from 'unist-util-visit' -import { isLikelyReference, modulesIn, notApiReason, type ApiProduct } from '@libtmux/api-model' +import { isLikelyReference, modulesIn, notApiReason, type ApiProduct } from '@libtmux/api-model/reference' import { createProseLinker, PORT_BY_LABEL, protocolRunMentions } from '../lib/prose-resolver' import { PORT_BY_SLUG } from '../lib/ports' import { API_MODELS, pageSlug } from '../lib/api-models' diff --git a/site/src/styles/brand.css b/site/src/styles/brand.css index cfdcb30bd..a256d21d2 100644 --- a/site/src/styles/brand.css +++ b/site/src/styles/brand.css @@ -1999,3 +1999,128 @@ html[data-brand="elixir"][data-theme-mode="dark"], html[data-brand="elixir"][dat --lt-color-code-bg: #1c2229; } } +html[data-brand="perl"] { + color-scheme: light; + --brand-color: #0298C3; + --brand-solid: #045c77; + --brand-on-solid: #ffffff; + --button-bg-primary: #045c77; + --button-text-primary: #ffffff; + --theme-primary: #045c77; + --theme-secondary: #53606d; + --theme-accent: #045c77; + --theme-background: #fafbfc; + --theme-text: #202830; + --background-color: #fafbfc; + --text-color: #202830; + --topnav-background: #fafbfc; + --topnav-text-color: #202830; + --topnav-link-color: #53606d; + --topnav-link-hover-color: #202830; + --color-background-primary: #fafbfc; + --color-background-secondary: #f3f5f7; + --color-background-border: #d6dce3; + --color-api-background-hover: #e9edf1; + --color-foreground-primary: #202830; + --color-foreground-secondary: #53606d; + --color-foreground-muted: #53606d; + --color-link: #045c77; + --color-brand-primary: #045c77; + --color-brand-content: #045c77; + --color-inline-code-background: #f3f5f7; + --lt-color-bg: #fafbfc; + --lt-color-bg-secondary: #f3f5f7; + --lt-color-bg-hover: #e9edf1; + --lt-color-fg: #202830; + --lt-color-fg-secondary: #53606d; + --lt-color-fg-muted: #53606d; + --lt-color-border: #d6dce3; + --lt-color-accent: #045c77; + --lt-color-link: #045c77; + --lt-color-link-visited: #045c77; + --lt-color-code-bg: #f3f5f7; +} +html[data-brand="perl"][data-theme-mode="dark"], html[data-brand="perl"][data-theme="dark"] { + color-scheme: dark; + --brand-color: #0298C3; + --brand-solid: #045c77; + --brand-on-solid: #ffffff; + --button-bg-primary: #045c77; + --button-text-primary: #ffffff; + --theme-primary: #a6def0; + --theme-secondary: #b7c1cd; + --theme-accent: #a6def0; + --theme-background: #15191d; + --theme-text: #e7edf3; + --background-color: #15191d; + --text-color: #e7edf3; + --topnav-background: #15191d; + --topnav-text-color: #e7edf3; + --topnav-link-color: #b7c1cd; + --topnav-link-hover-color: #e7edf3; + --color-background-primary: #15191d; + --color-background-secondary: #1c2229; + --color-background-border: #3e4a57; + --color-api-background-hover: #29323d; + --color-foreground-primary: #e7edf3; + --color-foreground-secondary: #b7c1cd; + --color-foreground-muted: #b7c1cd; + --color-link: #a6def0; + --color-brand-primary: #a6def0; + --color-brand-content: #a6def0; + --color-inline-code-background: #1c2229; + --lt-color-bg: #15191d; + --lt-color-bg-secondary: #1c2229; + --lt-color-bg-hover: #29323d; + --lt-color-fg: #e7edf3; + --lt-color-fg-secondary: #b7c1cd; + --lt-color-fg-muted: #b7c1cd; + --lt-color-border: #3e4a57; + --lt-color-accent: #a6def0; + --lt-color-link: #a6def0; + --lt-color-link-visited: #a6def0; + --lt-color-code-bg: #1c2229; +} +@media (prefers-color-scheme: dark) { + html[data-brand="perl"]:not([data-theme-mode]):not([data-theme="light"]) { + color-scheme: dark; + --brand-color: #0298C3; + --brand-solid: #045c77; + --brand-on-solid: #ffffff; + --button-bg-primary: #045c77; + --button-text-primary: #ffffff; + --theme-primary: #a6def0; + --theme-secondary: #b7c1cd; + --theme-accent: #a6def0; + --theme-background: #15191d; + --theme-text: #e7edf3; + --background-color: #15191d; + --text-color: #e7edf3; + --topnav-background: #15191d; + --topnav-text-color: #e7edf3; + --topnav-link-color: #b7c1cd; + --topnav-link-hover-color: #e7edf3; + --color-background-primary: #15191d; + --color-background-secondary: #1c2229; + --color-background-border: #3e4a57; + --color-api-background-hover: #29323d; + --color-foreground-primary: #e7edf3; + --color-foreground-secondary: #b7c1cd; + --color-foreground-muted: #b7c1cd; + --color-link: #a6def0; + --color-brand-primary: #a6def0; + --color-brand-content: #a6def0; + --color-inline-code-background: #1c2229; + --lt-color-bg: #15191d; + --lt-color-bg-secondary: #1c2229; + --lt-color-bg-hover: #29323d; + --lt-color-fg: #e7edf3; + --lt-color-fg-secondary: #b7c1cd; + --lt-color-fg-muted: #b7c1cd; + --lt-color-border: #3e4a57; + --lt-color-accent: #a6def0; + --lt-color-link: #a6def0; + --lt-color-link-visited: #a6def0; + --lt-color-code-bg: #1c2229; + } +} diff --git a/site/test/api-components.ts b/site/test/api-components.ts index 5bb48fe13..13fe12284 100644 --- a/site/test/api-components.ts +++ b/site/test/api-components.ts @@ -2,7 +2,7 @@ import { readFileSync, realpathSync } from 'node:fs' import { createRequire } from 'node:module' import { pathToFileURL } from 'node:url' import { expect, vi } from 'vitest' -import { parameterId } from '@libtmux/api-model' +import { parameterId } from '@libtmux/api-model/reference' import { parameterBindingFacts, POWER_SHELL_COMMON_HELP, POWER_SHELL_COMMON_HELP_TITLE, powerShellCommonParameterHref, powerShellCommonParameterLabel, scalarCellsAreLong } from '../src/lib/api-sections' import { signatureSpans, typeLayout } from '../src/lib/code-layout' import { linkTmuxDoc } from '../src/lib/tmux-links' diff --git a/site/test/api-db-concepts.outer.test.ts b/site/test/api-db-concepts.outer.test.ts index f86f44e8c..17b7c4020 100644 --- a/site/test/api-db-concepts.outer.test.ts +++ b/site/test/api-db-concepts.outer.test.ts @@ -2,7 +2,7 @@ import { existsSync } from 'node:fs' import { join } from 'node:path' import { beforeAll, describe, expect, it } from 'vitest' -import { CONCEPTS } from '@libtmux/api-model' +import { CONCEPTS } from '@libtmux/api-model/reference' import { bindingsOf, conceptOf, seed, symbolById } from '../src/db' import { MODEL_DIR } from '../src/db/paths' diff --git a/site/test/api-destination-evidence.publication.test.ts b/site/test/api-destination-evidence.publication.test.ts new file mode 100644 index 000000000..fe71be381 --- /dev/null +++ b/site/test/api-destination-evidence.publication.test.ts @@ -0,0 +1,94 @@ +// Audits all generated destinations; small address and HTML fixtures remain in medium. +import { readFileSync } from 'node:fs' +import { describe, expect, it } from 'vitest' +import { collectApiDestinations, EXTERNAL_INVENTORIES } from '../../scripts/lib/api-destinations.mjs' +import { checkApiEvidence, INVENTORY_SOURCES, inventoryDigest, needsCheck, UNVERIFIABLE_REASONS } from '../../scripts/lib/api-destination-verification.mjs' +import evidence from '../src/data/api-destination-evidence.json' + +const root = new URL('../../', import.meta.url).pathname +const destinations = collectApiDestinations({ root }) +const today = new Date(`${evidence.checkedAt}T12:00:00Z`) + +describe('API destination evidence', () => { + it('records the heading a link was read at, never the name of the book or site the page belongs to', () => { + // "Associated items - The Rust Reference" is headed "Associated items": a record that kept "The Rust Reference" could not see a page move. + // A name that ends the titles of three pages of one host is the host's book, not any page's. + const records = evidence.destinations as { url: string; host: string; title?: string; heading?: string }[] + const parts = (record: { title?: string }) => (record.title ?? '').split(/\s+[-|\u2013\u2014]\s+/).map((part) => part.trim().toLowerCase()).filter(Boolean) + const seen = new Map>() + for (const record of records) for (const part of new Set(parts(record))) seen.set(`${record.host}\0${part}`, new Set([...(seen.get(`${record.host}\0${part}`) ?? []), record.url.split('#')[0]])) + const books = new Set([...seen].filter(([, pages]) => pages.size >= 3).map(([key]) => key)) + for (const record of records) { + if (record.heading === undefined) continue + expect(books.has(`${record.host}\0${record.heading.toLowerCase()}`), `${record.url} records ${JSON.stringify(record.heading)}`).toBe(false) + } + expect([...books].some((key) => key.endsWith('\0the rust reference'))).toBe(true) + }) + + it('holds a passing record for every destination the site generates, and none for a link nothing makes', () => { + const { problems } = checkApiEvidence(destinations, evidence, { today, root }) + expect(problems).toEqual([]) + expect(Object.keys(destinations.get('https://docs.rs/tmux-mcp')?.uses.values().next().value.package ?? {})).toEqual(['identity', 'ports']) + }) + + it('never records an unreadable host as passing', () => { + for (const record of evidence.destinations as { url: string; ok: boolean; unverifiable?: string; failure?: string; detail?: string }[]) { + if (record.unverifiable) { + expect(record.ok, record.url).toBe(false) + expect(UNVERIFIABLE_REASONS.some((reason) => reason.test(record.unverifiable!)), `${record.url}: ${record.unverifiable}`).toBe(true) + } else if (!record.ok) { + expect(record.failure, record.url).toBeTruthy() + expect(record.detail, record.url).toBeTruthy() + } + } + }) + + it('requires a page that answers 200 at its own address, and a verdict for each name', () => { + for (const record of evidence.destinations as { url: string; ok: boolean; status: number; finalUrl?: string; checkedAt: string; terminal?: { symbol: string; at: string }[] }[]) { + expect(record.url, 'https url').toMatch(/^https:\/\//) + expect(record.checkedAt, record.url).toMatch(/^\d{4}-\d{2}-\d{2}$/) + if (!record.ok) continue + expect(record.status, record.url).toBe(200) + expect(record.finalUrl, `${record.url} is a redirect`).toBeUndefined() + const destination = destinations.get(record.url) + if (!destination) continue + expect(needsCheck(destination, record), record.url).toBe(false) + } + }) + + it('names every cached inventory, each checked against its host and still holding the entries it was checked with', () => { + expect(evidence.inventories.map((record) => record.name).sort()).toEqual(Object.keys(INVENTORY_SOURCES).sort()) + for (const record of evidence.inventories as { name: string; ok: boolean; missing: number; digest: string }[]) { + expect(record.ok, record.name).toBe(true) + expect(record.missing, record.name).toBe(0) + const entries = JSON.parse(readFileSync(new URL(`../src/data/inventories/${record.name}.entries.json`, import.meta.url), 'utf8')).e as [string, string][] + expect(record.digest, record.name).toBe(inventoryDigest(entries)) + } + }) + + it('keeps a manual\'s own labels out of the inventories, so a name never means one', () => { + for (const name of ['python', 'julia']) { + const { e } = JSON.parse(readFileSync(new URL(`../src/data/inventories/${name}.entries.json`, import.meta.url), 'utf8')) as { e: [string, string][] } + const names = new Set(e.map(([entry]) => entry)) + for (const label of name === 'python' ? ['search', 'default', 'genindex', 'modindex'] : ['index', 'Level-6']) expect(names.has(label), `${name}: ${label}`).toBe(false) + } + }) + + it('holds one record for each address', () => { + const urls = (evidence.destinations as { url: string }[]).map((record) => record.url) + expect(new Set(urls).size).toBe(urls.length) + }) + + it('lists the same inventories the reference and the prose linker attach', () => { + for (const file of ['src/lib/api-models.ts', 'src/lib/prose-resolver.ts']) { + const source = readFileSync(new URL(`../${file}`, import.meta.url), 'utf8') + for (const { baseUrl, langs } of EXTERNAL_INVENTORIES) { + const attached = new RegExp(`baseUrl: '${baseUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}',\\s*langs: \\[([^\\]]*)\\]`).exec(source) + ?? new RegExp(`langs: \\[([^\\]]*)\\][^}]*baseUrl: '${baseUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}'`).exec(source) + ?? new RegExp(`baseUrl: '${baseUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}'[^}]*langs: \\[([^\\]]*)\\]`).exec(source) + expect(attached, `${file} attaches ${baseUrl}`).not.toBeNull() + expect([...attached![1]!.matchAll(/'(\w+)'/g)].map(([, lang]) => lang), `${file} ${baseUrl}`).toEqual(langs) + } + } + }) +}) diff --git a/site/test/api-destination-evidence.test.ts b/site/test/api-destination-evidence.test.ts index 134a960df..207e92861 100644 --- a/site/test/api-destination-evidence.test.ts +++ b/site/test/api-destination-evidence.test.ts @@ -1,103 +1,14 @@ -import { readFileSync } from 'node:fs' import { describe, expect, it } from 'vitest' -import { API_HOSTS, EXTERNAL_INVENTORIES, PAGE_EXCEPTIONS, addressSegments, apiHostOf, arityOf, collectApiDestinations, linksIn, qualified, terminalSymbol, urlsIn } from '../../scripts/lib/api-destinations.mjs' +import { API_HOSTS, PAGE_EXCEPTIONS, addressSegments, apiHostOf, arityOf, linksIn, qualified, terminalSymbol, urlsIn } from '../../scripts/lib/api-destinations.mjs' import { addressOf, mismatch } from '../../scripts/lib/api-addresses.mjs' import { judge, judgeLabel, pageIdentity, sourceIdentity } from '../../scripts/lib/api-identities.mjs' import { PORT_LANGUAGES, languageOfUrl, languageProblem, loadReviewedLinks, doccHeading } from '../../scripts/lib/api-links.mjs' import { BARE_OWNERS, DEFAULT_NAMES, bareOwners, hintOwners } from '../../scripts/lib/api-sources.mjs' import { pageHeading } from '../../scripts/lib/api-html.mjs' import { dataLinks, markdownLinks, normalizeAddress, occurrencesIn } from '../../scripts/lib/api-markdown-links.mjs' -import { - INVENTORY_SOURCES, MAX_UNVERIFIABLE_SHARE, UNVERIFIABLE_REASONS, checkApiEvidence, expectationsOf, expectedSymbols, inventoryDigest, mentions, needsCheck, readPage, recordProblems, sameAddress, sectionAt, slugSymbol, -} from '../../scripts/lib/api-destination-verification.mjs' -import evidence from '../src/data/api-destination-evidence.json' +import { MAX_UNVERIFIABLE_SHARE, expectationsOf, expectedSymbols, mentions, readPage, recordProblems, sameAddress, sectionAt, slugSymbol } from '../../scripts/lib/api-destination-verification.mjs' const root = new URL('../../', import.meta.url).pathname -const destinations = collectApiDestinations({ root }) -const today = new Date(`${evidence.checkedAt}T12:00:00Z`) - -describe('API destination evidence', () => { - it('records the heading a link was read at, never the name of the book or site the page belongs to', () => { - // "Associated items - The Rust Reference" is headed "Associated items": a record that kept "The Rust Reference" could not see a page move. - // A name that ends the titles of three pages of one host is the host's book, not any page's. - const records = evidence.destinations as { url: string; host: string; title?: string; heading?: string }[] - const parts = (record: { title?: string }) => (record.title ?? '').split(/\s+[-|\u2013\u2014]\s+/).map((part) => part.trim().toLowerCase()).filter(Boolean) - const seen = new Map>() - for (const record of records) for (const part of new Set(parts(record))) seen.set(`${record.host}\0${part}`, new Set([...(seen.get(`${record.host}\0${part}`) ?? []), record.url.split('#')[0]])) - const books = new Set([...seen].filter(([, pages]) => pages.size >= 3).map(([key]) => key)) - for (const record of records) { - if (record.heading === undefined) continue - expect(books.has(`${record.host}\0${record.heading.toLowerCase()}`), `${record.url} records ${JSON.stringify(record.heading)}`).toBe(false) - } - expect([...books].some((key) => key.endsWith('\0the rust reference'))).toBe(true) - }) - - it('holds a passing record for every destination the site generates, and none for a link nothing makes', () => { - const { problems } = checkApiEvidence(destinations, evidence, { today, root }) - expect(problems).toEqual([]) - }) - - it('never records an unreadable host as passing', () => { - for (const record of evidence.destinations as { url: string; ok: boolean; unverifiable?: string; failure?: string; detail?: string }[]) { - if (record.unverifiable) { - expect(record.ok, record.url).toBe(false) - expect(UNVERIFIABLE_REASONS.some((reason) => reason.test(record.unverifiable!)), `${record.url}: ${record.unverifiable}`).toBe(true) - } else if (!record.ok) { - expect(record.failure, record.url).toBeTruthy() - expect(record.detail, record.url).toBeTruthy() - } - } - }) - - it('requires a page that answers 200 at its own address, and a verdict for each name', () => { - for (const record of evidence.destinations as { url: string; ok: boolean; status: number; finalUrl?: string; checkedAt: string; terminal?: { symbol: string; at: string }[] }[]) { - expect(record.url, 'https url').toMatch(/^https:\/\//) - expect(record.checkedAt, record.url).toMatch(/^\d{4}-\d{2}-\d{2}$/) - if (!record.ok) continue - expect(record.status, record.url).toBe(200) - expect(record.finalUrl, `${record.url} is a redirect`).toBeUndefined() - const destination = destinations.get(record.url) - if (!destination) continue - expect(needsCheck(destination, record), record.url).toBe(false) - } - }) - - it('names every cached inventory, each checked against its host and still holding the entries it was checked with', () => { - expect(evidence.inventories.map((record) => record.name).sort()).toEqual(Object.keys(INVENTORY_SOURCES).sort()) - for (const record of evidence.inventories as { name: string; ok: boolean; missing: number; digest: string }[]) { - expect(record.ok, record.name).toBe(true) - expect(record.missing, record.name).toBe(0) - const entries = JSON.parse(readFileSync(new URL(`../src/data/inventories/${record.name}.entries.json`, import.meta.url), 'utf8')).e as [string, string][] - expect(record.digest, record.name).toBe(inventoryDigest(entries)) - } - }) - - it('keeps a manual\'s own labels out of the inventories, so a name never means one', () => { - for (const name of ['python', 'julia']) { - const { e } = JSON.parse(readFileSync(new URL(`../src/data/inventories/${name}.entries.json`, import.meta.url), 'utf8')) as { e: [string, string][] } - const names = new Set(e.map(([entry]) => entry)) - for (const label of name === 'python' ? ['search', 'default', 'genindex', 'modindex'] : ['index', 'Level-6']) expect(names.has(label), `${name}: ${label}`).toBe(false) - } - }) - - it('holds one record for each address', () => { - const urls = (evidence.destinations as { url: string }[]).map((record) => record.url) - expect(new Set(urls).size).toBe(urls.length) - }) - - it('lists the same inventories the reference and the prose linker attach', () => { - for (const file of ['src/lib/api-models.ts', 'src/lib/prose-resolver.ts']) { - const source = readFileSync(new URL(`../${file}`, import.meta.url), 'utf8') - for (const { baseUrl, langs } of EXTERNAL_INVENTORIES) { - const attached = new RegExp(`baseUrl: '${baseUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}',\\s*langs: \\[([^\\]]*)\\]`).exec(source) - ?? new RegExp(`langs: \\[([^\\]]*)\\][^}]*baseUrl: '${baseUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}'`).exec(source) - ?? new RegExp(`baseUrl: '${baseUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}'[^}]*langs: \\[([^\\]]*)\\]`).exec(source) - expect(attached, `${file} attaches ${baseUrl}`).not.toBeNull() - expect([...attached![1]!.matchAll(/'(\w+)'/g)].map(([, lang]) => lang), `${file} ${baseUrl}`).toEqual(langs) - } - } - }) -}) describe('what the verifier reads from a page', () => { it('matches a symbol as a whole word, never inside another', () => { @@ -604,7 +515,6 @@ describe('the reviewed link table', () => { const use = { port: '', name: 'a.md', source: 'authored', label: 'crate API', from: 'go', package: { identity: 'tmux-mcp', ports: ['rs'] } } const [expectation] = expectationsOf({ url: 'https://docs.rs/tmux-mcp', uses: [use] }) expect(expectation).toMatchObject({ label: 'crate API', ports: ['go'], package: { identity: 'tmux-mcp', ports: ['rs'] } }) - expect(Object.keys(destinations.get('https://docs.rs/tmux-mcp')?.uses.values().next().value.package ?? {})).toEqual(['identity', 'ports']) }) it('keeps every port that wrote the same words at the same address, so the last one cannot hide the others', () => { diff --git a/site/test/api-doc-mentions.test.ts b/site/test/api-doc-mentions.test.ts index cae5425be..210a2754b 100644 --- a/site/test/api-doc-mentions.test.ts +++ b/site/test/api-doc-mentions.test.ts @@ -4,7 +4,7 @@ import { experimental_AstroContainer } from 'astro/container' import { createMarkdownProcessor } from '@astrojs/markdown-remark' import { fromHtml } from 'hast-util-from-html' import { select, selectAll } from 'astro-expressive-code/hast' -import { SymbolIndex, type ApiSymbol } from '@libtmux/api-model' +import { SymbolIndex, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS, indexFor } from '../src/lib/api-models' import { MCP_REFERENCE } from '../src/lib/mcp-catalog' import { rehypeApiLinks } from '../src/plugins/rehype-api-links' diff --git a/site/test/api-fidelity.test.ts b/site/test/api-fidelity.test.ts index a42c4baea..8595295f4 100644 --- a/site/test/api-fidelity.test.ts +++ b/site/test/api-fidelity.test.ts @@ -5,7 +5,7 @@ import { join } from 'node:path' import { fileURLToPath } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' import type { ApiModel, ApiSymbol } from '@libtmux/api-model' -import { sourceUrl } from '@libtmux/api-model' +import { sourceUrl } from '@libtmux/api-model/reference' import { API_MODEL_PORTS } from '../src/lib/ports' const root = fileURLToPath(new URL('../../', import.meta.url)) diff --git a/site/test/api-headings.test.ts b/site/test/api-headings.test.ts index 31b842eba..73647bb32 100644 --- a/site/test/api-headings.test.ts +++ b/site/test/api-headings.test.ts @@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs' import { experimental_AstroContainer } from 'astro/container' import { Window } from 'happy-dom' import { afterEach, describe, expect, it } from 'vitest' -import { parameterId, symbolsForProduct, type ApiSymbol, type Param } from '@libtmux/api-model' +import { parameterId, symbolsForProduct, type ApiSymbol, type Param } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { fieldsRepeated, splitFieldMembers } from '../src/lib/api-sections' import { productApiHref, productApiRoots } from '../src/lib/product-api' diff --git a/site/test/api-links-rendered.test.ts b/site/test/api-links-rendered.test.ts index d65533eb1..8afa44b73 100644 --- a/site/test/api-links-rendered.test.ts +++ b/site/test/api-links-rendered.test.ts @@ -5,7 +5,7 @@ import { pathToFileURL } from 'node:url' import { experimental_AstroContainer } from 'astro/container' import { createMarkdownProcessor } from '@astrojs/markdown-remark' import { fromMarkdown } from 'mdast-util-from-markdown' -import { BUILTINS, PORT_NAME, proseTexts } from '@libtmux/api-model' +import { BUILTINS, PORT_NAME, proseTexts } from '@libtmux/api-model/reference' import { apiHostOf, collectApiDestinations, proseRuns, proseSources, typeInputs } from '../../scripts/lib/api-destinations.mjs' import { languageOfUrl, languageProblem } from '../../scripts/lib/api-links.mjs' import { normalizeAddress } from '../../scripts/lib/api-markdown-links.mjs' diff --git a/site/test/api-prose-fields.test.ts b/site/test/api-prose-fields.test.ts index d6611b820..4e57ef215 100644 --- a/site/test/api-prose-fields.test.ts +++ b/site/test/api-prose-fields.test.ts @@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest' import { BUILTINS, PROSE_FIELDS, RENDERED_TEXTS, STRUCTURAL_FIELDS, commandFacts, isStructuralField, parameterBindingFacts, parameterBindingText, proseTexts, unclassifiedFields, type ApiSymbol, type SymbolIndex, -} from '@libtmux/api-model' +} from '@libtmux/api-model/reference' import { apiHostOf, apiIndexes, collectApiDestinations } from '../../scripts/lib/api-destinations.mjs' import { normalizeAddress } from '../../scripts/lib/api-markdown-links.mjs' import { languageOfUrl } from '../../scripts/lib/api-links.mjs' diff --git a/site/test/api-prose.test.ts b/site/test/api-prose.test.ts index 7fc4b901b..ba2702b7e 100644 --- a/site/test/api-prose.test.ts +++ b/site/test/api-prose.test.ts @@ -3,7 +3,7 @@ import { readFileSync } from 'node:fs' import { fromMarkdown } from 'mdast-util-from-markdown' import { API_MODELS } from '../src/lib/api-models' import { symbolMarkdown } from '../src/lib/symbol-markdown' -import { tokenizeDoc } from '@libtmux/api-model' +import { tokenizeDoc } from '@libtmux/api-model/reference' import { parseApiProse } from '../src/lib/api-prose' import { groupDirectory } from '../src/lib/api-directory' import { parseXmlDoc } from '../../packages/api-model/src/doc/csharp' diff --git a/site/test/api-scalar-members.outer.test.ts b/site/test/api-scalar-members.outer.test.ts index abea1bc03..9789a2937 100644 --- a/site/test/api-scalar-members.outer.test.ts +++ b/site/test/api-scalar-members.outer.test.ts @@ -3,7 +3,7 @@ import { chromium, type Browser } from 'playwright' import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' // A reference page asks the content collection for its sidebar; the tables here are drawn without one. vi.mock('astro:content', () => ({ getCollection: async () => [] })) -import { SymbolIndex } from '@libtmux/api-model' +import { SymbolIndex } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { LONG_CELL_CHARACTERS, memberTable, scalarCellCharacters, variantPayloads } from '../src/lib/api-sections' import { wordBreak } from '../src/lib/word-break' diff --git a/site/test/api-sections.test.ts b/site/test/api-sections.test.ts index 665c93b9b..4e75144eb 100644 --- a/site/test/api-sections.test.ts +++ b/site/test/api-sections.test.ts @@ -10,6 +10,15 @@ const symbol = (id: string, overrides: Partial = {}): ApiSymbol => ({ }) describe('reference page navigation', () => { + it('derives stable native method fragments when the optional dispatch identity is absent', () => { + const owner = symbol('LibTmux::Server::attach_argv', { kind: 'method', signatures: [ + { methodKind: 'call', raw: 'sub attach_argv($self, %args)', params: [{ name: 'args', variadic: 'keyword' }] }, + ] }) + const [method] = apiMethodDetails(owner) + expect(method.id).toMatch(/^LibTmux::Server::attach_argv\.method-[a-f0-9]{16}$/) + owner.signatures[0].raw = 'sub attach_argv( $self,\n %args )' + expect(apiMethodDetails(owner)[0].id).toBe(method.id) + }) it('keeps overload fragments stable through insertion, reordering, and signature formatting', () => { const owner = symbol('Server.open') const first = { params: [{ name: 'name', type: 'string' }], returns: 'Server', raw: 'open(name: string): Server' } diff --git a/site/test/api-signature-scope.test.ts b/site/test/api-signature-scope.test.ts index fe53c6b69..ec81e666f 100644 --- a/site/test/api-signature-scope.test.ts +++ b/site/test/api-signature-scope.test.ts @@ -2,7 +2,7 @@ import { readFileSync, realpathSync } from 'node:fs' import { createRequire } from 'node:module' import { pathToFileURL } from 'node:url' import { experimental_AstroContainer } from 'astro/container' -import { parameterId, qualifiedNameOf, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model' +import { parameterId, qualifiedNameOf, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model/reference' import { Window } from 'happy-dom' import { afterEach, expect, it, vi } from 'vitest' import { signatureMultiline } from '../src/lib/api-sections' diff --git a/site/test/api-tmux-sections.test.ts b/site/test/api-tmux-sections.test.ts index 402465a9d..b76df21c9 100644 --- a/site/test/api-tmux-sections.test.ts +++ b/site/test/api-tmux-sections.test.ts @@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs' import { experimental_AstroContainer } from 'astro/container' import { Window, type Document } from 'happy-dom' import { afterEach, describe, expect, it, vi } from 'vitest' -import { CONCEPTS, conceptsFor, type ApiSymbol } from '@libtmux/api-model' +import { CONCEPTS, conceptsFor, type ApiSymbol } from '@libtmux/api-model/reference' import mentions from '../src/data/mentions.json' import { API_MODELS, PORT_NAME } from '../src/lib/api-models' import { PORTS } from '../src/lib/ports' diff --git a/site/test/api-tree.test.ts b/site/test/api-tree.test.ts index b3c5b79df..680cb71ce 100644 --- a/site/test/api-tree.test.ts +++ b/site/test/api-tree.test.ts @@ -1,7 +1,7 @@ import { readFileSync } from 'node:fs' import { Window } from 'happy-dom' import { describe, expect, it, vi } from 'vitest' -import { compareMembers, membersOf, memberSignals } from '@libtmux/api-model' +import { compareMembers, membersOf, memberSignals } from '@libtmux/api-model/reference' import mentions from '../src/data/mentions.json' import { API_MODELS, API_NAV, OWNER_KINDS, topLevelTypesOf } from '../src/lib/api-models' import { bucketForSymbol, firstEntry, membersByType, navTree, referenceNavigation, referenceIndexSections } from '../src/lib/api-tree' diff --git a/site/test/authored-links.test.ts b/site/test/authored-links.test.ts index 572f1c3cd..541fe8ed2 100644 --- a/site/test/authored-links.test.ts +++ b/site/test/authored-links.test.ts @@ -2,7 +2,7 @@ import { createMarkdownProcessor } from '@astrojs/markdown-remark' import { select, selectAll, type Element, type Nodes } from 'astro-expressive-code/hast' import { fromHtml } from 'hast-util-from-html' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { modulesIn } from '@libtmux/api-model' +import { modulesIn } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { tmuxEntityAt } from '../src/lib/tmux-links' import { rehypeApiLinks } from '../src/plugins/rehype-api-links' diff --git a/site/test/branding.test.ts b/site/test/branding.test.ts index 483dec058..340f9dceb 100644 --- a/site/test/branding.test.ts +++ b/site/test/branding.test.ts @@ -20,7 +20,7 @@ const contrast = (a: string, b: string) => { describe('route branding', () => { it('titles each port home page by repository and language', () => { expect(Object.fromEntries(PORTS.map((port) => [port.slug, portHomeTitle(port)]))).toEqual({ - py: 'libtmux: Python-based tmux client', ruby: 'libtmux-ruby: Ruby-based tmux client', + perl: 'libtmux-perl: Perl-based tmux client', py: 'libtmux: Python-based tmux client', ruby: 'libtmux-ruby: Ruby-based tmux client', lua: 'libtmux-lua: Lua-based tmux client', ts: 'libtmux-ts: TypeScript-based tmux client', powershell: 'libtmux-powershell: PowerShell-based tmux client', julia: 'libtmux-julia: Julia-based tmux client', elixir: 'libtmux-elixir: Elixir-based tmux client', rs: 'libtmux-rs: Rust-based tmux client', @@ -41,7 +41,7 @@ describe('route branding', () => { }) it('uses project titles independently of package names and shared source repositories', () => { const names = { - py: 'libtmux', ruby: 'libtmux-ruby', lua: 'libtmux-lua', ts: 'libtmux-ts', + perl: 'libtmux-perl', py: 'libtmux', ruby: 'libtmux-ruby', lua: 'libtmux-lua', ts: 'libtmux-ts', powershell: 'libtmux-powershell', julia: 'LibTmux.jl', elixir: 'libtmux-elixir', rs: 'libtmux-rs', go: 'libtmux-go', java: 'libtmux-java', kotlin: 'libtmux-kotlin', scala: 'libtmux-scala', csharp: 'libtmux-dotnet', fsharp: 'libtmux-fsharp', @@ -95,7 +95,7 @@ describe('route branding', () => { .toBe('/pr-42/ja/brand/rust/workspace/logo.svg') }) it('ships raster and vector fallbacks for every palette and product', () => { - for (const language of Object.keys(palettes)) for (const product of ['library', 'mcp', 'workspace']) { + for (const language of Object.keys(palettes)) for (const product of (PORTS.find((port) => port.logoLanguage === language)?.productAvailability?.mcp === 'excluded' ? ['library', 'workspace'] : ['library', 'mcp', 'workspace'])) { const brand = { asset: (file: string) => `/brand/${language}/${product}/${file}` } for (const file of ['logo.svg', 'favicon.ico', 'logo-32.png', 'logo-512.png', 'apple-touch-icon-light.png', 'opengraph-light.png', 'twitter-light.png', 'site.webmanifest']) { expect(existsSync(publicFile(brand.asset(file))), brand.asset(file)).toBe(true) diff --git a/site/test/c-layout.test.ts b/site/test/c-layout.test.ts index 62532b578..d64d506b1 100644 --- a/site/test/c-layout.test.ts +++ b/site/test/c-layout.test.ts @@ -3,7 +3,7 @@ import { experimental_AstroContainer } from 'astro/container' import { Window } from 'happy-dom' import { fromMarkdown } from 'mdast-util-from-markdown' import { describe, expect, it } from 'vitest' -import { parameterId, SymbolIndex, type ApiSymbol, type Param } from '@libtmux/api-model' +import { parameterId, SymbolIndex, type ApiSymbol, type Param } from '@libtmux/api-model/reference' import { apiEntryFields, nativeSignatureText, usesNativeSignatures } from '../src/lib/api-sections' import { apiSignatureLayouts, CODE_COLUMNS, codeWidthFailures, signatureSpans, supportsCSignatures, type CodeLayout } from '../src/lib/code-layout' import { formatCDeclaration, formatCEnumDeclaration } from '../src/lib/cxx-code-layout' diff --git a/site/test/concept-coverage.test.ts b/site/test/concept-coverage.test.ts index 892b04011..ac2eeee0f 100644 --- a/site/test/concept-coverage.test.ts +++ b/site/test/concept-coverage.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { CONCEPTS, conceptsFor } from '@libtmux/api-model' +import { CONCEPTS, conceptsFor } from '@libtmux/api-model/reference' import { API_MODELS, referenceAlternatives, referenceHref } from '../src/lib/api-models' import { API_MODEL_PORTS } from '../src/lib/ports' @@ -27,7 +27,7 @@ function coverage(concept: string) { describe('the ports that have a page for an operation', () => { it('lists every port for a server snapshot except those with no whole-server snapshot', () => { const { pages, reasons } = coverage('snapshot') - expect(pages.toSorted()).toEqual(['csharp', 'elixir', 'fsharp', 'go', 'java', 'julia', 'kotlin', 'lua', 'powershell', 'rs', 'ruby', 'scala', 'swift', 'ts']) + expect(pages.toSorted()).toEqual(['csharp', 'elixir', 'fsharp', 'go', 'java', 'julia', 'kotlin', 'lua', 'perl', 'powershell', 'rs', 'ruby', 'scala', 'swift', 'ts']) // Python's core and C++ have no snapshot of a whole server, and each says so. expect(reasons.toSorted()).toEqual(['cxx', 'py']) for (const port of ['py', 'cxx']) expect(CONCEPTS.snapshot!.absent![port], port).toMatch(/^no equivalent on `Server`/) diff --git a/site/test/core-home.test.ts b/site/test/core-home.test.ts index 93fda691a..04162697c 100644 --- a/site/test/core-home.test.ts +++ b/site/test/core-home.test.ts @@ -36,6 +36,15 @@ describe('Core Library home data', () => { for (const entry of Object.values(CORE_HOME)) for (const key of Object.keys(entry.capabilities)) expect(CAPABILITIES).toHaveProperty(key) }) + it('keeps Perl physical windows separate from session-window associations', () => { + const home = resolveCoreHome('perl', 'latest') + expect(home.association?.id).toBe('LibTmux::WindowLink') + expect(home.objects.find((object) => object.role === 'window')?.wraps).toContain('physical') + expect(home.capabilities.cli.map((row) => row.key)).toContain('async') + expect(home.capabilities.cli.map((row) => row.key)).not.toContain('control-mode') + expect(coreHomeMarkdown('perl', 'latest', 'https://libtmux.org')).toContain('LibTmux::WindowLink') + }) + it('fails on a missing symbol, a missing type and an unknown capability', () => { const rs = CORE_HOME.rs! expect(() => resolveCoreHome('rs', 'latest', { ...rs, objects: { ...rs.objects, pane: 'pane.NoSuchPane' } })) diff --git a/site/test/csharp-layout.test.ts b/site/test/csharp-layout.test.ts index 9140faaf6..019d2a84f 100644 --- a/site/test/csharp-layout.test.ts +++ b/site/test/csharp-layout.test.ts @@ -3,7 +3,7 @@ import { experimental_AstroContainer } from 'astro/container' import { Window } from 'happy-dom' import { fromMarkdown } from 'mdast-util-from-markdown' import { describe, expect, it } from 'vitest' -import { parameterId, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model' +import { parameterId, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model/reference' import { apiEntryFields, nativeSignatureText, usesNativeSignatures } from '../src/lib/api-sections' import { apiSignatureLayouts, CODE_COLUMNS, codeWidthFailures, signatureSpans, supportsCSharpSignatures } from '../src/lib/code-layout' import { csharpDeclaration, formatCSharpDeclaration } from '../src/lib/csharp-code-layout' diff --git a/site/test/cxx-layout.test.ts b/site/test/cxx-layout.test.ts index 43156c336..1ab3be46d 100644 --- a/site/test/cxx-layout.test.ts +++ b/site/test/cxx-layout.test.ts @@ -1,6 +1,6 @@ import { readFileSync } from 'node:fs' import { describe, expect, it } from 'vitest' -import { SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model' +import { SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model/reference' import { fromMarkdown } from 'mdast-util-from-markdown' import { apiSignatureLayouts, CODE_COLUMNS, codeWidthFailures, signatureSpans, type CodeLayout } from '../src/lib/code-layout' import { usesNativeSignatures } from '../src/lib/api-sections' diff --git a/site/test/cxx-signature.test.ts b/site/test/cxx-signature.test.ts index f45c4ef93..86d5746d8 100644 --- a/site/test/cxx-signature.test.ts +++ b/site/test/cxx-signature.test.ts @@ -4,7 +4,7 @@ import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it, vi } from 'vitest' import { experimental_AstroContainer } from 'astro/container' import { Window, type Element } from 'happy-dom' -import { SymbolIndex, type ApiModel, type ApiSymbol } from '@libtmux/api-model' +import { SymbolIndex, type ApiModel, type ApiSymbol } from '@libtmux/api-model/reference' import { nativeSignatureText } from '../src/lib/api-sections' import { apiSignatureLayouts } from '../src/lib/code-layout' diff --git a/site/test/destination-evidence.test.ts b/site/test/destination-evidence.test.ts index de64e2eef..a8d0d7fee 100644 --- a/site/test/destination-evidence.test.ts +++ b/site/test/destination-evidence.test.ts @@ -41,7 +41,7 @@ describe('destination evidence', () => { expect(inventoryCoverage(without, registered)).toEqual([expect.stringMatching(/^elixir is registered in ports\.ts but has no inventory entry/)]) // A library that is not published gives the header nothing to link. const withheld = { ...INVENTORY, elixir: INVENTORY.elixir!.map((entry) => (entry.kind === 'library' ? { ...entry, status: 'planned' as const } : entry)) } - expect(inventoryCoverage(withheld, registered)).toEqual([expect.stringMatching(/^elixir has no published library entry/)]) + expect(inventoryCoverage(withheld, registered)).toEqual([expect.stringMatching(/^elixir has no available library source or publication/)]) expect(inventoryCoverage({ ...INVENTORY, nope: INVENTORY.elixir! }, registered)).toEqual(['nope has inventory entries but is not registered in ports.ts']) expect(inventoryCoverage({ ...INVENTORY, elixir: [] }, registered)).toHaveLength(1) }) @@ -183,6 +183,7 @@ describe('destination evidence', () => { describe('age', () => { const checked = new Date(`${evidence.checkedAt}T12:00:00Z`) const later = (days: number) => new Date(checked.getTime() + days * DAY) + const sameDate = withEvidence(evidence.destinations.map((record) => ({ ...record, checkedAt: evidence.checkedAt }))) it('is measured, never judged, by the agreement check, so a change that touches none of this cannot fail for the passage of time', () => { const ancient = withEvidence(evidence.destinations.map((record) => ({ ...record, checkedAt: '2001-01-01' }))) @@ -192,8 +193,8 @@ describe('destination evidence', () => { }) it('reports a record as stale only after the bound, oldest first, with its date', () => { - expect(staleRecords(evidence, { today: later(EVIDENCE_MAX_AGE_DAYS) })).toEqual([]) - const stale = staleRecords(evidence, { today: later(EVIDENCE_MAX_AGE_DAYS + 2) }) + expect(staleRecords(sameDate, { today: later(EVIDENCE_MAX_AGE_DAYS) })).toEqual([]) + const stale = staleRecords(sameDate, { today: later(EVIDENCE_MAX_AGE_DAYS + 2) }) expect(stale).toHaveLength(evidence.destinations.length) expect(stale[0]).toMatchObject({ checkedAt: evidence.checkedAt, days: EVIDENCE_MAX_AGE_DAYS + 2 }) const old = new Date(checked.getTime() - (EVIDENCE_MAX_AGE_DAYS + 5) * DAY).toISOString().slice(0, 10) @@ -203,7 +204,7 @@ describe('destination evidence', () => { }) it('words a warning with the date and the command that clears it', () => { - const stale = staleRecords(evidence, { today: later(EVIDENCE_MAX_AGE_DAYS + 2) }) + const stale = staleRecords(sameDate, { today: later(EVIDENCE_MAX_AGE_DAYS + 2) }) expect(staleWarnings(stale)).toEqual([`${evidence.destinations.length} destination records were last checked ${evidence.checkedAt}, more than ${EVIDENCE_MAX_AGE_DAYS} days ago: run node scripts/verify-destinations.mjs`]) expect(staleWarnings(stale.slice(0, 1))[0]).toMatch(/^1 destination record was last checked/) }) @@ -244,12 +245,12 @@ describe('destination evidence', () => { }) it('names every record dated beyond a day ahead of today, and fails the agreement check on it', () => { - expect(futureRecords(evidence, { today: new Date(checked.getTime() - DAY) })).toEqual([]) - const early = futureRecords(evidence, { today: new Date(checked.getTime() - 3 * DAY) }) + expect(futureRecords(sameDate, { today: new Date(checked.getTime() - DAY) })).toEqual([]) + const early = futureRecords(sameDate, { today: new Date(checked.getTime() - 3 * DAY) }) expect(early).toHaveLength(evidence.destinations.length) expect(early[0]).toMatchObject({ checkedAt: evidence.checkedAt }) - expect(checkEvidence(INVENTORY, evidence, { manifests, today: checked })).toEqual([]) - expect(checkEvidence(INVENTORY, evidence, { manifests, today: new Date(checked.getTime() - 3 * DAY) })) + expect(checkEvidence(INVENTORY, sameDate, { manifests, today: checked })).toEqual([]) + expect(checkEvidence(INVENTORY, sameDate, { manifests, today: new Date(checked.getTime() - 3 * DAY) })) .toContain(`${evidence.destinations[0]!.url} was checked ${evidence.checkedAt}, which is in the future`) }) diff --git a/site/test/elixir-layout-rendering.outer.test.ts b/site/test/elixir-layout-rendering.outer.test.ts new file mode 100644 index 000000000..43d0d96e4 --- /dev/null +++ b/site/test/elixir-layout-rendering.outer.test.ts @@ -0,0 +1,37 @@ +// Compiles and renders real Astro declarations; pure layout fixtures remain in medium. +import { expect, it } from 'vitest' +import { API_MODELS } from '../src/lib/api-models' +import { displayedSignature, renderSignatures } from './signature-fragment' +import { CODE_COLUMNS } from '../src/lib/code-layout' +import { productApiIndex } from '../src/lib/product-api' + +const model = API_MODELS.elixir +const index = productApiIndex(model, 'latest') +const symbol = (id: string) => model.symbols.find((entry) => entry.id === id)! + +it('render as one preformatted declaration with working links and no nested anchors', async () => { + const entry = symbol('LibTmux.Control.submit/3') + const nameHref = `/en/elixir/latest/reference/${entry.slug}/` + const { window, signatures, layouts } = await renderSignatures(entry, 'elixir', index, nameHref) + try { + expect(signatures).toHaveLength(entry.signatures.length) + const [rendered] = signatures + expect(rendered!.classList.contains('api-native-signature--formatted')).toBe(true) + expect(rendered!.getAttribute('data-code-columns')).toBe(String(CODE_COLUMNS.api)) + expect(rendered!.getAttribute('data-code-width-status')).toBe('fits') + expect(displayedSignature(rendered!)).toBe(layouts.get(entry.signatures[0]!)!.text) + expect(rendered!.querySelector('.api-signature-name-link')?.getAttribute('href')).toBe(nameHref) + expect([...rendered!.querySelectorAll('a.api-parameter-name')].map((link) => link.textContent)).toEqual(['control', 'request', 'options']) + expect(rendered!.querySelector('a a')).toBeNull() + } finally { await window.happyDOM.abort() } + }) + +it('give each spec clause of an overloaded function its own declaration', async () => { + const entry = symbol('LibTmux.Selection.new/2') + expect(entry.signatures.length).toBeGreaterThan(1) + const { window, signatures } = await renderSignatures(entry, 'elixir', index) + try { + expect(signatures).toHaveLength(entry.signatures.length) + expect(new Set(signatures.map((element) => displayedSignature(element))).size).toBe(entry.signatures.length) + } finally { await window.happyDOM.abort() } + }) diff --git a/site/test/elixir-layout.test.ts b/site/test/elixir-layout.test.ts index af8177acc..7421277d6 100644 --- a/site/test/elixir-layout.test.ts +++ b/site/test/elixir-layout.test.ts @@ -7,7 +7,6 @@ import { usesNativeSignatures } from '../src/lib/api-sections' import { apiSignatureLayouts, CODE_COLUMNS, codeWidthFailures, signatureSpans, supportsElixirSignatures } from '../src/lib/code-layout' import { productApiIndex } from '../src/lib/product-api' import { symbolMarkdownWithLayout } from '../src/lib/symbol-markdown' -import { displayedSignature, renderSignatures } from './signature-fragment' const model = API_MODELS.elixir const index = productApiIndex(model, 'latest') @@ -65,33 +64,6 @@ describe('Elixir declarations', () => { expect(field.find((span) => span.text === 'String.t')?.link).toMatchObject({ external: true, href: 'https://elixir.hexdocs.pm/String.html#t:t/0' }) }) - it('render as one preformatted declaration with working links and no nested anchors', async () => { - const entry = symbol('LibTmux.Control.submit/3') - const nameHref = `/en/elixir/latest/reference/${entry.slug}/` - const { window, signatures, layouts } = await renderSignatures(entry, 'elixir', index, nameHref) - try { - expect(signatures).toHaveLength(entry.signatures.length) - const [rendered] = signatures - expect(rendered!.classList.contains('api-native-signature--formatted')).toBe(true) - expect(rendered!.getAttribute('data-code-columns')).toBe(String(CODE_COLUMNS.api)) - expect(rendered!.getAttribute('data-code-width-status')).toBe('fits') - expect(displayedSignature(rendered!)).toBe(layouts.get(entry.signatures[0]!)!.text) - expect(rendered!.querySelector('.api-signature-name-link')?.getAttribute('href')).toBe(nameHref) - expect([...rendered!.querySelectorAll('a.api-parameter-name')].map((link) => link.textContent)).toEqual(['control', 'request', 'options']) - expect(rendered!.querySelector('a a')).toBeNull() - } finally { await window.happyDOM.abort() } - }) - - it('give each spec clause of an overloaded function its own declaration', async () => { - const entry = symbol('LibTmux.Selection.new/2') - expect(entry.signatures.length).toBeGreaterThan(1) - const { window, signatures } = await renderSignatures(entry, 'elixir', index) - try { - expect(signatures).toHaveLength(entry.signatures.length) - expect(new Set(signatures.map((element) => displayedSignature(element))).size).toBe(entry.signatures.length) - } finally { await window.happyDOM.abort() } - }) - it('reach the Markdown twin as an Elixir code block', async () => { const entry = symbol('LibTmux.Server.snapshot/2') const markdown = await symbolMarkdownWithLayout({ model, symbol: entry, index }) diff --git a/site/test/enum-variants.test.ts b/site/test/enum-variants.test.ts index 7ca8adf68..b413e0507 100644 --- a/site/test/enum-variants.test.ts +++ b/site/test/enum-variants.test.ts @@ -6,7 +6,7 @@ import { fileURLToPath } from 'node:url' import { Window } from 'happy-dom' import { afterEach, describe, expect, it, vi } from 'vitest' import { experimental_AstroContainer } from 'astro/container' -import { membersOf, memberSignals, pageMembersOf, symbolsForProduct, SymbolIndex, type ApiSymbol } from '@libtmux/api-model' +import { membersOf, memberSignals, pageMembersOf, symbolsForProduct, SymbolIndex, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { apiMemberSections, memberTable, memberTableColumns, splitVariantMembers, variantPayloads } from '../src/lib/api-sections' import mentionsData from '../src/data/mentions.json' diff --git a/site/test/field-members.test.ts b/site/test/field-members.test.ts index d04bd5307..3dcedcfb6 100644 --- a/site/test/field-members.test.ts +++ b/site/test/field-members.test.ts @@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs' import { Window } from 'happy-dom' import { afterAll, describe, expect, it, vi } from 'vitest' import { experimental_AstroContainer } from 'astro/container' -import { membersOf, memberSignals, memberTier, SymbolIndex, type ApiSymbol } from '@libtmux/api-model' +import { membersOf, memberSignals, memberTier, SymbolIndex, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { apiMemberSections, fieldsLabel, hasFieldMembers, memberTableColumns, splitFieldMembers } from '../src/lib/api-sections' import mentionsData from '../src/data/mentions.json' diff --git a/site/test/field-table-pages.test.ts b/site/test/field-table-pages.test.ts index 434062c90..8c4c5c6b4 100644 --- a/site/test/field-table-pages.test.ts +++ b/site/test/field-table-pages.test.ts @@ -7,7 +7,7 @@ import { Window } from 'happy-dom' import { afterEach, describe, expect, it, vi } from 'vitest' import { experimental_AstroContainer } from 'astro/container' import { createComponent, renderTemplate } from 'astro/runtime/server/index.js' -import { SymbolIndex, type ApiSymbol } from '@libtmux/api-model' +import { SymbolIndex, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { fieldsRepeated, LONG_CELL_CHARACTERS, memberTable, scalarCellCharacters, scalarCellsAreLong } from '../src/lib/api-sections' import { apiComponents } from './api-components' diff --git a/site/test/fixtures/header-links.ts b/site/test/fixtures/header-links.ts index fbc6d6c9f..d058a9c6d 100644 --- a/site/test/fixtures/header-links.ts +++ b/site/test/fixtures/header-links.ts @@ -25,6 +25,17 @@ export interface ExpectedLinks { } export const LINKS: Record = { + perl: { + actions: [['source', 'GitHub', 'GitHub: libtmux/libtmux-perl/packages/core', 'https://github.com/libtmux/libtmux-perl/tree/master/packages/core']], + indexed: true, + rows: [ + ['source', 'LibTmux', 'packages/core', 'https://github.com/libtmux/libtmux-perl/tree/master/packages/core', ['LibTmux']], + ['source', 'LibTmux-Async', 'packages/async', 'https://github.com/libtmux/libtmux-perl/tree/master/packages/async', ['LibTmux-Async']], + ['source', 'libtmux-perl', 'libtmux/libtmux-perl', 'https://github.com/libtmux/libtmux-perl', ['repository']], + ['source', 'LibTmux-Workspace', 'packages/workspace', 'https://github.com/libtmux/libtmux-perl/tree/master/packages/workspace', ['LibTmux-Workspace']], + ['source', 'libtmux-workspace', 'command · packages/workspace/bin/libtmux-workspace', 'https://github.com/libtmux/libtmux-perl/blob/master/packages/workspace/bin/libtmux-workspace', ['libtmux-workspace']], + ], + }, py: { actions: [['source', 'GitHub', 'GitHub: tmux-python/libtmux', 'https://github.com/tmux-python/libtmux'], ['package', 'PyPI', 'PyPI: libtmux package', 'https://pypi.org/project/libtmux/']], diff --git a/site/test/fixtures/home-examples.json b/site/test/fixtures/home-examples.json index e431ba348..fbbf1aa69 100644 --- a/site/test/fixtures/home-examples.json +++ b/site/test/fixtures/home-examples.json @@ -1465,6 +1465,98 @@ "excerptSha256": "315b120fc40982d69ab2945b84a0b2c6df5faf8d63d75bf940739cd6e23b68af" } } + }, + { + "port": "perl", + "page": "home", + "sourceRepository": "libtmux/libtmux-perl", + "sourceRevision": "36b978c5eb6aa33873229046037e7d26136ca2cf", + "sourceTree": "269782d0ba1403af082abe05736ade4e31b5aa53", + "files": [ + { + "name": "examples/quickstart.pl", + "sha256": "ba9f650b81972f6b11556c4babd22b19d868335d9701980069e5d37748ce3cf2", + "clipboardSha256": "a6e4fe17a24b02610dd71a460c9316e7349ef5c2764033e919203d0a06fa8cfd" + }, + { + "name": "scripts/lib/LibTmuxFixture.pm", + "sha256": "6b17d71a3bb2251d7512d5872bc60791fb0f4b1c0557a6d47e6799aaeabed94e", + "clipboardSha256": "50c57a617a04dfe553cbbcfd726f1f6a24e8e8cb77ca171aec86cd0f534f3667" + } + ], + "shellRecipe": [ + "perl examples/quickstart.pl" + ], + "expectedOutputs": [ + [ + "session demo", + " window 0:editor: %0 %1", + " window 1:logs: %2", + "%1 is in window editor" + ] + ], + "excerptSha256": "a6e4fe17a24b02610dd71a460c9316e7349ef5c2764033e919203d0a06fa8cfd", + "tmuxVersions": [ + "3.3a", + "3.4", + "3.5", + "3.5a", + "3.6", + "3.6a", + "3.6b", + "3.7", + "3.7a", + "3.7b", + "3.7c", + "3.8" + ], + "variants": { + "concise": { + "files": [ + { + "name": "examples/quickstart.pl", + "sha256": "229dc9ad4a3802b98c05c8014f999ae708622380ea9c33de86d8a64ddaa976d7", + "clipboardSha256": "0f56b6c69c9f65059b161e876346d5c164fd2463371f00fb5cf1df23de43936e" + }, + { + "name": "scripts/lib/LibTmuxFixture.pm", + "sha256": "6b17d71a3bb2251d7512d5872bc60791fb0f4b1c0557a6d47e6799aaeabed94e", + "clipboardSha256": "50c57a617a04dfe553cbbcfd726f1f6a24e8e8cb77ca171aec86cd0f534f3667" + } + ], + "excerptSha256": "0f56b6c69c9f65059b161e876346d5c164fd2463371f00fb5cf1df23de43936e" + }, + "errors": { + "files": [ + { + "name": "examples/quickstart.pl", + "sha256": "c87d40c67b319ab6921271be902dbfc0c4be706fe28ea08d1910e98aeae1de77", + "clipboardSha256": "1b06fe564ac4ab43baac37aeb5473fe3a5434c1d3bc78c4c5e9570910b463fc6" + }, + { + "name": "scripts/lib/LibTmuxFixture.pm", + "sha256": "6b17d71a3bb2251d7512d5872bc60791fb0f4b1c0557a6d47e6799aaeabed94e", + "clipboardSha256": "50c57a617a04dfe553cbbcfd726f1f6a24e8e8cb77ca171aec86cd0f534f3667" + } + ], + "excerptSha256": "1b06fe564ac4ab43baac37aeb5473fe3a5434c1d3bc78c4c5e9570910b463fc6" + }, + "cleanup": { + "files": [ + { + "name": "examples/quickstart.pl", + "sha256": "d4ba09045ef72f61fd8f3d97bf4ffa3700af0d7b397b179700e8e35895a796f9", + "clipboardSha256": "29d2e40a82a47781c8673f3de385a9d106e598dac819a35202c10b1b4205a7dd" + }, + { + "name": "scripts/lib/LibTmuxFixture.pm", + "sha256": "6b17d71a3bb2251d7512d5872bc60791fb0f4b1c0557a6d47e6799aaeabed94e", + "clipboardSha256": "50c57a617a04dfe553cbbcfd726f1f6a24e8e8cb77ca171aec86cd0f534f3667" + } + ], + "excerptSha256": "29d2e40a82a47781c8673f3de385a9d106e598dac819a35202c10b1b4205a7dd" + } + } } ] } diff --git a/site/test/header-link-data.test.ts b/site/test/header-link-data.test.ts index 8a9e57526..2a6dbf430 100644 --- a/site/test/header-link-data.test.ts +++ b/site/test/header-link-data.test.ts @@ -133,7 +133,7 @@ describe('header links', () => { expect(links('lua').indexed).toBe(false) // Nothing the inventory excludes reaches any port’s header. for (const port of PORTS) { - const excluded = INVENTORY[port.slug]!.filter((entry) => entry.status !== 'published') + const excluded = INVENTORY[port.slug]!.filter((entry) => entry.status !== 'published' && !entry.sourceAvailable) for (const entry of excluded) expect(links(port.slug).rows.flatMap((row) => row.entries), `${port.slug} ${entry.id}`).not.toContain(entry.id) } }) diff --git a/site/test/inventory-federation.test.ts b/site/test/inventory-federation.test.ts index d05e5f623..62d6f1084 100644 --- a/site/test/inventory-federation.test.ts +++ b/site/test/inventory-federation.test.ts @@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' -import { readInventory, symbolEntries } from '@libtmux/api-model' +import { readInventory, symbolEntries } from '@libtmux/api-model/reference' import { API_MODELS, createApiIndex, indexFor } from '../src/lib/api-models' import { productApiIndex } from '../src/lib/product-api' import { createProseLinker } from '../src/lib/prose-resolver' diff --git a/site/test/inventory.test.ts b/site/test/inventory.test.ts index 068d1e591..960e124fc 100644 --- a/site/test/inventory.test.ts +++ b/site/test/inventory.test.ts @@ -2,7 +2,7 @@ import { existsSync, mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { afterEach, describe, expect, it, vi } from 'vitest' -import { readInventory, targetEntries, targetKey } from '@libtmux/api-model' +import { readInventory, targetEntries, targetKey } from '@libtmux/api-model/reference' import { apiInventoryIdentity, installFragmentAlias, mergeTargets, renderedTargets, type InventoryPage } from '../src/lib/inventory-targets' import type { ApiSymbol } from '@libtmux/api-model' import { collectInventoryTargets, publishAssembledInventories } from '../src/lib/inventory-publisher' diff --git a/site/test/link-preview-payload.test.ts b/site/test/link-preview-payload.test.ts index 51a6cadca..570256014 100644 --- a/site/test/link-preview-payload.test.ts +++ b/site/test/link-preview-payload.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { docSummaryText } from '@libtmux/api-model' +import { docSummaryText } from '@libtmux/api-model/reference' import { API_GLOSSARY_PATH } from '../src/lib/api-glossary' import { API_MODELS } from '../src/lib/api-models' import { nativeQualifiedName } from '../src/lib/native-name' diff --git a/site/test/literal-links.test.ts b/site/test/literal-links.test.ts index 84abfe9b8..cdbd5315b 100644 --- a/site/test/literal-links.test.ts +++ b/site/test/literal-links.test.ts @@ -1,6 +1,6 @@ import { readFileSync, writeFileSync } from 'node:fs' import { describe, expect, it, vi } from 'vitest' -import { proseTexts, SymbolIndex, type ApiSymbol } from '@libtmux/api-model' +import { proseTexts, SymbolIndex, type ApiSymbol } from '@libtmux/api-model/reference' import { TYPE_KINDS } from '../../packages/api-model/src/link' import { API_MODELS } from '../src/lib/api-models' import { defaultVersionFor } from '../src/lib/versions' diff --git a/site/test/lua-layout-rendering.outer.test.ts b/site/test/lua-layout-rendering.outer.test.ts new file mode 100644 index 000000000..47acd252d --- /dev/null +++ b/site/test/lua-layout-rendering.outer.test.ts @@ -0,0 +1,26 @@ +// Compiles and renders real Astro declarations; pure layout fixtures remain in medium. +import { expect, it } from 'vitest' +import { API_MODELS } from '../src/lib/api-models' +import { displayedSignature, renderSignatures } from './signature-fragment' +import { fromMarkdown } from 'mdast-util-from-markdown' +import { SymbolIndex } from '@libtmux/api-model/reference' +import { symbolMarkdownWithLayout } from '../src/lib/symbol-markdown' + +const model = API_MODELS.lua + +it('renders the page declaration, with every overload, from the Markdown layout', async () => { + const index = new SymbolIndex(model.symbols, (entry) => `/en/lua/latest/reference/${entry.slug}/`, 'lua') + for (const id of ['libtmux.Window:set_option', 'libtmux.Server:handle']) { + const symbol = model.symbols.find((entry) => entry.id === id)! + const { signatures, window, layouts: prepared } = await renderSignatures(symbol, 'lua', index) + try { + const expected = symbol.signatures.map((signature) => prepared.get(signature)!.text) + expect(signatures.map(displayedSignature)).toEqual(expected) + expect(signatures.map((element) => element.getAttribute('data-code-width-status'))) + .toEqual(expected.map((text) => text.split('\n').some((line) => line.length > 60) ? 'unresolved' : 'fits')) + expect([...window.document.querySelectorAll('a')].filter((link) => link.textContent === symbol.name)).toEqual([]) + const fenced = fromMarkdown(await symbolMarkdownWithLayout({ model, symbol })).children.find((node) => node.type === 'code') + expect(fenced?.type === 'code' && fenced.value).toBe(expected.join('\n\n')) + } finally { await window.happyDOM.abort() } + } + }) diff --git a/site/test/lua-layout.test.ts b/site/test/lua-layout.test.ts index 8d67d0bc9..b258c36de 100644 --- a/site/test/lua-layout.test.ts +++ b/site/test/lua-layout.test.ts @@ -1,11 +1,10 @@ import { readFileSync } from 'node:fs' import { describe, expect, it } from 'vitest' import { fromMarkdown } from 'mdast-util-from-markdown' -import { parameterId, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model' +import { parameterId, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model/reference' import { apiEntryFields, usesNativeSignatures } from '../src/lib/api-sections' import { apiSignatureLayouts, codeWidthFailures, signatureSpans, supportsLuaSignatures } from '../src/lib/code-layout' import { symbolMarkdownWithLayout } from '../src/lib/symbol-markdown' -import { displayedSignature, renderSignatures } from './signature-fragment' interface Fixture { tools: Record @@ -186,22 +185,6 @@ describe('LuaCATS function layouts', () => { expect(apiEntryFields(symbol, 'lua').params.map((param) => param.name)).toEqual(['other', 'options']) }) - it('renders the page declaration, with every overload, from the Markdown layout', async () => { - const index = new SymbolIndex(model.symbols, (entry) => `/en/lua/latest/reference/${entry.slug}/`, 'lua') - for (const id of ['libtmux.Window:set_option', 'libtmux.Server:handle']) { - const symbol = model.symbols.find((entry) => entry.id === id)! - const { signatures, window, layouts: prepared } = await renderSignatures(symbol, 'lua', index) - try { - const expected = symbol.signatures.map((signature) => prepared.get(signature)!.text) - expect(signatures.map(displayedSignature)).toEqual(expected) - expect(signatures.map((element) => element.getAttribute('data-code-width-status'))) - .toEqual(expected.map((text) => text.split('\n').some((line) => line.length > 60) ? 'unresolved' : 'fits')) - expect([...window.document.querySelectorAll('a')].filter((link) => link.textContent === symbol.name)).toEqual([]) - const fenced = fromMarkdown(await symbolMarkdownWithLayout({ model, symbol })).children.find((node) => node.type === 'code') - expect(fenced?.type === 'code' && fenced.value).toBe(expected.join('\n\n')) - } finally { await window.happyDOM.abort() } - } - }) }) it('leaves classes and fields to the generic declaration', () => { diff --git a/site/test/mcp-description-audit.ts b/site/test/mcp-description-audit.ts index c2b044387..d3839507b 100644 --- a/site/test/mcp-description-audit.ts +++ b/site/test/mcp-description-audit.ts @@ -1,5 +1,5 @@ import { fromHtml } from 'hast-util-from-html' -import { parsePythonDoc } from '@libtmux/api-model' +import { parsePythonDoc } from '@libtmux/api-model/reference' import { MCP_REFERENCE, mcpObjects, toolSummary, type McpObject } from '../src/lib/mcp-reference' import { tmuxMentions } from '../src/lib/tmux-links' diff --git a/site/test/mcp-session.outer.test.ts b/site/test/mcp-session.outer.test.ts new file mode 100644 index 000000000..307612701 --- /dev/null +++ b/site/test/mcp-session.outer.test.ts @@ -0,0 +1,195 @@ +// Exercises owned recorder subprocesses and cleanup; pure value fixtures remain in medium. +import { describe, expect, it } from 'vitest' +import { listedBy, recordCalls, recordSettled, refusalCode, standInCalls, standInControls, withListed } from '../../scripts/lib/mcp-session.mjs' +import { UnsettledPaneError } from '../../scripts/lib/mcp-transcript-checks.mjs' + +/** + * A stdio MCP server in a few lines: `list` answers with a generation, and + * `use` is refused as `stale_target` unless it is sent that generation. + */ +const SERVER = ` +const GENERATION = '4242:1700000000' +let buffer = '' +const send = (id, result) => process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id, result }) + '\\n') +process.stdin.on('data', (chunk) => { + buffer += chunk + for (const line of buffer.split('\\n').slice(0, -1)) { + const message = JSON.parse(line) + if (message.method === 'initialize') send(message.id, { serverInfo: { name: 'fake' } }) + if (message.method === 'tools/call' && message.params.name === 'list') send(message.id, { content: [], structuredContent: { panes: [{ target: { generation: GENERATION } }] } }) + if (message.method === 'tools/call' && message.params.name === 'use') { + const stale = message.params.arguments.target.generation !== GENERATION + send(message.id, { isError: stale, content: [], structuredContent: stale ? { code: 'stale_target' } : { code: 'ok' } }) + } + } + buffer = buffer.slice(buffer.lastIndexOf('\\n') + 1) +}) +process.stdin.on('end', () => process.exit(0)) +` +const run = (calls: Parameters[0]['calls'], controls: Parameters[0]['controls'] = []) => recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, controls, pauseMs: 0, callTimeoutMs: 10000 }) + +describe('a call that needs a value only an earlier result returns', () => { + const stand = { target: { paneId: '%0', generation: '3f9a1c' } } + + it('is sent the value the listing returned, and the step records what was sent', async () => { + const { steps } = await run([{ tool: 'list', arguments: {} }, { tool: 'use', arguments: withListed(stand, '3f9a1c', 'generation') }]) + expect(steps[1]).toMatchObject({ isError: false, arguments: { target: { paneId: '%0', generation: '4242:1700000000' } } }) + }) + + it('has a control: the stand-in itself is refused as stale_target, so the swap is what makes the call work', async () => { + const { steps } = await run([{ tool: 'list', arguments: {} }, { tool: 'use', arguments: stand }]) + expect(steps[1]).toMatchObject({ isError: true, arguments: stand, structuredContent: { code: 'stale_target' } }) + }) + + it('refuses to send the stand-in when no earlier result returned the value', async () => { + await expect(run([{ tool: 'use', arguments: withListed(stand, '3f9a1c', 'generation') }])).rejects.toThrow(/no earlier result returned a "generation"/) + }) + +}) + +describe('the calls the recorder sends for an example that holds a stand-in', () => { + const example = [ + { tool: 'list', arguments: {} }, + { tool: 'use', arguments: { target: { paneId: '%0', generation: '3f9a1c' } } }, + { tool: 'list', arguments: { note: 'no stand-in here' } }, + ] + + it('swaps the stand-in in the calls that carry it, sends the others as written, and the recorded step keeps what went out', async () => { + const calls = standInCalls(example, '3f9a1c', 'generation') + expect(calls.map((call) => typeof call.arguments)).toEqual(['object', 'function', 'object']) + expect(calls[0]!.arguments).toBe(example[0]!.arguments) + expect(calls[2]!.arguments).toBe(example[2]!.arguments) + const { steps } = await run(calls) + expect(steps[1]).toMatchObject({ isError: false, arguments: { target: { paneId: '%0', generation: '4242:1700000000' } }, structuredContent: { code: 'ok' } }) + expect(JSON.stringify(steps.map((step) => step.arguments)), 'the stand-in never went out').not.toContain('3f9a1c') + }) + + it('has a control: the example sent as written is refused as stale_target', async () => { + const { steps } = await run(example) + expect(steps[1]).toMatchObject({ isError: true, structuredContent: { code: 'stale_target' } }) + }) + + it('refuses to send a call that carries the stand-in before any result lists the value', async () => { + await expect(run(standInCalls(example.slice(1), '3f9a1c', 'generation'))).rejects.toThrow(/no earlier result returned a "generation" to send in place of 3f9a1c/) + }) + +}) + +describe('the control calls of a recording', () => { + const example = [ + { tool: 'list', arguments: {} }, + { tool: 'use', arguments: { target: { paneId: '%0', generation: '3f9a1c' } } }, + { tool: 'use', arguments: { target: { paneId: '%1', generation: '3f9a1c' } } }, + ] + + it('makes the stand-in call as written once the example is done, in the same session, and keeps its answer out of the steps', async () => { + const controls = standInControls(example, '3f9a1c') + expect(controls).toEqual([{ tool: 'use', arguments: example[1]!.arguments }]) + const { steps, controls: answered } = await run([...standInCalls(example.slice(0, 2), '3f9a1c', 'generation')], controls) + expect(steps.map((step) => step.tool)).toEqual(['list', 'use']) + expect(answered).toHaveLength(1) + expect(answered[0]).toMatchObject({ tool: 'use', isError: true, arguments: { target: { generation: '3f9a1c' } } }) + expect(refusalCode(answered[0])).toBe('stale_target') + expect(refusalCode(steps[1]), 'a call the server accepted has no refusal').toBeUndefined() + }) + + it('names the tool that returned the value', async () => { + const { steps } = await run([example[0]!]) + expect(listedBy(steps, 'generation')).toBe('list') + expect(listedBy(steps, 'nothing')).toBeUndefined() + }) +}) + +describe('the state a recording reads after each call', () => { + const calls = [{ tool: 'list', arguments: {} }, { tool: 'list', arguments: {} }, { tool: 'list', arguments: {} }] + + it('reads once before the first call and after each, and stores the state on its step', async () => { + const { before, steps } = await recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, pauseMs: 0, callTimeoutMs: 10000, observe: (step) => ({ after: step ? step.tool : null }) }) + expect(before).toEqual({ after: null }) + expect(steps.map((step) => step.tmux)).toEqual([{ after: 'list' }, { after: 'list' }, { after: 'list' }]) + }) + + it('reads a state only once the pause that stands for an agent reading the result has passed', async () => { + const times: number[] = [] + await recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, pauseMs: 80, callTimeoutMs: 10000, observe: () => { times.push(Date.now()) } }) + expect(times).toHaveLength(calls.length + 1) + for (let at = 1; at < times.length; at++) expect(times[at]! - times[at - 1]!, `read ${at}`).toBeGreaterThanOrEqual(70) + }) + + it('ends the session with the error when a state cannot be read, so no step is recorded without one', async () => { + const failing = recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, pauseMs: 0, callTimeoutMs: 10000, observe: (step) => { if (step) throw new Error('tmux could not be read') } }) + await expect(failing).rejects.toThrow('tmux could not be read') + }) + + it('stores no state, and returns none, when nothing reads it', async () => { + const recorded = await run(calls) + expect(recorded).not.toHaveProperty('before') + expect(recorded.steps.every((step) => !('tmux' in step))).toBe(true) + }) +}) + +describe('recording again when the state does not settle', () => { + const calls = [{ tool: 'list', arguments: {} }, { tool: 'list', arguments: {} }] + const unsettled = (message = 'x: tmux was still changing 8000ms after list') => new UnsettledPaneError(message) + + /** The recorder's loop around a real session, whose observer takes the part of a settle check that times out. */ + const attempt = (outcomes: ('settles' | 'times out')[], extra: Partial>>>[0]> = {}) => { + const events: string[] = [] + let made = 0 + const result = recordSettled({ + attempts: 3, + record: async (number) => { + made++ + events.push(`record ${number}`) + const outcome = outcomes[number - 1]! + return recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, pauseMs: 0, callTimeoutMs: 10000, observe: (step) => { if (step && outcome === 'times out') throw unsettled() } }) + }, + reset: () => { events.push('reset') }, + warn: (message) => events.push(`warn ${message}`), + ...extra, + }) + return { result, events, made: () => made } + } + + it('records again after a settle check that times out while the calls run, which used to end the run', async () => { + const { result, events } = attempt(['times out', 'settles']) + const recorded = await result + expect(recorded.steps.map((step) => step.tool)).toEqual(['list', 'list']) + expect(events).toEqual(['record 1', 'warn x: tmux was still changing 8000ms after list; recording again', 'reset', 'record 2']) + }) + + it('records again after an answer that fails the check once the session has ended', async () => { + let checks = 0 + const { result, events } = attempt(['settles', 'settles'], { check: () => { if (++checks === 1) throw unsettled('x: tmux ran "tmux" in %1 after split_window, not sh') } }) + await result + expect(events.filter((event) => event.startsWith('record'))).toEqual(['record 1', 'record 2']) + expect(events).toContain('reset') + }) + + it('gives up after the attempts it was given, resetting between them and not after the last', async () => { + const { result, events, made } = attempt(['times out', 'times out', 'times out']) + await expect(result).rejects.toThrow('x: tmux was still changing 8000ms after list; still unsettled after 3 recordings') + await expect(result).rejects.toBeInstanceOf(Error) + expect(made()).toBe(3) + expect(events.filter((event) => event === 'reset')).toHaveLength(2) + }) + + it('ends the run at once on any other error, without resetting', async () => { + const { result, events } = attempt(['settles'], { check: () => { throw new Error('x: step 2 returned an error') } }) + await expect(result).rejects.toThrow('step 2 returned an error') + expect(events).toEqual(['record 1']) + const failed = recordSettled({ attempts: 3, record: async () => { throw new Error('the server did not exit') }, reset: () => { throw new Error('must not reset') } }) + await expect(failed).rejects.toThrow('the server did not exit') + }) + + it('waits for an asynchronous reset before the next recording', async () => { + const order: string[] = [] + let tries = 0 + await recordSettled({ + attempts: 2, + record: async () => { order.push('record'); if (++tries === 1) throw unsettled(); return 'done' }, + reset: async () => { order.push('reset starts'); await new Promise((resolve) => setTimeout(resolve, 20)); order.push('reset ends') }, + }) + expect(order).toEqual(['record', 'reset starts', 'reset ends', 'record']) + }) +}) diff --git a/site/test/mcp-session.test.ts b/site/test/mcp-session.test.ts index 761a52fec..1f4db7119 100644 --- a/site/test/mcp-session.test.ts +++ b/site/test/mcp-session.test.ts @@ -1,48 +1,7 @@ import { describe, expect, it } from 'vitest' -import { listedBy, listedValue, recordCalls, recordSettled, refusalCode, requireRefusal, standInCalls, standInControls, withListed } from '../../scripts/lib/mcp-session.mjs' -import { UnsettledPaneError } from '../../scripts/lib/mcp-transcript-checks.mjs' - -/** - * A stdio MCP server in a few lines: `list` answers with a generation, and - * `use` is refused as `stale_target` unless it is sent that generation. - */ -const SERVER = ` -const GENERATION = '4242:1700000000' -let buffer = '' -const send = (id, result) => process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id, result }) + '\\n') -process.stdin.on('data', (chunk) => { - buffer += chunk - for (const line of buffer.split('\\n').slice(0, -1)) { - const message = JSON.parse(line) - if (message.method === 'initialize') send(message.id, { serverInfo: { name: 'fake' } }) - if (message.method === 'tools/call' && message.params.name === 'list') send(message.id, { content: [], structuredContent: { panes: [{ target: { generation: GENERATION } }] } }) - if (message.method === 'tools/call' && message.params.name === 'use') { - const stale = message.params.arguments.target.generation !== GENERATION - send(message.id, { isError: stale, content: [], structuredContent: stale ? { code: 'stale_target' } : { code: 'ok' } }) - } - } - buffer = buffer.slice(buffer.lastIndexOf('\\n') + 1) -}) -process.stdin.on('end', () => process.exit(0)) -` -const run = (calls: Parameters[0]['calls'], controls: Parameters[0]['controls'] = []) => recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, controls, pauseMs: 0, callTimeoutMs: 10000 }) +import { listedValue, refusalCode, requireRefusal, standInCalls, standInControls } from '../../scripts/lib/mcp-session.mjs' describe('a call that needs a value only an earlier result returns', () => { - const stand = { target: { paneId: '%0', generation: '3f9a1c' } } - - it('is sent the value the listing returned, and the step records what was sent', async () => { - const { steps } = await run([{ tool: 'list', arguments: {} }, { tool: 'use', arguments: withListed(stand, '3f9a1c', 'generation') }]) - expect(steps[1]).toMatchObject({ isError: false, arguments: { target: { paneId: '%0', generation: '4242:1700000000' } } }) - }) - - it('has a control: the stand-in itself is refused as stale_target, so the swap is what makes the call work', async () => { - const { steps } = await run([{ tool: 'list', arguments: {} }, { tool: 'use', arguments: stand }]) - expect(steps[1]).toMatchObject({ isError: true, arguments: stand, structuredContent: { code: 'stale_target' } }) - }) - - it('refuses to send the stand-in when no earlier result returned the value', async () => { - await expect(run([{ tool: 'use', arguments: withListed(stand, '3f9a1c', 'generation') }])).rejects.toThrow(/no earlier result returned a "generation"/) - }) it('finds the value at any depth, takes the first, and ignores a value that is not a string', () => { const step = (structuredContent: unknown) => ({ structuredContent }) @@ -59,25 +18,6 @@ describe('the calls the recorder sends for an example that holds a stand-in', () { tool: 'list', arguments: { note: 'no stand-in here' } }, ] - it('swaps the stand-in in the calls that carry it, sends the others as written, and the recorded step keeps what went out', async () => { - const calls = standInCalls(example, '3f9a1c', 'generation') - expect(calls.map((call) => typeof call.arguments)).toEqual(['object', 'function', 'object']) - expect(calls[0]!.arguments).toBe(example[0]!.arguments) - expect(calls[2]!.arguments).toBe(example[2]!.arguments) - const { steps } = await run(calls) - expect(steps[1]).toMatchObject({ isError: false, arguments: { target: { paneId: '%0', generation: '4242:1700000000' } }, structuredContent: { code: 'ok' } }) - expect(JSON.stringify(steps.map((step) => step.arguments)), 'the stand-in never went out').not.toContain('3f9a1c') - }) - - it('has a control: the example sent as written is refused as stale_target', async () => { - const { steps } = await run(example) - expect(steps[1]).toMatchObject({ isError: true, structuredContent: { code: 'stale_target' } }) - }) - - it('refuses to send a call that carries the stand-in before any result lists the value', async () => { - await expect(run(standInCalls(example.slice(1), '3f9a1c', 'generation'))).rejects.toThrow(/no earlier result returned a "generation" to send in place of 3f9a1c/) - }) - it('leaves every call as written when the example has no stand-in', () => { expect(standInCalls(example, undefined, 'generation').map((call) => call.arguments)).toEqual(example.map((call) => call.arguments)) expect(standInCalls(example, '', 'generation').every((call) => typeof call.arguments === 'object')).toBe(true) @@ -91,17 +31,6 @@ describe('the control calls of a recording', () => { { tool: 'use', arguments: { target: { paneId: '%1', generation: '3f9a1c' } } }, ] - it('makes the stand-in call as written once the example is done, in the same session, and keeps its answer out of the steps', async () => { - const controls = standInControls(example, '3f9a1c') - expect(controls).toEqual([{ tool: 'use', arguments: example[1]!.arguments }]) - const { steps, controls: answered } = await run([...standInCalls(example.slice(0, 2), '3f9a1c', 'generation')], controls) - expect(steps.map((step) => step.tool)).toEqual(['list', 'use']) - expect(answered).toHaveLength(1) - expect(answered[0]).toMatchObject({ tool: 'use', isError: true, arguments: { target: { generation: '3f9a1c' } } }) - expect(refusalCode(answered[0])).toBe('stale_target') - expect(refusalCode(steps[1]), 'a call the server accepted has no refusal').toBeUndefined() - }) - it('has no control without a stand-in, and finds the code of a refusal wherever the server puts it', () => { expect(standInControls(example, undefined)).toEqual([]) expect(standInControls(example.slice(0, 1), '3f9a1c')).toEqual([]) @@ -120,103 +49,4 @@ describe('the control calls of a recording', () => { expect(() => requireRefusal({ isError: true, structuredContent: {} }, options), 'a refusal that carries no code').toThrow(/did not refuse/) }) - it('names the tool that returned the value', async () => { - const { steps } = await run([example[0]!]) - expect(listedBy(steps, 'generation')).toBe('list') - expect(listedBy(steps, 'nothing')).toBeUndefined() - }) -}) - -describe('the state a recording reads after each call', () => { - const calls = [{ tool: 'list', arguments: {} }, { tool: 'list', arguments: {} }, { tool: 'list', arguments: {} }] - - it('reads once before the first call and after each, and stores the state on its step', async () => { - const { before, steps } = await recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, pauseMs: 0, callTimeoutMs: 10000, observe: (step) => ({ after: step ? step.tool : null }) }) - expect(before).toEqual({ after: null }) - expect(steps.map((step) => step.tmux)).toEqual([{ after: 'list' }, { after: 'list' }, { after: 'list' }]) - }) - - it('reads a state only once the pause that stands for an agent reading the result has passed', async () => { - const times: number[] = [] - await recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, pauseMs: 80, callTimeoutMs: 10000, observe: () => { times.push(Date.now()) } }) - expect(times).toHaveLength(calls.length + 1) - for (let at = 1; at < times.length; at++) expect(times[at]! - times[at - 1]!, `read ${at}`).toBeGreaterThanOrEqual(70) - }) - - it('ends the session with the error when a state cannot be read, so no step is recorded without one', async () => { - const failing = recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, pauseMs: 0, callTimeoutMs: 10000, observe: (step) => { if (step) throw new Error('tmux could not be read') } }) - await expect(failing).rejects.toThrow('tmux could not be read') - }) - - it('stores no state, and returns none, when nothing reads it', async () => { - const recorded = await run(calls) - expect(recorded).not.toHaveProperty('before') - expect(recorded.steps.every((step) => !('tmux' in step))).toBe(true) - }) -}) - -describe('recording again when the state does not settle', () => { - const calls = [{ tool: 'list', arguments: {} }, { tool: 'list', arguments: {} }] - const unsettled = (message = 'x: tmux was still changing 8000ms after list') => new UnsettledPaneError(message) - - /** The recorder's loop around a real session, whose observer takes the part of a settle check that times out. */ - const attempt = (outcomes: ('settles' | 'times out')[], extra: Partial>>>[0]> = {}) => { - const events: string[] = [] - let made = 0 - const result = recordSettled({ - attempts: 3, - record: async (number) => { - made++ - events.push(`record ${number}`) - const outcome = outcomes[number - 1]! - return recordCalls({ command: process.execPath, args: ['-e', SERVER], calls, pauseMs: 0, callTimeoutMs: 10000, observe: (step) => { if (step && outcome === 'times out') throw unsettled() } }) - }, - reset: () => { events.push('reset') }, - warn: (message) => events.push(`warn ${message}`), - ...extra, - }) - return { result, events, made: () => made } - } - - it('records again after a settle check that times out while the calls run, which used to end the run', async () => { - const { result, events } = attempt(['times out', 'settles']) - const recorded = await result - expect(recorded.steps.map((step) => step.tool)).toEqual(['list', 'list']) - expect(events).toEqual(['record 1', 'warn x: tmux was still changing 8000ms after list; recording again', 'reset', 'record 2']) - }) - - it('records again after an answer that fails the check once the session has ended', async () => { - let checks = 0 - const { result, events } = attempt(['settles', 'settles'], { check: () => { if (++checks === 1) throw unsettled('x: tmux ran "tmux" in %1 after split_window, not sh') } }) - await result - expect(events.filter((event) => event.startsWith('record'))).toEqual(['record 1', 'record 2']) - expect(events).toContain('reset') - }) - - it('gives up after the attempts it was given, resetting between them and not after the last', async () => { - const { result, events, made } = attempt(['times out', 'times out', 'times out']) - await expect(result).rejects.toThrow('x: tmux was still changing 8000ms after list; still unsettled after 3 recordings') - await expect(result).rejects.toBeInstanceOf(Error) - expect(made()).toBe(3) - expect(events.filter((event) => event === 'reset')).toHaveLength(2) - }) - - it('ends the run at once on any other error, without resetting', async () => { - const { result, events } = attempt(['settles'], { check: () => { throw new Error('x: step 2 returned an error') } }) - await expect(result).rejects.toThrow('step 2 returned an error') - expect(events).toEqual(['record 1']) - const failed = recordSettled({ attempts: 3, record: async () => { throw new Error('the server did not exit') }, reset: () => { throw new Error('must not reset') } }) - await expect(failed).rejects.toThrow('the server did not exit') - }) - - it('waits for an asynchronous reset before the next recording', async () => { - const order: string[] = [] - let tries = 0 - await recordSettled({ - attempts: 2, - record: async () => { order.push('record'); if (++tries === 1) throw unsettled(); return 'done' }, - reset: async () => { order.push('reset starts'); await new Promise((resolve) => setTimeout(resolve, 20)); order.push('reset ends') }, - }) - expect(order).toEqual(['record', 'reset starts', 'reset ends', 'record']) - }) }) diff --git a/site/test/mcp-transcript-checks.test.ts b/site/test/mcp-transcript-checks.test.ts index 024ab033a..5f98c655e 100644 --- a/site/test/mcp-transcript-checks.test.ts +++ b/site/test/mcp-transcript-checks.test.ts @@ -1,6 +1,4 @@ import { describe, expect, it } from 'vitest' -import { readdirSync, readFileSync } from 'node:fs' -import { hostname, userInfo } from 'node:os' import { hostLeaks, idsIn, leaks, readings, recordingLeaks, sanitize, UnsettledPaneError, verifyRecording, verifySettledPanes, withoutContracts } from '../../scripts/lib/mcp-transcript-checks.mjs' import type { TmuxState } from '../src/lib/mcp-tmux-state' @@ -163,14 +161,6 @@ describe('a pane described before its shell has started', () => { expect(() => verifyRecording(failed, { ...OPTIONS, commands: ['sh'] })).not.toThrow(UnsettledPaneError) }) - it('is satisfied by every committed recording', () => { - const dir = new URL('../src/data/mcp-transcripts/', import.meta.url) - for (const name of readdirSync(dir).filter((file) => file.endsWith('.json'))) { - const recorded = JSON.parse(readFileSync(new URL(name, dir), 'utf8')) as { steps: Step[] } - const commands = name === 'ruby.json' ? ['cat'] : ['sh'] - expect(() => verifySettledPanes(recorded.steps, { port: name, commands }), name).not.toThrow() - } - }) }) describe('keeping the host out of a recording', () => { @@ -242,43 +232,6 @@ describe('keeping the host out of a recording', () => { expect(sanitize(clean, marks), 'rewriting twice changes nothing').toEqual(clean) }) - it('finds a path, a user name or a machine name planted in the tmux state of every committed recording, and the rewrite removes it', () => { - const dir = new URL('../src/data/mcp-transcripts/', import.meta.url) - const places = ['/home/d', '/tmp/t239', '/var/folders'] - const names = ['d', 'tony-box'] - const plants: [string, string][] = [['a sandbox path', '/tmp/t239-x/project'], ['a home directory', '/home/d/work'], ['a machine name', 'tony-box'], ['a user name', 'd']] - for (const file of readdirSync(dir).filter((name) => name.endsWith('.json'))) { - const recorded = JSON.parse(readFileSync(new URL(file, dir), 'utf8')) as { tmuxBefore?: TmuxState; steps: { tmux?: TmuxState }[] } - const states = [recorded.tmuxBefore, ...recorded.steps.map((step) => step.tmux)].filter((state): state is TmuxState => Boolean(state?.windows.length)) - expect(states.length, `${file} carries a state with a window to plant in`).toBeGreaterThan(0) - expect(leaks(JSON.stringify(withoutContracts(recorded)), places, names), `${file} as recorded`).toEqual([]) - for (const [what, text] of plants) { - // The plant goes into a window name, which is the free text a state holds, in each state in turn. - for (const index of states.keys()) { - const planted = structuredClone(recorded) - const target = [planted.tmuxBefore, ...planted.steps.map((step) => step.tmux)].filter((candidate): candidate is TmuxState => Boolean(candidate?.windows.length))[index]! - target.windows[0]!.name = text - expect(leaks(JSON.stringify(withoutContracts(planted)), places, names), `${file}: ${what} in state ${index}`).not.toEqual([]) - const clean = sanitize(planted, { paths: [['/tmp/t239-x/project', '/home/user/project'], ['/home/d', '/home/user']], names }) - expect(leaks(JSON.stringify(withoutContracts(clean)), places, names), `${file}: ${what} in state ${index} after the rewrite`).toEqual([]) - } - } - } - }) - - it('has committed recordings that name neither this machine nor the sandbox, and that the rewrite leaves as they are', () => { - const dir = new URL('../src/data/mcp-transcripts/', import.meta.url) - const files = readdirSync(dir).filter((name) => name.endsWith('.json')) - expect(files.length).toBeGreaterThan(8) - // d is the name of the machine the recordings were made on; the others are whoever runs this. - const names = ['d', hostname(), userInfo().username].filter((name) => !['host', 'user'].includes(name)) - for (const name of files) { - const recorded = withoutContracts(JSON.parse(readFileSync(new URL(name, dir), 'utf8'))) - expect(leaks(JSON.stringify(recorded, null, 2), ['/home/d', '/tmp/t239', '/var/folders'], names), name).toEqual([]) - expect(recordingLeaks(recorded, { places: ['/home/d', '/tmp/t239', '/var/folders'], names, components: ['t239-'] }), `${name}: every parsed value`).toEqual([]) - expect(sanitize(recorded, { names }), `${name} is a fixed point of the rewrite`).toEqual(recorded) - } - }) }) describe('reading a text through the encodings a server or a tool may put on it', () => { @@ -307,121 +260,3 @@ describe('reading a text through the encodings a server or a tool may put on it' expect(readings('%'.repeat(5) + '25'.repeat(40)).length).toBeLessThan(100) }) }) - -describe('what a finished recording is scanned for before it is written', () => { - // The checkout is outside the home directory, so a piece of it is not already a place of its own. - const HOST = { sandbox: '/tmp/t239-ts-AbC123', home: '/home/d', checkout: '/srv/ports/libtmux-ts', listed: '4242:1700000000', user: 'd', machine: 'tony-box' } - const MARKS = { paths: [['/tmp/t239-ts-AbC123/project', '/home/user/project'], ['4242:1700000000', '3f9a1c']] as [string, string][], names: ['tony-box', 'd'] } - const dir = new URL('../src/data/mcp-transcripts/', import.meta.url) - const files = readdirSync(dir).filter((name) => name.endsWith('.json')) - type Recorded = { contracts?: unknown; tmuxBefore: TmuxState; steps: { tool: string; tmux: TmuxState; structuredContent?: any; content: { text?: string }[] }[]; sandbox: { rewritten?: unknown } } - const stateOf = (recorded: Recorded, index: number): TmuxState => (index === 0 ? recorded.tmuxBefore : recorded.steps[index - 1]!.tmux) - - /** What the recorder does with a finished session: the rewrite of every step and of the start, then the one call that scans the transcript. */ - const recorderPipeline = (recorded: Recorded) => { - const steps = recorded.steps.map((step) => sanitize(step, MARKS)) - const tmuxBefore = sanitize(recorded.tmuxBefore, MARKS) - return hostLeaks({ ...recorded, tmuxBefore, steps }, HOST) - } - - const escapedOnce = String.raw`\/tmp\/t239-ts-AbC123` - let thrice = escapedOnce - for (let layer = 0; layer < 2; layer++) thrice = JSON.stringify(thrice).slice(1, -1) - const PLANTS: [string, string][] = [ - ['an escaped sandbox root', escapedOnce], - ['a triple-escaped sandbox root', thrice], - ['a percent-encoded sandbox path', encodeURIComponent('/tmp/t239-ts-AbC123/project')], - ['a percent-encoded home directory', encodeURIComponent('/home/d/work')], - ['a percent-encoded checkout', encodeURIComponent('/srv/ports/libtmux-ts')], - ['an escaped, then percent-encoded, checkout', encodeURIComponent(String.raw`\/srv\/ports\/libtmux-ts`)], - ['the sandbox directory name alone', 't239-ts-AbC123'], - ['the sandbox directory name in a file name', 'run-t239-ts-AbC123.log'], - ['the sandbox root as JSON text with split fields', JSON.stringify({ dir: '/tmp', name: 't239-ts-AbC123' })], - ['the checkout as JSON text with split fields', JSON.stringify({ dir: '/srv/ports', name: 'libtmux-ts' })], - ['the checkout as JSON text inside JSON text', JSON.stringify({ outer: JSON.stringify({ dir: '/srv/ports/', name: 'libtmux-ts' }) })], - ['the sandbox root as JSON text, escaped once more', JSON.stringify(JSON.stringify({ path: '/tmp/t239-ts-AbC123' }))], - ['the process id and start time a Julia server lists, percent-encoded', encodeURIComponent('4242:1700000000')], - ['a machine name, percent-encoded', 'tony-%62ox'], - ['a user name as a unicode escape', String.raw`\u0064`], - ] - - it('passes every committed recording through the recorder\'s own pipeline with nothing named', () => { - for (const file of files) { - const recorded = JSON.parse(readFileSync(new URL(file, dir), 'utf8')) as Recorded - expect(recorderPipeline(recorded), file).toEqual([]) - } - }) - - it('finds each planted form in the window name of every state of every recording the pipeline is given', () => { - for (const file of files) { - const recorded = JSON.parse(readFileSync(new URL(file, dir), 'utf8')) as Recorded - // A window name is the free text a state holds; the first state with a window, a middle one and the last. - const withWindow = Array.from({ length: recorded.steps.length + 1 }, (_, index) => index).filter((index) => stateOf(recorded, index).windows.length > 0) - expect(withWindow.length, `${file} has states with a window to plant in`).toBeGreaterThan(1) - for (const [what, text] of PLANTS) { - for (const index of new Set([withWindow[0]!, withWindow[Math.floor(withWindow.length / 2)]!, withWindow.at(-1)!])) { - const planted = structuredClone(recorded) - stateOf(planted, index).windows[0]!.name = text - expect(recorderPipeline(planted), `${file}: ${what} in state ${index}`).not.toEqual([]) - } - } - } - }) - - it('finds a path split into the fields of an object or the entries of a list, in a result and in a request', () => { - const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded - const splits: [string, (planted: Recorded) => void][] = [ - ['a sandbox directory and name in a result', (planted) => { planted.steps[0]!.structuredContent.where = { dir: '/tmp', name: 't239-ts-AbC123' } }], - ['a checkout split into its directory and name', (planted) => { planted.steps[0]!.structuredContent.where = { cwd: '/srv/ports/', repo: 'libtmux-ts' } }], - ['a path as two neighbouring entries', (planted) => { planted.steps[0]!.structuredContent.argv = ['cd', '/srv/ports', 'libtmux-ts'] }], - ['an escaped path in a pane\'s output', (planted) => { planted.steps[0]!.content = [{ text: String.raw`{"cwd":"\\/tmp\\/t239-ts-AbC123\\/x"}` }] }], - ['a key', (planted) => { planted.steps[0]!.structuredContent[String.raw`\/tmp\/t239-ts-AbC123`] = true }], - ] - for (const [what, plant] of splits) { - const planted = structuredClone(recorded) - planted.steps[0]!.structuredContent ??= {} - plant(planted) - expect(recorderPipeline(planted), what).not.toEqual([]) - } - }) - - it('has controls: the paths a recording is allowed to hold, a path outside the host, and the token for a generation pass', () => { - const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded - const clean = (text: string) => { - const planted = structuredClone(recorded) - stateOf(planted, 1).windows[0]!.name = text - return recorderPipeline(planted) - } - for (const text of ['/home/user/project', String.raw`\/home\/user\/project`, encodeURIComponent('/home/user/project'), '3f9a1c', '100%', '50%25 done', String.raw`\d+`, JSON.stringify({ dir: '/home/user', name: 'project' }), 't239']) { - expect(clean(text), text).toEqual([]) - } - }) - - it('rewrites a path the sandbox project is under, with its slashes escaped or not, before the scan sees it', () => { - const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded - for (const text of ['/tmp/t239-ts-AbC123/project', String.raw`{"path":"\/tmp\/t239-ts-AbC123\/project"}`]) { - const planted = structuredClone(recorded) - planted.steps[0]!.content = [{ text }] - expect(recorderPipeline(planted), text).toEqual([]) - expect(JSON.stringify(sanitize(planted.steps[0], MARKS))).toContain('home') - } - }) - - it('says where it found each, and scans the serialized text as a second layer', () => { - const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded - const planted = structuredClone(recorded) - stateOf(planted, 2).windows[0]!.name = String.raw`\/tmp\/t239-ts-AbC123` - const found = hostLeaks(planted, HOST) - expect(found).toContain('/tmp/t239-ts-AbC123 ($.steps[1].tmux.windows[0].name)') - expect(found.some((item) => item.endsWith('(in the serialized text)'))).toBe(true) - // Reached only by the serialized text: a number's digits never form a string, but a key joined to a value does. - expect(leaks(JSON.stringify({ steps: [{ tmux: { windows: [{ name: String.raw`\/tmp\/t239-ts-AbC123` }] } }] }, null, 2), ['/tmp/t239-ts-AbC123'])).toEqual(['/tmp/t239-ts-AbC123']) - }) - - it('leaves the contracts out, and finds the host in everything else, as before', () => { - const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded - const withContract = structuredClone(recorded) - withContract.contracts = { kill_pane: { inputSchema: { properties: { pane: { pattern: String.raw`^%\d+$` } } } } } - expect(hostLeaks(withContract, HOST)).toEqual([]) - }) -}) diff --git a/site/test/mcp-transcript-corpus.outer.test.ts b/site/test/mcp-transcript-corpus.outer.test.ts new file mode 100644 index 000000000..964d18abb --- /dev/null +++ b/site/test/mcp-transcript-corpus.outer.test.ts @@ -0,0 +1,173 @@ +// Scans recorded source files and injected counterexamples across the complete corpus. +import { describe, expect, it } from 'vitest' +import { readdirSync, readFileSync } from 'node:fs' +import { hostname, userInfo } from 'node:os' +import { hostLeaks, leaks, recordingLeaks, sanitize, verifySettledPanes, withoutContracts } from '../../scripts/lib/mcp-transcript-checks.mjs' +import type { TmuxState } from '../src/lib/mcp-tmux-state' + +type Step = { tool: string; arguments: unknown; isError: boolean; content: unknown[]; structuredContent?: unknown } + +it('is satisfied by every committed recording', () => { + const dir = new URL('../src/data/mcp-transcripts/', import.meta.url) + for (const name of readdirSync(dir).filter((file) => file.endsWith('.json'))) { + const recorded = JSON.parse(readFileSync(new URL(name, dir), 'utf8')) as { steps: Step[] } + const commands = name === 'ruby.json' ? ['cat'] : ['sh'] + expect(() => verifySettledPanes(recorded.steps, { port: name, commands }), name).not.toThrow() + } + }) + +it('finds a path, a user name or a machine name planted in the tmux state of every committed recording, and the rewrite removes it', () => { + const dir = new URL('../src/data/mcp-transcripts/', import.meta.url) + const places = ['/home/d', '/tmp/t239', '/var/folders'] + const names = ['d', 'tony-box'] + const plants: [string, string][] = [['a sandbox path', '/tmp/t239-x/project'], ['a home directory', '/home/d/work'], ['a machine name', 'tony-box'], ['a user name', 'd']] + for (const file of readdirSync(dir).filter((name) => name.endsWith('.json'))) { + const recorded = JSON.parse(readFileSync(new URL(file, dir), 'utf8')) as { tmuxBefore?: TmuxState; steps: { tmux?: TmuxState }[] } + const states = [recorded.tmuxBefore, ...recorded.steps.map((step) => step.tmux)].filter((state): state is TmuxState => Boolean(state?.windows.length)) + expect(states.length, `${file} carries a state with a window to plant in`).toBeGreaterThan(0) + expect(leaks(JSON.stringify(withoutContracts(recorded)), places, names), `${file} as recorded`).toEqual([]) + for (const [what, text] of plants) { + // The plant goes into a window name, which is the free text a state holds, in each state in turn. + for (const index of states.keys()) { + const planted = structuredClone(recorded) + const target = [planted.tmuxBefore, ...planted.steps.map((step) => step.tmux)].filter((candidate): candidate is TmuxState => Boolean(candidate?.windows.length))[index]! + target.windows[0]!.name = text + expect(leaks(JSON.stringify(withoutContracts(planted)), places, names), `${file}: ${what} in state ${index}`).not.toEqual([]) + const clean = sanitize(planted, { paths: [['/tmp/t239-x/project', '/home/user/project'], ['/home/d', '/home/user']], names }) + expect(leaks(JSON.stringify(withoutContracts(clean)), places, names), `${file}: ${what} in state ${index} after the rewrite`).toEqual([]) + } + } + } + }) + +it('has committed recordings that name neither this machine nor the sandbox, and that the rewrite leaves as they are', () => { + const dir = new URL('../src/data/mcp-transcripts/', import.meta.url) + const files = readdirSync(dir).filter((name) => name.endsWith('.json')) + expect(files.length).toBeGreaterThan(8) + // d is the name of the machine the recordings were made on; the others are whoever runs this. + const names = ['d', hostname(), userInfo().username].filter((name) => !['host', 'user'].includes(name)) + for (const name of files) { + const recorded = withoutContracts(JSON.parse(readFileSync(new URL(name, dir), 'utf8'))) + expect(leaks(JSON.stringify(recorded, null, 2), ['/home/d', '/tmp/t239', '/var/folders'], names), name).toEqual([]) + expect(recordingLeaks(recorded, { places: ['/home/d', '/tmp/t239', '/var/folders'], names, components: ['t239-'] }), `${name}: every parsed value`).toEqual([]) + expect(sanitize(recorded, { names }), `${name} is a fixed point of the rewrite`).toEqual(recorded) + } + }) + +describe('what a finished recording is scanned for before it is written', () => { + // The checkout is outside the home directory, so a piece of it is not already a place of its own. + const HOST = { sandbox: '/tmp/t239-ts-AbC123', home: '/home/d', checkout: '/srv/ports/libtmux-ts', listed: '4242:1700000000', user: 'd', machine: 'tony-box' } + const MARKS = { paths: [['/tmp/t239-ts-AbC123/project', '/home/user/project'], ['4242:1700000000', '3f9a1c']] as [string, string][], names: ['tony-box', 'd'] } + const dir = new URL('../src/data/mcp-transcripts/', import.meta.url) + const files = readdirSync(dir).filter((name) => name.endsWith('.json')) + type Recorded = { contracts?: unknown; tmuxBefore: TmuxState; steps: { tool: string; tmux: TmuxState; structuredContent?: any; content: { text?: string }[] }[]; sandbox: { rewritten?: unknown } } + const stateOf = (recorded: Recorded, index: number): TmuxState => (index === 0 ? recorded.tmuxBefore : recorded.steps[index - 1]!.tmux) + + /** What the recorder does with a finished session: the rewrite of every step and of the start, then the one call that scans the transcript. */ + const recorderPipeline = (recorded: Recorded) => { + const steps = recorded.steps.map((step) => sanitize(step, MARKS)) + const tmuxBefore = sanitize(recorded.tmuxBefore, MARKS) + return hostLeaks({ ...recorded, tmuxBefore, steps }, HOST) + } + + const escapedOnce = String.raw`\/tmp\/t239-ts-AbC123` + let thrice = escapedOnce + for (let layer = 0; layer < 2; layer++) thrice = JSON.stringify(thrice).slice(1, -1) + const PLANTS: [string, string][] = [ + ['an escaped sandbox root', escapedOnce], + ['a triple-escaped sandbox root', thrice], + ['a percent-encoded sandbox path', encodeURIComponent('/tmp/t239-ts-AbC123/project')], + ['a percent-encoded home directory', encodeURIComponent('/home/d/work')], + ['a percent-encoded checkout', encodeURIComponent('/srv/ports/libtmux-ts')], + ['an escaped, then percent-encoded, checkout', encodeURIComponent(String.raw`\/srv\/ports\/libtmux-ts`)], + ['the sandbox directory name alone', 't239-ts-AbC123'], + ['the sandbox directory name in a file name', 'run-t239-ts-AbC123.log'], + ['the sandbox root as JSON text with split fields', JSON.stringify({ dir: '/tmp', name: 't239-ts-AbC123' })], + ['the checkout as JSON text with split fields', JSON.stringify({ dir: '/srv/ports', name: 'libtmux-ts' })], + ['the checkout as JSON text inside JSON text', JSON.stringify({ outer: JSON.stringify({ dir: '/srv/ports/', name: 'libtmux-ts' }) })], + ['the sandbox root as JSON text, escaped once more', JSON.stringify(JSON.stringify({ path: '/tmp/t239-ts-AbC123' }))], + ['the process id and start time a Julia server lists, percent-encoded', encodeURIComponent('4242:1700000000')], + ['a machine name, percent-encoded', 'tony-%62ox'], + ['a user name as a unicode escape', String.raw`\u0064`], + ] + + it('passes every committed recording through the recorder\'s own pipeline with nothing named', () => { + for (const file of files) { + const recorded = JSON.parse(readFileSync(new URL(file, dir), 'utf8')) as Recorded + expect(recorderPipeline(recorded), file).toEqual([]) + } + }) + + it('finds each planted form in the window name of every state of every recording the pipeline is given', () => { + for (const file of files) { + const recorded = JSON.parse(readFileSync(new URL(file, dir), 'utf8')) as Recorded + // A window name is the free text a state holds; the first state with a window, a middle one and the last. + const withWindow = Array.from({ length: recorded.steps.length + 1 }, (_, index) => index).filter((index) => stateOf(recorded, index).windows.length > 0) + expect(withWindow.length, `${file} has states with a window to plant in`).toBeGreaterThan(1) + for (const [what, text] of PLANTS) { + for (const index of new Set([withWindow[0]!, withWindow[Math.floor(withWindow.length / 2)]!, withWindow.at(-1)!])) { + const planted = structuredClone(recorded) + stateOf(planted, index).windows[0]!.name = text + expect(recorderPipeline(planted), `${file}: ${what} in state ${index}`).not.toEqual([]) + } + } + } + }) + + it('finds a path split into the fields of an object or the entries of a list, in a result and in a request', () => { + const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded + const splits: [string, (planted: Recorded) => void][] = [ + ['a sandbox directory and name in a result', (planted) => { planted.steps[0]!.structuredContent.where = { dir: '/tmp', name: 't239-ts-AbC123' } }], + ['a checkout split into its directory and name', (planted) => { planted.steps[0]!.structuredContent.where = { cwd: '/srv/ports/', repo: 'libtmux-ts' } }], + ['a path as two neighbouring entries', (planted) => { planted.steps[0]!.structuredContent.argv = ['cd', '/srv/ports', 'libtmux-ts'] }], + ['an escaped path in a pane\'s output', (planted) => { planted.steps[0]!.content = [{ text: String.raw`{"cwd":"\\/tmp\\/t239-ts-AbC123\\/x"}` }] }], + ['a key', (planted) => { planted.steps[0]!.structuredContent[String.raw`\/tmp\/t239-ts-AbC123`] = true }], + ] + for (const [what, plant] of splits) { + const planted = structuredClone(recorded) + planted.steps[0]!.structuredContent ??= {} + plant(planted) + expect(recorderPipeline(planted), what).not.toEqual([]) + } + }) + + it('has controls: the paths a recording is allowed to hold, a path outside the host, and the token for a generation pass', () => { + const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded + const clean = (text: string) => { + const planted = structuredClone(recorded) + stateOf(planted, 1).windows[0]!.name = text + return recorderPipeline(planted) + } + for (const text of ['/home/user/project', String.raw`\/home\/user\/project`, encodeURIComponent('/home/user/project'), '3f9a1c', '100%', '50%25 done', String.raw`\d+`, JSON.stringify({ dir: '/home/user', name: 'project' }), 't239']) { + expect(clean(text), text).toEqual([]) + } + }) + + it('rewrites a path the sandbox project is under, with its slashes escaped or not, before the scan sees it', () => { + const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded + for (const text of ['/tmp/t239-ts-AbC123/project', String.raw`{"path":"\/tmp\/t239-ts-AbC123\/project"}`]) { + const planted = structuredClone(recorded) + planted.steps[0]!.content = [{ text }] + expect(recorderPipeline(planted), text).toEqual([]) + expect(JSON.stringify(sanitize(planted.steps[0], MARKS))).toContain('home') + } + }) + + it('says where it found each, and scans the serialized text as a second layer', () => { + const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded + const planted = structuredClone(recorded) + stateOf(planted, 2).windows[0]!.name = String.raw`\/tmp\/t239-ts-AbC123` + const found = hostLeaks(planted, HOST) + expect(found).toContain('/tmp/t239-ts-AbC123 ($.steps[1].tmux.windows[0].name)') + expect(found.some((item) => item.endsWith('(in the serialized text)'))).toBe(true) + // Reached only by the serialized text: a number's digits never form a string, but a key joined to a value does. + expect(leaks(JSON.stringify({ steps: [{ tmux: { windows: [{ name: String.raw`\/tmp\/t239-ts-AbC123` }] } }] }, null, 2), ['/tmp/t239-ts-AbC123'])).toEqual(['/tmp/t239-ts-AbC123']) + }) + + it('leaves the contracts out, and finds the host in everything else, as before', () => { + const recorded = JSON.parse(readFileSync(new URL('ts.json', dir), 'utf8')) as Recorded + const withContract = structuredClone(recorded) + withContract.contracts = { kill_pane: { inputSchema: { properties: { pane: { pattern: String.raw`^%\d+$` } } } } } + expect(hostLeaks(withContract, HOST)).toEqual([]) + }) +}) diff --git a/site/test/native-name.test.ts b/site/test/native-name.test.ts index de5e9b2cd..8cabbb706 100644 --- a/site/test/native-name.test.ts +++ b/site/test/native-name.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model' +import { qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { symbolPreview } from '../src/lib/link-preview' import { nativePackageName, nativeQualifiedName, nativeShortName } from '../src/lib/native-name' @@ -197,7 +197,7 @@ describe('short names', () => { }) it('are the owner, a separator that the language writes, and the member, for every symbol of every port', { timeout: 30_000 }, () => { - const separators: Record = { rs: ['::'], cxx: ['::'], ruby: ['::', '.', '#'], lua: ['.', ':'], powershell: ['\\'] } + const separators: Record = { perl: ['::'], rs: ['::'], cxx: ['::'], ruby: ['::', '.', '#'], lua: ['.', ':'], powershell: ['\\'] } for (const [port, model] of Object.entries(API_MODELS)) { const owners = new Map(model.symbols.map((symbol) => [symbol.id, symbol])) for (const symbol of model.symbols) { diff --git a/site/test/native-prose-ownership.test.ts b/site/test/native-prose-ownership.test.ts index c7cbd4211..227f033ad 100644 --- a/site/test/native-prose-ownership.test.ts +++ b/site/test/native-prose-ownership.test.ts @@ -6,7 +6,7 @@ import { fileURLToPath } from 'node:url' import { createMarkdownProcessor, parseFrontmatter } from '@astrojs/markdown-remark' import { fromMarkdown } from 'mdast-util-from-markdown' import { visit } from 'unist-util-visit' -import { SymbolIndex } from '@libtmux/api-model' +import { SymbolIndex } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { getResolver } from '../src/lib/prose-resolver' import { llmsPage } from '../src/lib/llms' diff --git a/site/test/native-shell-context.outer.test.ts b/site/test/native-shell-context.outer.test.ts new file mode 100644 index 000000000..cb17ddd1f --- /dev/null +++ b/site/test/native-shell-context.outer.test.ts @@ -0,0 +1,116 @@ +// Outer: collect source-bound native articles from owned Git repositories. +import { execFileSync } from 'node:child_process' +import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, describe, expect, it } from 'vitest' +import { collectNativeContext, nativeHash } from '../../scripts/native-shell-context.mjs' + +const directories: string[] = [] +afterEach(() => directories.splice(0).forEach((directory) => rmSync(directory, { recursive: true, force: true }))) + +function fixture() { + const directory = mkdtempSync(join(tmpdir(), 'native-context-')) + directories.push(directory) + const checkout = join(directory, 'source'), artifact = join(directory, 'artifact') + mkdirSync(join(checkout, 'docs/api'), { recursive: true }) + mkdirSync(join(artifact, 'api/libtmux.server'), { recursive: true }) + mkdirSync(join(artifact, 'genindex'), { recursive: true }) + const source = '# Server\n\nNative source.\n' + writeFileSync(join(checkout, 'docs/api/libtmux.server.md'), source) + const git = (...args: string[]) => execFileSync('git', ['-C', checkout, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim() + git('init') + git('add', '.') + git('-c', 'user.name=Test', '-c', 'user.email=test@example.invalid', '-c', 'commit.gpgsign=false', 'commit', '-m', 'Native source fixture') + const sourceSha = git('rev-parse', 'HEAD') + const article = '

Server

Server
\n
  exact & bytes\n
' + const html = `Server
${article}
docs/api/libtmux.server.md
` + writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html) + writeFileSync(join(artifact, 'api/libtmux.server.md'), source) + writeFileSync(join(artifact, 'genindex/index.html'), '
Generated index
') + writeFileSync(join(artifact, 'docs.json'), JSON.stringify({ pages: [{ url: '/api/libtmux.server/', markdownUrl: '/api/libtmux.server.md' }] })) + const options = { prefix: '/pr-42/en', sphinxPort: 'py', version: 'v0.62.0', checkout, sourceSha } + return { artifact, checkout, options, article, html, source, sourceSha } +} + +describe('native shell source collection', () => { + it('recognizes Sphinx properties inside their class', async () => { + const { artifact, options, html } = fixture() + const declarations = '
Server
sessions
' + writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html.replace(/
/, declarations)) + const context = await collectNativeContext(artifact, options) + expect(context.pages.find((page) => page.file === 'api/libtmux.server/index.html')?.declarations).toContainEqual({ + id: 'libtmux.Server.sessions', name: 'sessions', kind: 'property', parent: 'libtmux.Server', + }) + }) + it('records the kind of the declaration each cross-reference points at, not the role it was written with', async () => { + const { artifact, options, html } = fixture() + const xref = (role: string, href: string, label: string) => `${label}` + const declarations = '
Server
sessions
' + + '
LibTmuxException
' + + `

${xref('py-attr', '#libtmux.Server.sessions', 'sessions')} ${xref('py-class', '#libtmux.exc.LibTmuxException', 'LibTmuxException')} ${xref('py-mod', '#module-libtmux.server', 'libtmux.server')}` + + ` ${xref('py-class', '#libtmux.nonesuch', 'nonesuch')} no code external

` + writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html.replace(/
/, declarations)) + const context = await collectNativeContext(artifact, options) + expect(context.pages.find((page) => page.file === 'api/libtmux.server/index.html')?.xrefKinds).toEqual({ + 'libtmux.Server.sessions': 'property', 'libtmux.exc.LibTmuxException': 'exception', 'module-libtmux.server': 'module', + }) + expect(context.pages.find((page) => page.file === 'genindex/index.html')?.xrefKinds).toEqual({}) + }) + it('binds real source, exact Markdown and native article bytes, without inventing generated-index targets', async () => { + const { artifact, options, article, source, sourceSha } = fixture() + const context = await collectNativeContext(artifact, options) + const server = context.pages.find((page: { file: string }) => page.file === 'api/libtmux.server/index.html')! + expect(server.url).toBe('/pr-42/en/py/v0.62.0/api/api/libtmux.server/') + expect(server.sourcePath).toBe('py/v0.62.0/api/api/libtmux.server/') + expect(server.markdownHref).toBe('/pr-42/en/py/v0.62.0/api/api/libtmux.server.md') + expect(server.source).toEqual({ repo: 'tmux-python/libtmux', ref: sourceSha, path: 'docs/api/libtmux.server.md', sha256: nativeHash(source) }) + expect(server.articleSha256).toBe(nativeHash(article)) + expect(server.signatures).toEqual(['libtmux.Server']) + expect(server.hasTableOfContents).toBe(false) + const index = context.pages.find((page: { file: string }) => page.file === 'genindex/index.html')! + expect(index.source).toBeUndefined() + expect(index.markdownHref).toBeUndefined() + expect(await collectNativeContext(artifact, options)).toEqual(context) + }) + it('binds the global toctree once, on published URLs, and rejects pages that disagree', async () => { + const { artifact, options, html } = fixture() + const context = await collectNativeContext(artifact, options) + expect(context.toctree).toEqual([{ title: 'Server', url: '/pr-42/en/py/v0.62.0/api/api/libtmux.server/', children: [] }]) + writeFileSync(join(artifact, 'genindex/index.html'), html.replace('docs/api/libtmux.server.md', '').replace('>Server', '>Other')) + await expect(collectNativeContext(artifact, options)).rejects.toThrow('global toctree differs') + writeFileSync(join(artifact, 'genindex/index.html'), '
Generated index
') + await expect(collectNativeContext(artifact, options)).rejects.toThrow('no global toctree') + }) + it('offers contents only for real destinations beyond the page title', async () => { + const { artifact, options, html } = fixture() + const page = join(artifact, 'api/libtmux.server/index.html') + const writeToc = (links: string) => writeFileSync(page, html.replace('', ``)) + writeToc('ServerMissingInvalid') + expect((await collectNativeContext(artifact, options)).pages[0].hasTableOfContents).toBe(false) + writeToc('Server declaration') + expect((await collectNativeContext(artifact, options)).pages[0].hasTableOfContents).toBe(true) + }) + it('rejects a different revision or uncommitted source instead of citing it as the selected revision', async () => { + const { artifact, options, checkout } = fixture() + await expect(collectNativeContext(artifact, { ...options, sourceSha: '0'.repeat(40) })).rejects.toThrow('revision mismatch') + writeFileSync(join(checkout, 'docs/api/libtmux.server.md'), 'Changed source') + await expect(collectNativeContext(artifact, options)).rejects.toThrow('tracked changes') + }) + it('fails when metadata or the exact Markdown target is absent', async () => { + const { artifact, options, html } = fixture() + writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html.replace('docs/api/libtmux.server.md', '')) + await expect(collectNativeContext(artifact, options)).rejects.toThrow('no valid source path') + writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html) + rmSync(join(artifact, 'api/libtmux.server.md')) + await expect(collectNativeContext(artifact, options)).rejects.toThrow('Markdown is missing') + }) + it('rejects unknown generated routes and traversing paths in the native export inventory', async () => { + const { artifact, options } = fixture() + const metadata = JSON.parse(readFileSync(join(artifact, 'docs.json'), 'utf8')) + writeFileSync(join(artifact, 'docs.json'), JSON.stringify({ pages: [{ ...metadata.pages[0], url: '/../outside/' }] })) + await expect(collectNativeContext(artifact, options)).rejects.toThrow('not a local absolute path') + writeFileSync(join(artifact, 'docs.json'), JSON.stringify({ pages: [] })) + await expect(collectNativeContext(artifact, options)).rejects.toThrow('no docs.json entry') + }) +}) diff --git a/site/test/native-shell-context.test.ts b/site/test/native-shell-context.test.ts index a5be4051b..9c205a5c7 100644 --- a/site/test/native-shell-context.test.ts +++ b/site/test/native-shell-context.test.ts @@ -1,63 +1,8 @@ -import { execFileSync } from 'node:child_process' -import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, describe, expect, it } from 'vitest' -import { collectNativeContext, nativeHash } from '../../scripts/native-shell-context.mjs' +import { describe, expect, it } from 'vitest' import { nativeReferenceTree, type NativeShellContext } from '../src/lib/native-shell' import { searchApi, apiTreeHref } from '../src/lib/api-search' -const directories: string[] = [] -afterEach(() => directories.splice(0).forEach((directory) => rmSync(directory, { recursive: true, force: true }))) - -function fixture() { - const directory = mkdtempSync(join(tmpdir(), 'native-context-')) - directories.push(directory) - const checkout = join(directory, 'source'), artifact = join(directory, 'artifact') - mkdirSync(join(checkout, 'docs/api'), { recursive: true }) - mkdirSync(join(artifact, 'api/libtmux.server'), { recursive: true }) - mkdirSync(join(artifact, 'genindex'), { recursive: true }) - const source = '# Server\n\nNative source.\n' - writeFileSync(join(checkout, 'docs/api/libtmux.server.md'), source) - const git = (...args: string[]) => execFileSync('git', ['-C', checkout, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim() - git('init') - git('add', '.') - git('-c', 'user.name=Test', '-c', 'user.email=test@example.invalid', '-c', 'commit.gpgsign=false', 'commit', '-m', 'Native source fixture') - const sourceSha = git('rev-parse', 'HEAD') - const article = '

Server

Server
\n
  exact & bytes\n
' - const html = `Server
${article}
docs/api/libtmux.server.md
` - writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html) - writeFileSync(join(artifact, 'api/libtmux.server.md'), source) - writeFileSync(join(artifact, 'genindex/index.html'), '
Generated index
') - writeFileSync(join(artifact, 'docs.json'), JSON.stringify({ pages: [{ url: '/api/libtmux.server/', markdownUrl: '/api/libtmux.server.md' }] })) - const options = { prefix: '/pr-42/en', sphinxPort: 'py', version: 'v0.62.0', checkout, sourceSha } - return { artifact, checkout, options, article, html, source, sourceSha } -} - describe('native shell context', () => { - it('recognizes Sphinx properties inside their class', async () => { - const { artifact, options, html } = fixture() - const declarations = '
Server
sessions
' - writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html.replace(/
/, declarations)) - const context = await collectNativeContext(artifact, options) - expect(context.pages.find((page) => page.file === 'api/libtmux.server/index.html')?.declarations).toContainEqual({ - id: 'libtmux.Server.sessions', name: 'sessions', kind: 'property', parent: 'libtmux.Server', - }) - }) - it('records the kind of the declaration each cross-reference points at, not the role it was written with', async () => { - const { artifact, options, html } = fixture() - const xref = (role: string, href: string, label: string) => `${label}` - const declarations = '
Server
sessions
' - + '
LibTmuxException
' - + `

${xref('py-attr', '#libtmux.Server.sessions', 'sessions')} ${xref('py-class', '#libtmux.exc.LibTmuxException', 'LibTmuxException')} ${xref('py-mod', '#module-libtmux.server', 'libtmux.server')}` - + ` ${xref('py-class', '#libtmux.nonesuch', 'nonesuch')} no code external

` - writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html.replace(/
/, declarations)) - const context = await collectNativeContext(artifact, options) - expect(context.pages.find((page) => page.file === 'api/libtmux.server/index.html')?.xrefKinds).toEqual({ - 'libtmux.Server.sessions': 'property', 'libtmux.exc.LibTmuxException': 'exception', 'module-libtmux.server': 'module', - }) - expect(context.pages.find((page) => page.file === 'genindex/index.html')?.xrefKinds).toEqual({}) - }) it('keeps repeated native declarations on their own pages with nested ownership', () => { const context = { port: 'py', pages: ['api/server/', 'internals/server/'].map((path) => ({ path, title: 'Server', url: `/pr-42/en/py/v0.46.2/api/${path}`, declarations: [ @@ -82,65 +27,4 @@ describe('native shell context', () => { } expect(records.find((record) => record.kind === 'section' && record.name === 'Client')?.qualifiedName).toBe('api/libtmux.client') }) - it('binds real source, exact Markdown and native article bytes, without inventing generated-index targets', async () => { - const { artifact, options, article, source, sourceSha } = fixture() - const context = await collectNativeContext(artifact, options) - const server = context.pages.find((page: { file: string }) => page.file === 'api/libtmux.server/index.html')! - expect(server.url).toBe('/pr-42/en/py/v0.62.0/api/api/libtmux.server/') - expect(server.sourcePath).toBe('py/v0.62.0/api/api/libtmux.server/') - expect(server.markdownHref).toBe('/pr-42/en/py/v0.62.0/api/api/libtmux.server.md') - expect(server.source).toEqual({ repo: 'tmux-python/libtmux', ref: sourceSha, path: 'docs/api/libtmux.server.md', sha256: nativeHash(source) }) - expect(server.articleSha256).toBe(nativeHash(article)) - expect(server.signatures).toEqual(['libtmux.Server']) - expect(server.hasTableOfContents).toBe(false) - const index = context.pages.find((page: { file: string }) => page.file === 'genindex/index.html')! - expect(index.source).toBeUndefined() - expect(index.markdownHref).toBeUndefined() - expect(await collectNativeContext(artifact, options)).toEqual(context) - }) - - it('binds the global toctree once, on published URLs, and rejects pages that disagree', async () => { - const { artifact, options, html } = fixture() - const context = await collectNativeContext(artifact, options) - expect(context.toctree).toEqual([{ title: 'Server', url: '/pr-42/en/py/v0.62.0/api/api/libtmux.server/', children: [] }]) - writeFileSync(join(artifact, 'genindex/index.html'), html.replace('docs/api/libtmux.server.md', '').replace('>Server', '>Other')) - await expect(collectNativeContext(artifact, options)).rejects.toThrow('global toctree differs') - writeFileSync(join(artifact, 'genindex/index.html'), '
Generated index
') - await expect(collectNativeContext(artifact, options)).rejects.toThrow('no global toctree') - }) - - it('offers contents only for real destinations beyond the page title', async () => { - const { artifact, options, html } = fixture() - const page = join(artifact, 'api/libtmux.server/index.html') - const writeToc = (links: string) => writeFileSync(page, html.replace('', ``)) - writeToc('ServerMissingInvalid') - expect((await collectNativeContext(artifact, options)).pages[0].hasTableOfContents).toBe(false) - writeToc('Server declaration') - expect((await collectNativeContext(artifact, options)).pages[0].hasTableOfContents).toBe(true) - }) - - it('rejects a different revision or uncommitted source instead of citing it as the selected revision', async () => { - const { artifact, options, checkout } = fixture() - await expect(collectNativeContext(artifact, { ...options, sourceSha: '0'.repeat(40) })).rejects.toThrow('revision mismatch') - writeFileSync(join(checkout, 'docs/api/libtmux.server.md'), 'Changed source') - await expect(collectNativeContext(artifact, options)).rejects.toThrow('tracked changes') - }) - - it('fails when metadata or the exact Markdown target is absent', async () => { - const { artifact, options, html } = fixture() - writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html.replace('docs/api/libtmux.server.md', '')) - await expect(collectNativeContext(artifact, options)).rejects.toThrow('no valid source path') - writeFileSync(join(artifact, 'api/libtmux.server/index.html'), html) - rmSync(join(artifact, 'api/libtmux.server.md')) - await expect(collectNativeContext(artifact, options)).rejects.toThrow('Markdown is missing') - }) - - it('rejects unknown generated routes and traversing paths in the native export inventory', async () => { - const { artifact, options } = fixture() - const metadata = JSON.parse(readFileSync(join(artifact, 'docs.json'), 'utf8')) - writeFileSync(join(artifact, 'docs.json'), JSON.stringify({ pages: [{ ...metadata.pages[0], url: '/../outside/' }] })) - await expect(collectNativeContext(artifact, options)).rejects.toThrow('not a local absolute path') - writeFileSync(join(artifact, 'docs.json'), JSON.stringify({ pages: [] })) - await expect(collectNativeContext(artifact, options)).rejects.toThrow('no docs.json entry') - }) }) diff --git a/site/test/native-signature.test.ts b/site/test/native-signature.test.ts index cc6cdc15a..118c1c559 100644 --- a/site/test/native-signature.test.ts +++ b/site/test/native-signature.test.ts @@ -7,7 +7,7 @@ import { runInNewContext } from 'node:vm' import { describe, expect, it } from 'vitest' import { experimental_AstroContainer } from 'astro/container' import { Window, type Element, type HTMLElement } from 'happy-dom' -import { parameterId, parentInventory, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model' +import { parameterId, parentInventory, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model/reference' import { apiEntryFields, nativeSignatureText, usesNativeSignatures } from '../src/lib/api-sections' import { API_MODEL_PORTS } from '../src/lib/ports' import { extractSourceWithSpec } from '../../packages/api-model/src/languages/spec' @@ -59,6 +59,7 @@ function displayedSignature(element: Element): string { } const cases = [ + ['perl', 'LibTmux::Server::capture_pane'], ['ts', 'server.Server.setHook'], ['ts', 'selection.Selection.filter'], ['ts', 'selection.Selection.[Symbol.iterator]'], @@ -625,7 +626,7 @@ describe('native signature emission', () => { const before = JSON.stringify(models.julia) const { entries } = await signatureProbe(models) expect([...new Set(entries.map(({ port }) => port))]).toEqual(API_MODEL_PORTS.map(({ slug }) => slug)) - expect(new Set(entries.map(({ port }) => port)).size).toBe(16) + expect(new Set(entries.map(({ port }) => port)).size).toBe(API_MODEL_PORTS.length) for (const [port, model] of Object.entries(models)) { const callables = model.symbols.filter((symbol) => symbol.signatures.some((signature) => signature.params.length > 0 && signature.returns)) const selected = callables.find((symbol) => /capture/i.test(symbol.name)) ?? callables[0] diff --git a/site/test/page-transitions.outer.test.ts b/site/test/page-transitions.outer.test.ts new file mode 100644 index 000000000..e0450236f --- /dev/null +++ b/site/test/page-transitions.outer.test.ts @@ -0,0 +1,25 @@ +import { readFileSync } from 'node:fs' +import { afterEach, expect, it, vi } from 'vitest' +import { loadHeaderTemplates, renderPage } from './header-page' + +// Compiles and renders the real shell; source-only assertions remain in the unit suite. +afterEach(() => vi.unstubAllEnvs()) + +it('renders the router meta tags in the head of the base layout', async () => { + const { baseLayout } = await loadHeaderTemplates() + const html = await renderPage(baseLayout, 'https://libtmux.org/en/ts/latest/guides/panes/', { pagePath: 'guides/panes', portSlug: 'ts' }) + const head = /([\s\S]*?)<\/head>/.exec(html)![1]! + expect(head).toContain(' { + const header = readFileSync(new URL('../src/components/SiteHeader.astro', import.meta.url), 'utf8') + const panel = header.indexOf('id="site-header-panel"') + expect(panel).toBeGreaterThan(header.indexOf('site-header__menu-button')) + expect(panel).toBeGreaterThan(header.indexOf('site-header__always')) + const { baseLayout } = await loadHeaderTemplates() + const html = await renderPage(baseLayout, 'https://libtmux.org/en/ts/latest/guides/panes/', { pagePath: 'guides/panes', portSlug: 'ts' }) + expect(/([\s\S]*?)<\/head>/.exec(html)![1]).toContain('') + expect(html).toContain('id="site-header-panel"') +}) diff --git a/site/test/page-transitions.test.ts b/site/test/page-transitions.test.ts index 7d7f89d93..b8753d0d8 100644 --- a/site/test/page-transitions.test.ts +++ b/site/test/page-transitions.test.ts @@ -1,7 +1,6 @@ import { closeSync, openSync, readFileSync, readSync, readdirSync, statSync } from 'node:fs' import { join } from 'node:path' -import { beforeAll, describe, expect, it, vi } from 'vitest' -import { loadHeaderTemplates, renderPage } from './header-page' +import { beforeAll, describe, expect, it } from 'vitest' import { SITE_BUILT, SITE_ROOT } from './site-root' const read = (path: string) => readFileSync(new URL(path, import.meta.url), 'utf8') @@ -21,31 +20,10 @@ describe('shell sources', () => { expect(/([\s\S]*?)<\/head>/.exec(layout)![1]).toContain('') }) - it('renders the router meta tags in the head of the base layout', async () => { - const { baseLayout } = await loadHeaderTemplates() - const html = await renderPage(baseLayout, 'https://libtmux.org/en/ts/latest/guides/panes/', { pagePath: 'guides/panes', portSlug: 'ts' }) - const head = /([\s\S]*?)<\/head>/.exec(html)![1]! - expect(head).toContain(' { expect(read('../src/components/docs/DocumentationScript.astro')).toMatch(/guardTreeNavigation\(\)/) }) - it('holds the first frame until the header bar is parsed', async () => { - const header = read('../src/components/SiteHeader.astro') - const panel = header.indexOf('id="site-header-panel"') - expect(panel).toBeGreaterThan(header.indexOf('site-header__menu-button')) - expect(panel).toBeGreaterThan(header.indexOf('site-header__always')) - const { baseLayout } = await loadHeaderTemplates() - const html = await renderPage(baseLayout, 'https://libtmux.org/en/ts/latest/guides/panes/', { pagePath: 'guides/panes', portSlug: 'ts' }) - expect(/([\s\S]*?)<\/head>/.exec(html)![1]).toContain('') - expect(html).toContain('id="site-header-panel"') - vi.unstubAllEnvs() - }) - it('guards navigation within a page before the router listens for history', () => { const head = /([\s\S]*?)<\/head>/.exec(read('../src/layouts/BaseLayout.astro'))![1]! const guard = head.indexOf('guardPageNavigation()') diff --git a/site/test/parameter-permalinks.test.ts b/site/test/parameter-permalinks.test.ts index 625f81a8d..ca0578b36 100644 --- a/site/test/parameter-permalinks.test.ts +++ b/site/test/parameter-permalinks.test.ts @@ -4,7 +4,7 @@ import { pathToFileURL } from 'node:url' import { experimental_AstroContainer } from 'astro/container' import { Window, type Element } from 'happy-dom' import { afterEach, expect, it, vi } from 'vitest' -import { parameterId, SymbolIndex, type ApiSymbol, type Param } from '@libtmux/api-model' +import { parameterId, SymbolIndex, type ApiSymbol, type Param } from '@libtmux/api-model/reference' import { apiEntryFields, parameterBindingFacts, POWER_SHELL_COMMON_HELP, POWER_SHELL_COMMON_HELP_TITLE, powerShellCommonParameterHref, powerShellCommonParameterLabel } from '../src/lib/api-sections' import { linkTmuxDoc } from '../src/lib/tmux-links' import { signatureSpans, typeLayout } from '../src/lib/code-layout' @@ -53,7 +53,7 @@ async function parameterComponents() { expect(start).toBeGreaterThan(0) expect(end).toBeGreaterThan(start) const wrapper = `--- -import { parameterId } from '@libtmux/api-model' +import { parameterId } from '@libtmux/api-model/reference' import ApiType from './ApiType.astro' import ApiDoc from './ApiDoc.astro' import ApiFieldOverloads from './ApiFieldOverloads.astro' diff --git a/site/test/perl-pod-links.test.ts b/site/test/perl-pod-links.test.ts new file mode 100644 index 000000000..c027a331b --- /dev/null +++ b/site/test/perl-pod-links.test.ts @@ -0,0 +1,30 @@ +import { describe, expect, it } from 'vitest' +import { pageIdentity, judgeLabel } from '../../scripts/lib/api-identities.mjs' +import { languageProblem } from '../../scripts/lib/api-links.mjs' +import { apiHostOf } from '../../scripts/lib/api-destinations.mjs' +import { readPage } from '../../scripts/lib/api-html.mjs' + +describe('native Perl POD destinations', () => { + it.each([ + ['https://metacpan.org/pod/Future', 'Future'], + ['https://metacpan.org/pod/IO::Async::Loop', 'IO::Async::Loop'], + ['https://perldoc.perl.org/5.44.0/JSON::PP', 'JSON::PP'], + ])('reads %s from its NAME declaration', (url, module) => { + const page = readPage(`Perl documentation

#NAME

${module} - module description

`) + const identity = pageIdentity(url, page) + expect(apiHostOf(url)).toBe(new URL(url).hostname) + expect(languageProblem('perl', url)).toBeUndefined() + expect(identity).toMatchObject({ via: 'pod', kind: 'module', path: module.split('::') }) + expect(judgeLabel(module, identity)).toBeUndefined() + expect(judgeLabel('Wrong::Module', identity)).toMatchObject({ failure: 'label' }) + }) + + it('rejects a search or challenge page and never infers identity from its URL', () => { + const url = 'https://metacpan.org/pod/Future' + expect(pageIdentity(url, readPage('Client Challenge

Client Challenge

'))) + .toMatchObject({ kind: 'other', path: [] }) + const wrong = pageIdentity(url, readPage('

NAME

IO::Async - framework

')) + expect(judgeLabel('Future', wrong)).toMatchObject({ failure: 'label' }) + expect(languageProblem('perl', 'https://docs.python.org/3/library/asyncio.html')).toMatchObject({ failure: 'language' }) + }) +}) diff --git a/site/test/perl-source-usage.test.ts b/site/test/perl-source-usage.test.ts new file mode 100644 index 000000000..614bdf020 --- /dev/null +++ b/site/test/perl-source-usage.test.ts @@ -0,0 +1,33 @@ +import { createHash } from 'node:crypto' +import { describe, expect, it } from 'vitest' +import { scanSource } from '../../scripts/lib/tmux-usage-scan.mjs' + +const text = "package LibTmux::Server;\nsub create($self) {\n$self->_cmd_op(['new-session']);\n}\n=pod\nkill-server\n=cut\n" +const native = () => ({ + sha256: createHash('sha256').update(text).digest('hex'), + functions: [{ name: 'create', owner: 'LibTmux::Server', start: 2, nameLine: 2, end: 4, kind: 'function' }], + types: [{ name: 'LibTmux::Server', start: 1, end: 7 }], + tokens: [ + { t: 'sym', v: '$self', line: 3, function: 0 }, + { t: 'sym', v: '->', line: 3, function: 0 }, + { t: 'id', v: '_cmd_op', line: 3, function: 0 }, + { t: 'sym', v: '(', line: 3, function: 0 }, + { t: 'str', v: 'new-session', line: 3, function: 0 }, + ], +}) +const options = { grammar: 'perl', text, commands: new Set(['new-session', 'kill-server']), known: new Set(['new-session', 'kill-server']) } + +describe('source-bound native PPI command analysis', () => { + it('retains package ownership and calls without treating POD as code', async () => { + const result = await scanSource({ ...options, native: native() }) + expect(result.functions[0]?.owner).toBe('LibTmux::Server') + expect(result.functions[0]?.calls.get('_cmd_op')).toBe(3) + expect([...result.functions[0]!.receivers.get('_cmd_op')!]).toEqual(['self']) + expect(result.functions[0]?.sites.map(({ command }) => command)).toEqual(['new-session']) + expect(result.functions[0]?.sites[0]?.dispatch).toBeNull() + }) + it('refuses absent or stale native parser input', async () => { + await expect(scanSource(options)).rejects.toThrow(/native PPI/) + await expect(scanSource({ ...options, native: { ...native(), sha256: '0'.repeat(64) } })).rejects.toThrow(/exact bytes/) + }) +}) diff --git a/site/test/port-inventory.test.ts b/site/test/port-inventory.test.ts index 0e204c4e2..c8fcf274a 100644 --- a/site/test/port-inventory.test.ts +++ b/site/test/port-inventory.test.ts @@ -19,9 +19,10 @@ const coordinates = (slug: string, kinds?: InventoryEntry['kind'][]) => const manifests = manifestPackages.ports as Record -const distributions = (slug: string) => published(slug).filter((entry) => !entry.within && entry.kind !== 'source') +const available = (slug: string) => entries(slug).filter((entry) => entry.status === 'published' || entry.sourceAvailable) +const distributions = (slug: string) => available(slug).filter((entry) => !entry.within && entry.kind !== 'source') const declared = (slug: string) => manifests[slug]!.distributions.map((entry) => entry.name) const GO = 'github.com/libtmux/libtmux-go' @@ -35,7 +36,7 @@ describe('port inventory', () => { expect(new Set(ids).size, 'ids are unique').toBe(ids.length) expect(entries(slug).filter((entry) => entry.kind === 'library'), 'exactly one library').toHaveLength(1) expect(entries(slug)[0]!.kind).toBe('library') - expect(entries(slug)[0]!.status).toBe('published') + expect(entries(slug)[0]!.status === 'published' || entries(slug)[0]!.sourceAvailable).toBe(true) for (const entry of entries(slug)) { expect(entry.label.trim(), entry.id).not.toBe('') expect(entry.coordinate.trim(), entry.id).not.toBe('') @@ -62,7 +63,7 @@ describe('port inventory', () => { it.each(PORTS.map(({ slug }) => slug).filter((slug) => manifests[slug]!.units.length > 0))('lists exactly the %s units its manifests declare', (slug) => { const types = new Set(manifests[slug]!.units.map((unit) => unit.unit)) - const found = published(slug).filter((entry) => entry.within && entry.unit && types.has(entry.unit)) + const found = available(slug).filter((entry) => entry.within && entry.unit && types.has(entry.unit)) const pair = (unit: string | undefined, name: string) => `${unit}: ${name}` expect(found.map((entry) => pair(entry.unit, entry.label)).sort((a, b) => a.localeCompare(b))) .toEqual(manifests[slug]!.units.map((unit) => pair(unit.unit, unit.name)).sort((a, b) => a.localeCompare(b))) @@ -151,6 +152,7 @@ describe('port inventory', () => { const commands = Object.entries(INVENTORY).flatMap(([slug, list]) => list.filter((entry) => /^(?:command|executable|executable product)$/.test(entry.unit ?? '')) .map((entry) => [slug, entry.id, entry.kind])) expect(commands).toEqual([ + ['perl', 'libtmux-workspace', 'cli'], ['go', 'libtmux-mcp', 'cli'], ['go', 'tmux-workspace', 'cli'], ['cxx', 'libtmux-mcp-server', 'cli'], ['cxx', 'tmux-workspace', 'cli'], ['swift', 'product:libtmux-mcp', 'cli'], ['swift', 'product:tmux-workspace', 'cli'], ]) @@ -200,7 +202,7 @@ describe('port inventory', () => { it('agrees with every field of the port metadata the hero already shows', () => { for (const port of PORTS) { const [library] = entries(port.slug) - const list = published(port.slug) + const list = available(port.slug) expect(library!.repo, `${port.slug} repo`).toBe(port.repo) // The vcpkg port is `libtmux`; the metadata's package name is the repository's. expect(library!.coordinate, `${port.slug} packageName`).toBe(port.slug === 'cxx' ? 'libtmux' : port.packageName) @@ -346,11 +348,12 @@ describe('port inventory', () => { const all = Object.entries(INVENTORY).flatMap(([port, list]) => list.map((entry) => ({ port, entry }))) for (const { port, entry } of all) { const leaf = entry.path?.split('/').at(-1) ?? '' - // A file has an extension and is opened as a blob; none of the directories here do. - expect(entry.file === true, `${port}:${entry.id} ${entry.path ?? ''}`).toBe(entry.path !== undefined && /\.[a-z]+$/.test(leaf)) + // Packaged executables may have no extension; their manifest reader records the file path. + const commandFile = manifests[port]?.units.some((unit) => unit.unit === 'command' && unit.path === entry.path && unit.file === true) + expect(entry.file === true, `${port}:${entry.id} ${entry.path ?? ''}`).toBe(entry.path !== undefined && (/\.[a-z]+$/.test(leaf) || commandFile === true)) if (entry.path) expect(sourceUrl(entry)).toContain(`/${entry.file ? 'blob' : 'tree'}/`) } expect(all.filter(({ entry }) => entry.file).map(({ port, entry }) => `${port}:${entry.id}`).sort()) - .toEqual(['julia:LibTmux.Filters', 'julia:LibTmuxJSONExt', 'julia:LibTmuxTablesExt', 'py:pytest-plugin']) + .toEqual(['julia:LibTmux.Filters', 'julia:LibTmuxJSONExt', 'julia:LibTmuxTablesExt', 'perl:libtmux-workspace', 'py:pytest-plugin']) }) }) diff --git a/site/test/port-prose.test.ts b/site/test/port-prose.test.ts index 44b96802a..5109f88bd 100644 --- a/site/test/port-prose.test.ts +++ b/site/test/port-prose.test.ts @@ -7,7 +7,7 @@ import { resolvePortBody, resolvePortContent } from '../src/lib/workspace-shared import { remarkPortCode, resolvePortCode } from '../src/plugins/remark-port-code.mjs' import { rehypeSiteRoot } from '../src/plugins/rehype-site-root.mjs' import { rehypeApiLinks } from '../src/plugins/rehype-api-links' -import { proseMentions } from '@libtmux/api-model' +import { proseMentions } from '@libtmux/api-model/reference' import { proseHref } from '../src/lib/docs-paths' import { docsEntriesAvailable, docsEntryAvailable } from '../src/lib/page-port-links' import { PORT_BY_SLUG } from '../src/lib/ports' diff --git a/site/test/powershell-prose-links.test.ts b/site/test/powershell-prose-links.test.ts index 102103d46..8b96f35f9 100644 --- a/site/test/powershell-prose-links.test.ts +++ b/site/test/powershell-prose-links.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { fromMarkdown } from 'mdast-util-from-markdown' -import { builtinHref, tokenizeDoc, type ApiSymbol } from '@libtmux/api-model' +import { builtinHref, tokenizeDoc, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS, createApiIndex } from '../src/lib/api-models' import { apiCommandFacts, parameterBindingFacts, parameterBindingText } from '../src/lib/api-sections' import { apiGlossaryHref } from '../src/lib/api-glossary' diff --git a/site/test/prerelease-notice.test.ts b/site/test/prerelease-notice.test.ts index c75da1e8c..c844501e7 100644 --- a/site/test/prerelease-notice.test.ts +++ b/site/test/prerelease-notice.test.ts @@ -12,7 +12,7 @@ import { withPortRoot, withRoot } from '../src/lib/site-root' import { buildTarget } from '../src/lib/versions' import { renderedTargets } from '../src/lib/inventory-targets' import { tmuxInventoryVersion } from '../src/lib/inventory-links' -import { targetKey } from '@libtmux/api-model' +import { targetKey } from '@libtmux/api-model/reference' const astroRequire = createRequire(realpathSync(new URL('../node_modules/astro/package.json', import.meta.url))) const noticeSource = readFileSync(new URL('../src/components/PrereleaseNotice.astro', import.meta.url), 'utf8') diff --git a/site/test/product-api-index.test.ts b/site/test/product-api-index.test.ts index 50f91b4e3..155cad04e 100644 --- a/site/test/product-api-index.test.ts +++ b/site/test/product-api-index.test.ts @@ -1,6 +1,6 @@ import { Window, type Element as DomElement } from 'happy-dom' import { afterAll, describe, expect, it } from 'vitest' -import { qualifiedNameOf } from '@libtmux/api-model' +import { qualifiedNameOf } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { productApiRoots } from '../src/lib/product-api' import { loadAstroTemplate, renderAstroTemplate } from './astro-templates' diff --git a/site/test/product-docs.test.ts b/site/test/product-docs.test.ts index 357d233d7..0f40a2601 100644 --- a/site/test/product-docs.test.ts +++ b/site/test/product-docs.test.ts @@ -79,7 +79,7 @@ const legacyWorkspaceTopics = new RegExp(`/(?:${portSlugs(PORTS.filter((port) => const storageIdentity = new RegExp(`/ports/(?:${portSlugs()})/`) // Port documentation is not translated, so no port tree exists under a translated locale. const localizedPortTree = new RegExp(`^/ja/(?:${portSlugs()})/`) -const nativeProductDocs = (port: string) => ['powershell', 'julia'].includes(port) +const nativeProductDocs = (port: string) => ['powershell', 'julia', 'perl'].includes(port) const mcpClientSetupRoutes: Record = { py: ['mcp/guides'], ruby: ['mcp/guides/connect-client', 'mcp/source-guide'], julia: ['mcp/source-guide'], ts: ['mcp/guides'], rs: ['mcp/guides/connect-client'], @@ -93,10 +93,10 @@ it('advertises local native loaders while retaining their development status', ( // py-vs-generic-local-CLI dichotomy this test covers. const native = (p: Port) => p.workspaceCliAvailability === 'local' || p.workspaceCliAvailability === 'published' for (const port of PORTS.filter((p) => p.slug === 'py' || native(p))) { - expect(port.workspaceCli).toBe(port.slug === 'julia' ? 'libtmux-workspace load' : native(port) ? 'tmux-workspace load' : 'tmuxp load') + expect(port.workspaceCli).toBe(['julia', 'perl'].includes(port.slug) ? 'libtmux-workspace load' : native(port) ? 'tmux-workspace load' : 'tmuxp load') if (!native(port)) expect(port.workspaceCliAvailability).toBe('released') expect(productInDevelopment(port, 'workspace')).toBe(native(port)) - expect(productInDevelopment(port, 'mcp')).toBe(true) + expect(productInDevelopment(port, 'mcp')).toBe(productAvailable(port, 'mcp')) expect(productDescription(port, 'workspace')).not.toMatch(/worktree|checkpoint/) if (port.workspaceCliAvailability === 'local') { expect(productDescription(port, 'workspace')).toContain(port.slug === 'julia' ? 'LibTmuxWorkspace' : 'Build the CLI from source') @@ -110,6 +110,8 @@ it('advertises local native loaders while retaining their development status', ( }) function sectionsFor(port: string, product: ProductPage['product']): string[] { + const registered = PORTS.find((entry) => entry.slug === port)! + if (registered.productAvailability?.[product] === 'excluded') return [] if (port === 'powershell' && product === 'mcp') return [] if (nativeProductDocs(port)) return ['', 'source-guide', 'reference'] // A product with no published implementation has only the overview that says so. diff --git a/site/test/product-reference.test.ts b/site/test/product-reference.test.ts index f7f55c52f..46a0d4be8 100644 --- a/site/test/product-reference.test.ts +++ b/site/test/product-reference.test.ts @@ -11,7 +11,7 @@ import { isTuplePayload } from '../src/lib/api-tree' import { symbolMarkdown } from '../src/lib/symbol-markdown' import { PORT_BY_SLUG, productAvailable } from '../src/lib/ports' import { getResolver } from '../src/lib/prose-resolver' -import { decideMention, symbolsForProduct, type ApiProduct } from '@libtmux/api-model' +import { decideMention, symbolsForProduct, type ApiProduct } from '@libtmux/api-model/reference' import type { SidebarItem } from '../src/lib/sidebar' import mentionIndex from '../src/data/mentions.json' import { apiCommandRelatedLinks } from '../src/lib/api-sections' diff --git a/site/test/publication-provenance.test.ts b/site/test/publication-provenance.test.ts index e128f0a08..007c463f3 100644 --- a/site/test/publication-provenance.test.ts +++ b/site/test/publication-provenance.test.ts @@ -183,7 +183,7 @@ describe('deterministic build provenance', () => { ]) }) - it.each(['ruby', 'lua', 'powershell', 'julia'])('records %s source and native exporter as separate clean inputs', (port) => { + it.each(['ruby', 'lua', 'powershell', 'julia', 'perl'])('records %s source and native exporter as separate clean inputs', (port) => { const docs = repository('libtmux/docs') const name = `libtmux/libtmux-${port}` const source = repository(name) @@ -204,7 +204,7 @@ describe('deterministic build provenance', () => { expect(snapshot(docs.directory, { ...env, LIBTMUX_DOCS_GENERATOR_CHECKOUT: source.directory }).nativeGenerator?.sha).toBe(source.sha) }) - it.each(['ruby', 'lua', 'powershell', 'julia'].flatMap((port) => + it.each(['ruby', 'lua', 'powershell', 'julia', 'perl'].flatMap((port) => ['missing', 'repository', 'sha', 'dirty', 'missing-dirty'].map((mutation) => [port, mutation]), ))('rejects %s native exporter metadata with %s', (port, mutation) => { const root = tree() @@ -226,7 +226,7 @@ describe('deterministic build provenance', () => { expect(() => verifyBuild(root, expected())).toThrow('unexpected native generator') }) - it.each(['ruby', 'lua', 'powershell', 'julia'])('rechecks the %s exporter HEAD when consuming the captured inputs', (port) => { + it.each(['ruby', 'lua', 'powershell', 'julia', 'perl'])('rechecks the %s exporter HEAD when consuming the captured inputs', (port) => { const docs = repository('libtmux/docs') const source = repository(`libtmux/libtmux-${port}`) const generator = repository(`libtmux/libtmux-${port}`, 'separate native exporter') @@ -242,7 +242,7 @@ describe('deterministic build provenance', () => { expect(() => snapshot(docs.directory, { ...env, LIBTMUX_DOCS_GENERATOR_CHECKOUT: docs.directory })).toThrow('native generator repository') }) - it.each(['ruby', 'lua', 'powershell', 'julia'])('can build an explicitly selected %s fork but rejects its publication', (port) => { + it.each(['ruby', 'lua', 'powershell', 'julia', 'perl'])('can build an explicitly selected %s fork but rejects its publication', (port) => { const docs = repository('libtmux/docs') const source = repository(`contributor/libtmux-${port}`) const generator = repository(`libtmux/libtmux-${port}`) diff --git a/site/test/published-inventory.test.ts b/site/test/published-inventory.test.ts index 5e22d2032..eaf5fb308 100644 --- a/site/test/published-inventory.test.ts +++ b/site/test/published-inventory.test.ts @@ -5,7 +5,7 @@ import { tmpdir } from 'node:os' import { dirname, join, resolve } from 'node:path' import { gzipSync } from 'node:zlib' import { afterEach, describe, expect, it } from 'vitest' -import { readInventory, targetKey, writeInventoryEntries } from '@libtmux/api-model' +import { readInventory, targetKey, writeInventoryEntries } from '@libtmux/api-model/reference' const root = resolve(import.meta.dirname, '../..') const scratch: string[] = [] diff --git a/site/test/python-layout.test.ts b/site/test/python-layout.test.ts index fc80e64ab..3deb49b9f 100644 --- a/site/test/python-layout.test.ts +++ b/site/test/python-layout.test.ts @@ -5,7 +5,7 @@ import { experimental_AstroContainer } from 'astro/container' import { Window } from 'happy-dom' import { fromMarkdown } from 'mdast-util-from-markdown' import { afterEach, describe, expect, it, vi } from 'vitest' -import { parameterId, qualifiedNameOf, SymbolIndex, type Param, type Signature } from '@libtmux/api-model' +import { parameterId, qualifiedNameOf, SymbolIndex, type Param, type Signature } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { signatureParameterText } from '../src/lib/api-sections' import { apiSignatureLayouts, CODE_COLUMNS, codeWidthFailures } from '../src/lib/code-layout' diff --git a/site/test/related-labels.test.ts b/site/test/related-labels.test.ts index 7a29ce84d..e7d975e25 100644 --- a/site/test/related-labels.test.ts +++ b/site/test/related-labels.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest' import { experimental_AstroContainer } from 'astro/container' import { Window, type Document } from 'happy-dom' -import { membersOf, memberSignals, moduleOf, qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model' +import { membersOf, memberSignals, moduleOf, qualifiedNameOf, type ApiSymbol } from '@libtmux/api-model/reference' import mentionsData from '../src/data/mentions.json' import { API_MODELS, indexFor, pageSlug, topLevelTypesOf } from '../src/lib/api-models' import { ownerQualifiedName, relatedLabels, type RelatedLabelInput } from '../src/lib/api-labels' diff --git a/site/test/ruby-layout-rendering.outer.test.ts b/site/test/ruby-layout-rendering.outer.test.ts new file mode 100644 index 000000000..dfe95aaff --- /dev/null +++ b/site/test/ruby-layout-rendering.outer.test.ts @@ -0,0 +1,27 @@ +// Compiles and renders real Astro declarations; pure layout fixtures remain in medium. +import { expect, it } from 'vitest' +import { API_MODELS } from '../src/lib/api-models' +import { displayedSignature, renderSignatures } from './signature-fragment' +import { fromMarkdown } from 'mdast-util-from-markdown' +import { SymbolIndex } from '@libtmux/api-model/reference' +import { symbolMarkdownWithLayout } from '../src/lib/symbol-markdown' + +const model = API_MODELS.ruby + +it('renders the page declaration and the Markdown export from one layout', async () => { + const symbol = model.symbols.find((entry) => entry.id === 'LibTmux::Async::Server#new_session')! + expect(symbol.signatures).toHaveLength(2) + const index = new SymbolIndex(model.symbols, (entry) => `/en/ruby/latest/reference/${entry.slug}/`, 'ruby') + const { signatures, window, layouts: prepared } = await renderSignatures(symbol, 'ruby', index) + try { + const expected = symbol.signatures.map((signature) => prepared.get(signature)!.text) + expect(signatures.map(displayedSignature)).toEqual(expected) + expect(signatures.map((element) => element.getAttribute('data-code-columns'))).toEqual(['60', '60']) + expect(signatures.map((element) => element.getAttribute('data-code-width-status'))).toEqual(['fits', 'fits']) + expect(signatures[1]!.querySelector('a[href="/en/ruby/latest/reference/' + model.symbols.find((entry) => entry.id === 'LibTmux::Session')!.slug + '/"]')?.textContent).toBe('LibTmux::Session') + expect([...window.document.querySelectorAll('a')].filter((link) => link.textContent === symbol.name)).toEqual([]) + const markdown = await symbolMarkdownWithLayout({ model, symbol }) + const fenced = fromMarkdown(markdown).children.find((node) => node.type === 'code') + expect(fenced?.type === 'code' && fenced.value).toBe(expected.join('\n\n')) + } finally { await window.happyDOM.abort() } + }) diff --git a/site/test/ruby-layout.test.ts b/site/test/ruby-layout.test.ts index 81667456d..8c189f0f0 100644 --- a/site/test/ruby-layout.test.ts +++ b/site/test/ruby-layout.test.ts @@ -1,12 +1,11 @@ import { readFileSync } from 'node:fs' import { describe, expect, it } from 'vitest' import { fromMarkdown } from 'mdast-util-from-markdown' -import { parameterId, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model' +import { parameterId, SymbolIndex, type ApiModel, type ApiSymbol, type Signature } from '@libtmux/api-model/reference' import { apiEntryFields, usesNativeSignatures } from '../src/lib/api-sections' import { apiSignatureLayouts, codeWidthFailures, signatureSpans, supportsRubySignatures, typeLayout, type SpanLayout } from '../src/lib/code-layout' import { rubyTypeLayout } from '../src/lib/ruby-code-layout' import { symbolMarkdownWithLayout } from '../src/lib/symbol-markdown' -import { displayedSignature, renderSignatures } from './signature-fragment' interface Reference { tools: Record; width: number; cases: { id: string; name: string; static: boolean; raw: string; reference: string; stock?: string | null }[] } const reference = JSON.parse(readFileSync(new URL('./fixtures/ruby-rbs-layout/reference.json', import.meta.url), 'utf8')) as Reference @@ -210,23 +209,6 @@ describe('Ruby RBS layouts', () => { expect(apiEntryFields(symbol, 'ruby').params.map((param) => param.name)).toEqual(['start', 'finish']) }) - it('renders the page declaration and the Markdown export from one layout', async () => { - const symbol = model.symbols.find((entry) => entry.id === 'LibTmux::Async::Server#new_session')! - expect(symbol.signatures).toHaveLength(2) - const index = new SymbolIndex(model.symbols, (entry) => `/en/ruby/latest/reference/${entry.slug}/`, 'ruby') - const { signatures, window, layouts: prepared } = await renderSignatures(symbol, 'ruby', index) - try { - const expected = symbol.signatures.map((signature) => prepared.get(signature)!.text) - expect(signatures.map(displayedSignature)).toEqual(expected) - expect(signatures.map((element) => element.getAttribute('data-code-columns'))).toEqual(['60', '60']) - expect(signatures.map((element) => element.getAttribute('data-code-width-status'))).toEqual(['fits', 'fits']) - expect(signatures[1]!.querySelector('a[href="/en/ruby/latest/reference/' + model.symbols.find((entry) => entry.id === 'LibTmux::Session')!.slug + '/"]')?.textContent).toBe('LibTmux::Session') - expect([...window.document.querySelectorAll('a')].filter((link) => link.textContent === symbol.name)).toEqual([]) - const markdown = await symbolMarkdownWithLayout({ model, symbol }) - const fenced = fromMarkdown(markdown).children.find((node) => node.type === 'code') - expect(fenced?.type === 'code' && fenced.value).toBe(expected.join('\n\n')) - } finally { await window.happyDOM.abort() } - }) }) it('leaves the classes and modules of the model to the generic declaration', () => { diff --git a/site/test/rust-variant-fields.test.ts b/site/test/rust-variant-fields.test.ts index 3162a4497..dcf8109dc 100644 --- a/site/test/rust-variant-fields.test.ts +++ b/site/test/rust-variant-fields.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { isMemberOwner as sharedMemberOwner, OWNER_KINDS as sharedOwnerKinds, ownersOf as proseOwnersOf, membersOf, navSidecarFor, SymbolIndex, type ApiModel, type ApiSymbol } from '@libtmux/api-model' +import { isMemberOwner as sharedMemberOwner, OWNER_KINDS as sharedOwnerKinds, ownersOf as proseOwnersOf, membersOf, navSidecarFor, SymbolIndex, type ApiModel, type ApiSymbol } from '@libtmux/api-model/reference' import { API_MODELS, API_NAV, isMemberOwner, OWNER_KINDS, ownersOf } from '../src/lib/api-models' import { membersByTypeFor, navTreeFor, referenceTreeFor } from '../src/lib/api-tree' import { searchApi } from '../src/lib/api-search' diff --git a/site/test/signature-fragment.ts b/site/test/signature-fragment.ts index 981a61b19..a845d5a56 100644 --- a/site/test/signature-fragment.ts +++ b/site/test/signature-fragment.ts @@ -30,6 +30,7 @@ async function compileFragment() { const type = await compile('../src/components/api/ApiType.astro', { './SymbolName.astro': name, './ApiKeyword.astro': keyword, '@libtmux/api-model': new URL('../../packages/api-model/src/index.ts', import.meta.url).href, + '@libtmux/api-model/reference': new URL('../../packages/api-model/src/reference.ts', import.meta.url).href, '../../lib/code-layout': new URL('../src/lib/code-layout.ts', import.meta.url).href, }) const source = readFileSync(new URL('../src/components/api/ApiEntry.astro', import.meta.url), 'utf8') diff --git a/site/test/source-only-inventory.test.ts b/site/test/source-only-inventory.test.ts new file mode 100644 index 000000000..b6620dce3 --- /dev/null +++ b/site/test/source-only-inventory.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from 'vitest' +import { collectDestinations, inventoryCoverage } from '../../scripts/lib/destination-verification.mjs' +import { portHeaderLinks } from '../src/lib/header-links' +import { INVENTORY, type InventoryEntry } from '../src/lib/port-inventory' +import { PORT_BY_SLUG } from '../src/lib/ports' + +const library: InventoryEntry = { + ...INVENTORY.perl![0]!, sourceAvailable: true, + package: { host: 'npm', url: 'https://www.npmjs.com/package/unpublished-test' }, +} + +describe('source availability independent of registry publication', () => { + it('offers verified source without a package-host or API publication claim', () => { + const links = portHeaderLinks(PORT_BY_SLUG.perl!, { perl: [library] }) + expect(links.actions.map(({ kind }) => kind)).toEqual(['source']) + expect(links.rows.map(({ kind }) => kind)).toEqual(['source']) + expect(links.rows[0]?.url).toContain('/tree/master/packages/core') + }) + it('verifies available source as present and the unpublished host as absent', () => { + const records = collectDestinations({ perl: [library] }, {}) + expect([...records.values()].find(({ host }) => host === 'github')?.entries[0].status).toBe('published') + expect(records.get(library.package!.url)?.entries[0].status).toBe('configured-unpublished') + expect(inventoryCoverage({ perl: [library] }, ['perl'])).toEqual([]) + expect(inventoryCoverage({ perl: [{ ...library, sourceAvailable: false }] }, ['perl'])).not.toEqual([]) + }) +}) diff --git a/site/test/stage-port-docs.outer.test.ts b/site/test/stage-port-docs.outer.test.ts index 7c7ab8f4f..f1c77a0b0 100644 --- a/site/test/stage-port-docs.outer.test.ts +++ b/site/test/stage-port-docs.outer.test.ts @@ -1,5 +1,5 @@ import { execFileSync, spawnSync } from 'node:child_process' -import { copyFileSync, cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs' +import { copyFileSync, cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, symlinkSync, utimesSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { expect, it } from 'vitest' @@ -11,7 +11,7 @@ const cachedRevision = 'a'.repeat(40) const files = ['scripts/stage-port-docs.mjs', 'site/src/lib/ports.ts', 'site/src/lib/site-root.ts', 'site/src/lib/cooldown.ts', 'site/src/lib/port-documentation.ts', 'site/src/lib/versions.ts'] -const stagedPorts = ['ruby', 'lua', 'powershell', 'julia', 'elixir', 'kotlin', 'scala', 'fsharp'] +const stagedPorts = ['ruby', 'lua', 'powershell', 'julia', 'elixir', 'kotlin', 'scala', 'fsharp', 'perl'] function fixture(slug: 'ruby' | 'lua' | 'kotlin', run: (fixture: { directory: string; checkout: string; revision: string; @@ -117,6 +117,11 @@ it.each(['ruby', 'lua', 'kotlin'] as const)('stages other caches before acceptin expect(readFileSync(rendered, 'utf8')).toContain(`fresh-${slug}`) expect(readFileSync(rendered, 'utf8')).toContain(revision) expect(JSON.parse(readFileSync(cache, 'utf8')).source.revision).toBe(revision) + const observed = new Date('2000-01-01T00:00:00Z') + utimesSync(rendered, observed, observed) + const repeated = invoke('--port', slug, ...(slug === 'kotlin' ? ['--from-source'] : [])) + expect(repeated.status, repeated.stderr).toBe(0) + expect(statSync(rendered).mtimeMs).toBe(observed.getTime()) const wrappers = invoke('--wrappers') expect(wrappers.status, wrappers.stderr).toBe(0) const renderedBytes = readFileSync(rendered, 'utf8') diff --git a/site/test/stage-port-docs.test.ts b/site/test/stage-port-docs.test.ts index 6cab3c66d..dc4120216 100644 --- a/site/test/stage-port-docs.test.ts +++ b/site/test/stage-port-docs.test.ts @@ -22,9 +22,11 @@ describe('integrated guide inputs', () => { const git = (...args: string[]) => execFileSync('git', ['-C', checkout, ...args], { encoding: 'utf8', stdio: 'pipe' }).trim() try { git('init', '-q') - for (const path of Object.keys(stagedRoutesFor('lua'))) { + const paths = Object.keys(stagedRoutesFor('lua')) + const contents = new Map(paths.map((path, index) => [path, `# Integrated guide ${index}\n\nUTF-8: café λ\nblob 0\n\0\n`])) + for (const path of paths) { mkdirSync(dirname(join(checkout, path)), { recursive: true }) - writeFileSync(join(checkout, path), '# Integrated guide\n') + writeFileSync(join(checkout, path), contents.get(path)!) } git('add', '.') git('-c', 'user.name=Fixture', '-c', 'user.email=fixture@example.invalid', 'commit', '-qm', 'integrated') @@ -36,7 +38,7 @@ describe('integrated guide inputs', () => { const artifact = artifactFromRevision(port, checkout, revision) expect(artifact.source).toEqual({ repository: port.repo, revision }) expect(artifact.guides.length).toBe(Object.keys(stagedRoutesFor('lua')).length) - expect(artifact.guides.every((guide: { content: string }) => guide.content === '# Integrated guide\n')).toBe(true) + for (const guide of artifact.guides) expect(guide.content).toBe(contents.get(guide.path)) } finally { rmSync(checkout, { recursive: true, force: true }) } @@ -128,7 +130,12 @@ describe('staged port guide links', () => { expect(index).toContain('"label":"Overview","order":1') const cards = JSON.parse(/^cards: (.+)$/m.exec(index)![1]) expect(cards[0].label).toBe('Getting started') - expect(cards[1].label).toBe('Attaching to tmux') + expect(cards[1].label).toBe(port === 'perl' ? 'Installation' : 'Attaching to tmux') + if (port === 'perl') { + const example = files.get('perl/examples/orchestration/index.md')! + const body = /^---\n[\s\S]*?\n---\n\n([\s\S]*)$/.exec(example)![1] + expect(body).toMatch(/^Constructing `LibTmux::Server`/) + } for (const section of ['examples', 'topics']) { const page = files.get(`${port}/${section}/index.md`) if (!page) continue diff --git a/site/test/swift-layout.test.ts b/site/test/swift-layout.test.ts index 568478b16..5e4689bbe 100644 --- a/site/test/swift-layout.test.ts +++ b/site/test/swift-layout.test.ts @@ -3,7 +3,7 @@ import { createRequire } from 'node:module' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it, vi } from 'vitest' import { experimental_AstroContainer } from 'astro/container' -import { parameterId, SymbolIndex, type ApiModel, type ApiSymbol, type Param } from '@libtmux/api-model' +import { parameterId, SymbolIndex, type ApiModel, type ApiSymbol, type Param } from '@libtmux/api-model/reference' import { fromMarkdown } from 'mdast-util-from-markdown' import { apiSignatureLayouts, CODE_COLUMNS, codeWidthFailures, signatureSpans, typeLayout, type CodeLayout, type SpanLayout } from '../src/lib/code-layout' import { nativeSignatureText, usesNativeSignatures } from '../src/lib/api-sections' diff --git a/site/test/symbol-form.test.ts b/site/test/symbol-form.test.ts index 4fbd3b1e9..4d14092b2 100644 --- a/site/test/symbol-form.test.ts +++ b/site/test/symbol-form.test.ts @@ -18,6 +18,7 @@ interface Row { } const ROWS: Record = { + perl: { type: ['LibTmux::Server', 'LibTmux::Server'], method: ['LibTmux::Server/snapshot', 'LibTmux::Server/snapshot', 'LibTmux::Server::snapshot'], function: ['grep', 'grep', 'LibTmux::Selection::grep'], property: ['Pane/width', 'Pane/width', 'LibTmux::Pane::width'], member: ['Mode', 'active', 'LibTmux::Mode::active', 'active', 'active'] }, py: { type: ['libtmux::Server', 'libtmux.Server'], method: ['Server.list_sessions', 'Server.list_sessions()', 'libtmux.Server.list_sessions'], function: ['get_version', 'get_version()', 'libtmux.get_version'], property: ['Server.socket_name', 'Server.socket_name', 'libtmux.Server.socket_name'], member: ['Direction', 'UP', 'libtmux.Direction.UP', 'Direction.UP', 'Direction.UP'] }, ts: { type: ['server.Server', 'server.Server'], method: ['Server.listSessions', 'Server.listSessions()', 'server.Server.listSessions'], function: ['parseWorkspace', 'parseWorkspace()', 'config.parseWorkspace'], property: ['Pane.id', 'Pane.id', 'pane.Pane.id'], member: ['Direction', 'Up', 'constants.Direction.Up', 'Direction.Up', 'Direction.Up'] }, rs: { type: ['crate.Server', 'crate::Server'], method: ['Server.list_sessions', 'Server::list_sessions()', 'server.Server.list_sessions'], function: ['retry_until', 'retry_until()', 'test.retry_until'], property: ['Pane::id', 'Pane::id', 'pane.Pane.id'], member: ['Direction', 'Up', 'pane.Direction.Up', 'Direction::Up', 'Direction::Up'] }, diff --git a/site/test/tmux-catalog-coverage.outer.test.ts b/site/test/tmux-catalog-coverage.outer.test.ts index b0e409a18..35befadac 100644 --- a/site/test/tmux-catalog-coverage.outer.test.ts +++ b/site/test/tmux-catalog-coverage.outer.test.ts @@ -2,7 +2,7 @@ import { readdirSync, readFileSync } from 'node:fs' import { join, relative } from 'node:path' import { fileURLToPath } from 'node:url' import { createMarkdownProcessor } from '@astrojs/markdown-remark' -import { SymbolIndex } from '@libtmux/api-model' +import { SymbolIndex } from '@libtmux/api-model/reference' import { Window } from 'happy-dom' import { describe, expect, it } from 'vitest' import { API_MODELS } from '../src/lib/api-models' diff --git a/site/test/tmux-catalog-links.test.ts b/site/test/tmux-catalog-links.test.ts index 1d13c0781..78a7703fe 100644 --- a/site/test/tmux-catalog-links.test.ts +++ b/site/test/tmux-catalog-links.test.ts @@ -3,7 +3,7 @@ import { createRequire } from 'node:module' import { pathToFileURL } from 'node:url' import { createMarkdownProcessor } from '@astrojs/markdown-remark' import { experimental_AstroContainer } from 'astro/container' -import { SymbolIndex } from '@libtmux/api-model' +import { SymbolIndex } from '@libtmux/api-model/reference' import { fromHtml } from 'hast-util-from-html' import { selectAll } from 'astro-expressive-code/hast' import { Window } from 'happy-dom' diff --git a/site/test/tmux-links.test.ts b/site/test/tmux-links.test.ts index 816bb689f..d6c33df28 100644 --- a/site/test/tmux-links.test.ts +++ b/site/test/tmux-links.test.ts @@ -2,7 +2,7 @@ import { readFileSync, realpathSync } from 'node:fs' import { createRequire } from 'node:module' import { pathToFileURL } from 'node:url' import { experimental_AstroContainer } from 'astro/container' -import { SymbolIndex } from '@libtmux/api-model' +import { SymbolIndex } from '@libtmux/api-model/reference' import { Window, type Element as DomElement } from 'happy-dom' import { afterEach, describe, expect, it, vi } from 'vitest' import { API_MODELS, indexFor } from '../src/lib/api-models' diff --git a/site/test/tmux-reference.test.ts b/site/test/tmux-reference.test.ts index dd81172b9..ff48b6a96 100644 --- a/site/test/tmux-reference.test.ts +++ b/site/test/tmux-reference.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest' vi.mock('astro:content', () => ({ getCollection: async () => [] })) -import { readInventory, sourceUrl, writeInventory } from '@libtmux/api-model' +import { readInventory, sourceUrl, writeInventory } from '@libtmux/api-model/reference' import { tmuxCommandSources, tmuxReferenceContext, tmuxReferenceIndex, tmuxReferencePaths, tmuxReferencePreview, tmuxReferenceTree, tmuxReferenceUrl, tmuxReferenceVersionUrl, tmuxSourceCommands, tmuxSourceModel } from '../src/lib/tmux-reference' import { tmuxManual, tmuxManualUrl } from '../src/lib/tmux-manual-data' import { referenceIndexSectionsFor } from '../src/lib/api-tree' diff --git a/site/test/type-alias-declaration.test.ts b/site/test/type-alias-declaration.test.ts index 516406d6a..6cc364c4e 100644 --- a/site/test/type-alias-declaration.test.ts +++ b/site/test/type-alias-declaration.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest' import { Window } from 'happy-dom' -import { SymbolIndex, membersOf, pageMembersOf } from '@libtmux/api-model' +import { SymbolIndex, membersOf, pageMembersOf } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { referenceTree } from '../src/lib/api-tree' import { sidebarCatalog } from '../src/lib/api-sidebar' diff --git a/site/test/type-parameters.test.ts b/site/test/type-parameters.test.ts index 7bc3b1a38..3ec0d8c21 100644 --- a/site/test/type-parameters.test.ts +++ b/site/test/type-parameters.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { fromMarkdown } from 'mdast-util-from-markdown' -import { SymbolIndex, typeParameterId, type ApiSymbol, type Signature } from '@libtmux/api-model' +import { SymbolIndex, typeParameterId, type ApiSymbol, type Signature } from '@libtmux/api-model/reference' import { API_MODELS } from '../src/lib/api-models' import { apiEntryFields, apiEntrySections, nativeSignatureText } from '../src/lib/api-sections' import { apiSignatureLayouts, signatureSpans } from '../src/lib/code-layout' From f14e97e25a512167f59f0b15073f390f76cbfcef Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 7 Nov 2026 18:42:58 -0600 Subject: [PATCH 04/30] docs(ci[perl]) Check native contracts and shared types before artifact upload why: Source-only Perl documentation needs a checked artifact from the same pinned builder and publisher revision. what: - Run native model, POD link, source scan and package inventory checks after rendering - Check shared TypeScript and Astro types before uploading the Perl tree - Document the exact focused commands separately from publication and timing gates --- .github/CONTRIBUTING.md | 26 ++++++++++++++++++++++++++ .github/workflows/port-docs.yml | 15 +++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 73fe20485..d207db710 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -680,3 +680,29 @@ cleanup in separate work. Follow [WRITING.md](../WRITING.md#commits) for commit messages and [AGENTS.md](../AGENTS.md#repository-boundaries) for push and deployment limits. + +### Perl source-bound documentation checks + +The reusable port builder checks the selected Perl artifact after rendering. +It runs the native model/POD/source/inventory suites and the shared Node type +checks before uploading an artifact. These checks use the selected source +revision and the builder workflow's own committed docs revision. They do not +replace the development-loop timing gates or the full publication audit. + +```console +$ node site/node_modules/vitest/vitest.mjs run \ + --root packages/api-model \ + test/perl.test.ts +``` + +```console +$ node site/node_modules/vitest/vitest.mjs run \ + --root site \ + test/perl-pod-links.test.ts \ + test/perl-source-usage.test.ts \ + test/source-only-inventory.test.ts +``` + +```console +$ pnpm run --recursive type-check +``` diff --git a/.github/workflows/port-docs.yml b/.github/workflows/port-docs.yml index a3f7c5a19..f0ca1cf5d 100644 --- a/.github/workflows/port-docs.yml +++ b/.github/workflows/port-docs.yml @@ -642,6 +642,21 @@ jobs: test -s "_site/en/py/$LIBTMUX_DOCS_VERSION/api/api/index.html" fi + - name: Check Perl native model and authored POD links + if: matrix.port == 'perl' + working-directory: docs + env: + LIBTMUX_DOCS_TEST_SOURCE_ONLY: '1' + run: | + time node site/node_modules/vitest/vitest.mjs run --root packages/api-model test/perl.test.ts + time node site/node_modules/vitest/vitest.mjs run --root site \ + test/perl-pod-links.test.ts test/perl-source-usage.test.ts test/source-only-inventory.test.ts + + - name: Check shared TypeScript and Astro types for Perl + if: matrix.port == 'perl' + working-directory: docs + run: time pnpm run --recursive type-check + # The version directory itself: its contents become # //. - id: content From 27da172ab4f71229d72928b98568545f22a15372 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 7 Nov 2026 19:03:07 -0600 Subject: [PATCH 05/30] docs(fix[checks]) Restore reader exports and destination fixture imports why: Shared rendering needs the Python docstring parser through the reader entry, and destination fixtures must retain their file reader after merging the current documentation source. what: - Export the documentation parser without importing native extractors - Exercise the public reader entry through the existing docstring suite - Restore the filesystem import used by the destination evidence fixture --- packages/api-model/src/reference.ts | 1 + packages/api-model/test/python-docs.test.ts | 3 ++- site/test/api-destination-evidence.test.ts | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/api-model/src/reference.ts b/packages/api-model/src/reference.ts index f6787818d..d149d6216 100644 --- a/packages/api-model/src/reference.ts +++ b/packages/api-model/src/reference.ts @@ -4,6 +4,7 @@ export { sourceUrl, symbolsForProduct } from './products.ts' export { SymbolIndex, keywordArgument, parameterId, typeParameterId, type LinkTarget, type KeywordHelp, type TypeParameterBinding } from './link.ts' export { boundLabel, parseTypeParameter, parseTypeParameters, typeParameterList, typeParametersOf, withTypeParameterDocs } from './type-params.ts' export { tokenizeDoc, docSummaryText, referencesIn, type DocSpan } from './doc/roles.ts' +export { parsePythonDoc } from './doc/python.ts' export { writeInventory, writeInventoryEntries, readInventory, inventoryType, isSymbolEntry, symbolEntries, NON_SYMBOL_ROLES, type InventoryEntry } from './inventory.ts' export { targetKey, targetEntries, compatibilityEntries, type InventoryTarget } from './targets.ts' export { Resolver, notASymbol, toPath, DEFAULT_TEMPLATES, DEFAULT_PRIMARY_MODULES } from './resolver.ts' diff --git a/packages/api-model/test/python-docs.test.ts b/packages/api-model/test/python-docs.test.ts index 4610cc0d2..ea702e09c 100644 --- a/packages/api-model/test/python-docs.test.ts +++ b/packages/api-model/test/python-docs.test.ts @@ -3,7 +3,8 @@ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { describe, expect, it } from 'vitest' -import { parsePythonDoc, pythonDocBody } from '../src/doc/python.ts' +import { pythonDocBody } from '../src/doc/python.ts' +import { parsePythonDoc } from '@libtmux/api-model/reference' import { docSummaryText, referencesIn, tokenizeDoc } from '../src/doc/roles.ts' import { extractPython } from '../src/languages/python.ts' import { readInventory } from '../src/inventory.ts' diff --git a/site/test/api-destination-evidence.test.ts b/site/test/api-destination-evidence.test.ts index 207e92861..8fbdc99db 100644 --- a/site/test/api-destination-evidence.test.ts +++ b/site/test/api-destination-evidence.test.ts @@ -1,3 +1,4 @@ +import { readFileSync } from 'node:fs' import { describe, expect, it } from 'vitest' import { API_HOSTS, PAGE_EXCEPTIONS, addressSegments, apiHostOf, arityOf, linksIn, qualified, terminalSymbol, urlsIn } from '../../scripts/lib/api-destinations.mjs' import { addressOf, mismatch } from '../../scripts/lib/api-addresses.mjs' From fdf4a4e7876b19b23679d349d17a68c88852232c Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 7 Nov 2026 19:32:31 -0600 Subject: [PATCH 06/30] docs(fix[perl]) Add the workspace API index why: Workspace navigation and declaration breadcrumbs need a real reference index before readers can browse the installed loader API. what: - Add the native workspace index using the existing product reference page - Link the public module and versioned configuration guide --- .../docs/ports/perl/workspace/reference.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 site/src/content/docs/ports/perl/workspace/reference.md diff --git a/site/src/content/docs/ports/perl/workspace/reference.md b/site/src/content/docs/ports/perl/workspace/reference.md new file mode 100644 index 000000000..3a2ea314d --- /dev/null +++ b/site/src/content/docs/ports/perl/workspace/reference.md @@ -0,0 +1,18 @@ +--- +title: LibTmux::Workspace API reference +description: Public Perl workspace configuration, planning, loading, and error APIs. +port: perl +product: workspace +sidebar: + label: Language API + order: 4 +--- + +Use [LibTmux::Workspace](./libtmux-workspace/) to validate configuration, +inspect a plan, and load sessions, windows, and panes through public core +APIs. Planning performs no tmux I/O. Loading reports completed steps, +conflicts, and partial failures. + +The declarations below preserve native signatures, POD links, and source +locations. Read the [workspace guide](../source-guide/) for the versioned +JSON format, source installation, and complete CLI examples. From 64aaaa816186f03f9e3e1bd724af753152b9763a Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 7 Nov 2026 19:32:31 -0600 Subject: [PATCH 07/30] docs(fix[status]) Describe unpublished ports as source previews why: A release notice must agree with the selected port's registry status when its packages are available only from source. what: - Derive the notice from the existing product maturity data - Carry the selected port through shared and native layouts - Check unpublished core and workspace pages alongside released ports --- site/src/components/PrereleaseNotice.astro | 15 ++++++++++----- site/src/layouts/BaseLayout.astro | 2 +- site/src/layouts/NativeShell.astro | 2 +- site/test/prerelease-notice.test.ts | 18 +++++++++++++++--- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/site/src/components/PrereleaseNotice.astro b/site/src/components/PrereleaseNotice.astro index 33f1d10d5..9b2fd9ece 100644 --- a/site/src/components/PrereleaseNotice.astro +++ b/site/src/components/PrereleaseNotice.astro @@ -1,6 +1,8 @@ --- +import { PORT_BY_SLUG, productStatus } from '../lib/ports' +import { REGISTRY } from '../lib/registry' /** - * The bar that says the libraries are released but still change between releases. + * Release maturity notice for the selected port. * * Sits directly under the header and scrolls away with the page rather than * pinning: the header is `sticky top-0`, and a second sticky strip would take @@ -24,17 +26,20 @@ interface Props { /** Match the root landing page's centered content column. */ centered?: boolean + port?: string } -const { centered = false } = Astro.props +const { centered = false, port } = Astro.props +const info = port ? PORT_BY_SLUG[port] : undefined +const unpublished = info && productStatus(info, 'core', REGISTRY) === 'unreleased' ---

- Early release + {unpublished ? 'Source preview' : 'Early release'} - libtmux is released, and its APIs may still change between releases. - This site's structure and URLs may change too. + {unpublished ? "This library is not published yet. Install it from source. Its APIs and this site's structure and URLs may change." + : "libtmux is released, and its APIs may still change between releases. This site's structure and URLs may change too."}