@mean-weasel/lineage 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/cli/lineageCli.ts", "../../src/server/agentClaims.ts", "../../src/server/assetLineageDb.ts", "../../src/server/assetCore.ts", "../../src/server/adapters/storage/s3StorageAdapter.ts", "../../src/server/localReview.ts", "../../src/server/assetLineageSelection.ts", "../../src/server/assetLineageWorkspaces.ts", "../../src/server/assetLineage.ts", "../../src/server/assetLineageHandoff.ts", "../../src/cli/lineage.ts"],
4
- "sourcesContent": ["import { existsSync, mkdirSync, readFileSync } from 'node:fs';\nimport { homedir, platform } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport {\n createAgentClaim,\n heartbeatAgentClaim,\n inspectAgentClaim,\n isAgentClaimError,\n listAgentClaims,\n parseClaimTtl,\n redactAgentClaimTokens,\n releaseAgentClaim,\n revokeAgentClaim,\n transferAgentClaim,\n type AgentClaimScopeType,\n} from '../server/agentClaims';\nimport { defaultProduct } from '../server/assetCore';\nimport { getLineageNextAsset, getLineageSnapshot } from '../server/assetLineage';\nimport { getLineageBrief, linkSelectedLineageChild } from '../server/assetLineageHandoff';\n\nexport interface LineageCliConfig {\n binName: 'lineage' | 'lineage-dev';\n channel: 'stable' | 'development';\n defaultHost: string;\n defaultPort: number;\n displayName: string;\n}\n\ninterface StartOptions {\n dbPath: string;\n host: string;\n json: boolean;\n open: boolean;\n port: number;\n}\n\ninterface DataCommandOptions {\n assetId?: string;\n childAssetId?: string;\n claimToken?: string;\n confirmWrite: boolean;\n dbPath?: string;\n json: boolean;\n project: string;\n rootAssetId?: string;\n}\n\nconst signalExitCodes: Partial<Record<NodeJS.Signals, number>> = {\n SIGINT: 130,\n SIGTERM: 143,\n};\n\nfunction packageRoot(): string {\n return resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');\n}\n\nfunction packageVersion(): string {\n try {\n const packageInfo = JSON.parse(readFileSync(join(packageRoot(), 'package.json'), 'utf8')) as { version?: string };\n return packageInfo.version || '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n\nfunction dataRoot(displayName: string): string {\n if (process.env.LINEAGE_HOME) return process.env.LINEAGE_HOME;\n if (platform() === 'darwin') return join(homedir(), 'Library', 'Application Support', displayName);\n if (platform() === 'win32') return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), displayName);\n return join(process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share'), displayName.toLowerCase().replace(/\\s+/g, '-'));\n}\n\nfunction readOption(args: string[], name: string): string | undefined {\n const prefix = `${name}=`;\n const inline = args.find(arg => arg.startsWith(prefix));\n if (inline) return inline.slice(prefix.length);\n const index = args.indexOf(name);\n if (index >= 0) return args[index + 1];\n return undefined;\n}\n\nexport function resolveStartOptions(config: LineageCliConfig, args: string[]): StartOptions {\n const runtimeDir = dataRoot(config.displayName);\n const rawPort = readOption(args, '--port') || process.env.PORT || String(config.defaultPort);\n const port = Number(rawPort);\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`Invalid port: ${rawPort}`);\n }\n return {\n dbPath: readOption(args, '--db') || process.env.LINEAGE_DB || join(runtimeDir, `${config.binName}.sqlite`),\n host: readOption(args, '--host') || process.env.HOST || config.defaultHost,\n json: args.includes('--json'),\n open: args.includes('--open'),\n port,\n };\n}\n\nfunction printHelp(config: LineageCliConfig): void {\n console.log(`${config.binName} ${packageVersion()}\n\nUsage:\n ${config.binName} start [--port <port>] [--host <host>] [--db <path>] [--open] [--json]\n ${config.binName} next [--project <project>] [--root <asset-id>] [--db <path>] [--json]\n ${config.binName} brief [--project <project>] [--root <asset-id>] [--db <path>] [--json]\n ${config.binName} inspect --asset-id <asset-id> [--project <project>] [--db <path>] [--json]\n ${config.binName} link-child --root <asset-id> --child <asset-id> [--project <project>] [--claim-token <claim-id.secret>] [--confirm-write] [--db <path>] [--json]\n ${config.binName} agent claim --project <project> --scope <scope> --target <target-id> --agent-name <name> [--channel <channel>] [--ttl 20m] [--json]\n ${config.binName} agent status [--project <project>] [--json]\n ${config.binName} agent inspect --claim <claim-id> [--project <project>] [--json]\n ${config.binName} agent heartbeat --claim-token <claim-id.secret> [--json]\n ${config.binName} agent release --claim-token <claim-id.secret> [--json]\n ${config.binName} agent revoke --claim <claim-id> --project <project> --reason <text> --confirm-write [--json]\n ${config.binName} agent transfer --claim <claim-id> --to-agent-name <name> --confirm-write [--project <project>] [--json]\n ${config.binName} --help\n ${config.binName} --version\n\n${config.displayName} runs the bundled Lineage server for the ${config.channel} channel.`);\n}\n\nfunction openBrowser(url: string): void {\n const command = platform() === 'darwin' ? 'open' : platform() === 'win32' ? 'cmd' : 'xdg-open';\n const args = platform() === 'win32' ? ['/c', 'start', '', url] : [url];\n const opener = spawn(command, args, { detached: true, stdio: 'ignore' });\n opener.unref();\n}\n\nfunction positionalArgs(args: string[]): string[] {\n const values: string[] = [];\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n if (arg.startsWith('--')) {\n if (!arg.includes('=') && args[index + 1] && !args[index + 1].startsWith('--')) index += 1;\n continue;\n }\n values.push(arg);\n }\n return values;\n}\n\nfunction resolveDataCommandOptions(args: string[]): DataCommandOptions {\n const positions = positionalArgs(args);\n const options = {\n assetId: readOption(args, '--asset-id') || positions[0],\n childAssetId: readOption(args, '--child'),\n claimToken: readOption(args, '--claim-token') || process.env.LINEAGE_CLAIM_TOKEN,\n confirmWrite: args.includes('--confirm-write'),\n dbPath: readOption(args, '--db'),\n json: args.includes('--json'),\n project: readOption(args, '--project') || process.env.LINEAGE_DEFAULT_PRODUCT || defaultProduct,\n rootAssetId: readOption(args, '--root'),\n };\n if (options.dbPath) process.env.LINEAGE_DB = options.dbPath;\n return options;\n}\n\nexport function runLineageDataCommand(command: string, args: string[]): unknown {\n const options = resolveDataCommandOptions(args);\n if (command === 'next') return getLineageNextAsset(options.project, options.rootAssetId || options.assetId);\n if (command === 'brief') return getLineageBrief(options.project, options.rootAssetId || options.assetId);\n if (command === 'inspect') {\n if (!options.assetId) throw new Error('lineage inspect requires --asset-id');\n return getLineageSnapshot(options.project, options.assetId);\n }\n if (command === 'link-child') {\n if (!options.childAssetId) throw new Error('lineage link-child requires --child');\n return linkSelectedLineageChild(options.project, {\n childAssetId: options.childAssetId,\n claimToken: options.claimToken,\n confirmWrite: options.confirmWrite,\n rootAssetId: options.rootAssetId || options.assetId,\n });\n }\n throw new Error(`Unknown command: ${command}`);\n}\n\nfunction printDataResult(command: string, result: unknown, json: boolean): void {\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n if (command === 'next' && result && typeof result === 'object' && 'reason' in result) {\n const next = result as { next_asset?: { asset_id: string; title: string } | null; reason: string; root_asset_id: string };\n console.log(next.next_asset ? `${next.next_asset.asset_id}: ${next.next_asset.title}` : `No next asset: ${next.reason}`);\n console.log(`Root: ${next.root_asset_id}`);\n return;\n }\n if (command === 'brief' && result && typeof result === 'object' && 'brief' in result) {\n const brief = result as { brief: { title: string; prompt: string } };\n console.log(brief.brief.title);\n console.log(brief.brief.prompt);\n return;\n }\n if (command === 'inspect' && result && typeof result === 'object' && 'nodes' in result) {\n const snapshot = result as { active_asset_id: string; edges: unknown[]; nodes: unknown[]; root_asset_id: string };\n console.log(`${snapshot.root_asset_id}: ${snapshot.nodes.length} node(s), ${snapshot.edges.length} edge(s)`);\n console.log(`Active: ${snapshot.active_asset_id}`);\n return;\n }\n if (command === 'link-child' && result && typeof result === 'object') {\n const link = result as { dryRun?: boolean; edge?: { child_asset_id: string; parent_asset_id: string }; message?: string };\n console.log(link.message || `${link.dryRun ? 'Dry run: ' : ''}Link ${link.edge?.child_asset_id || 'child'} from ${link.edge?.parent_asset_id || 'parent'}`);\n return;\n }\n console.log(String(result));\n}\n\nexport function runLineageAgentCommand(command: string, args: string[]): unknown {\n const dbPath = readOption(args, '--db');\n if (dbPath) process.env.LINEAGE_DB = dbPath;\n const project = readOption(args, '--project') || process.env.LINEAGE_DEFAULT_PRODUCT || defaultProduct;\n const claimId = readOption(args, '--claim');\n const claimToken = readOption(args, '--claim-token') || process.env.LINEAGE_CLAIM_TOKEN;\n if (command === 'claim') {\n return createAgentClaim({\n agentId: readOption(args, '--agent-id'),\n agentKind: readOption(args, '--agent-kind'),\n agentName: readOption(args, '--agent-name') || '',\n channel: readOption(args, '--channel'),\n force: args.includes('--force'),\n project,\n reason: readOption(args, '--reason'),\n scopeType: (readOption(args, '--scope') || '') as AgentClaimScopeType,\n targetId: readOption(args, '--target') || '',\n targetTitle: readOption(args, '--target-title'),\n threadId: readOption(args, '--thread-id'),\n ttlSeconds: parseClaimTtl(readOption(args, '--ttl')),\n });\n }\n if (command === 'status') return listAgentClaims(project);\n if (command === 'inspect') {\n if (!claimId) throw new Error('lineage agent inspect requires --claim');\n return inspectAgentClaim(claimId, project);\n }\n if (command === 'heartbeat') {\n if (!claimToken) throw new Error('lineage agent heartbeat requires --claim-token');\n return heartbeatAgentClaim(claimToken, parseClaimTtl(readOption(args, '--ttl')));\n }\n if (command === 'release') {\n if (!claimToken) throw new Error('lineage agent release requires --claim-token');\n return releaseAgentClaim(claimToken);\n }\n if (command === 'revoke') {\n if (!claimId) throw new Error('lineage agent revoke requires --claim');\n return revokeAgentClaim(project, claimId, {\n actor: readOption(args, '--actor') || 'human',\n confirmWrite: args.includes('--confirm-write'),\n reason: readOption(args, '--reason'),\n });\n }\n if (command === 'transfer') {\n if (!claimId) throw new Error('lineage agent transfer requires --claim');\n return transferAgentClaim(project, claimId, {\n actor: readOption(args, '--actor') || 'human',\n confirmWrite: args.includes('--confirm-write'),\n reason: readOption(args, '--reason'),\n toAgentName: readOption(args, '--to-agent-name') || '',\n });\n }\n throw new Error(`Unknown agent command: ${command}`);\n}\n\nfunction printAgentResult(command: string, result: unknown, json: boolean): void {\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n if (command === 'claim' && result && typeof result === 'object' && 'claim' in result) {\n const created = result as { claim?: { id: string; target_id: string }; claim_token?: string };\n console.log(`Claimed ${created.claim?.target_id || 'target'} as ${created.claim?.id || 'claim'}`);\n if (created.claim_token) console.log(`Token: ${created.claim_token}`);\n return;\n }\n if (command === 'status' && result && typeof result === 'object' && 'claims' in result) {\n const status = result as { claims: Array<{ agent_name: string; derived_state: string; target_id: string }> };\n if (status.claims.length === 0) {\n console.log('No agent claims.');\n return;\n }\n for (const claim of status.claims) console.log(`${claim.agent_name} ${claim.derived_state} ${claim.target_id}`);\n return;\n }\n if (result && typeof result === 'object' && 'claim' in result) {\n const inspected = result as { claim?: { id: string; status: string; target_id: string } };\n console.log(`${inspected.claim?.id || 'claim'} ${inspected.claim?.status || 'unknown'} ${inspected.claim?.target_id || ''}`.trim());\n return;\n }\n console.log(String(result));\n}\n\nfunction start(config: LineageCliConfig, args: string[]): void {\n let options: StartOptions;\n const json = args.includes('--json');\n try {\n options = resolveStartOptions(config, args);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (json) console.error(JSON.stringify({ ok: false, error: message }, null, 2));\n else console.error(`${config.binName}: ${message}`);\n process.exit(1);\n }\n const serverPath = join(packageRoot(), 'dist', 'server.js');\n if (!existsSync(serverPath)) {\n const message = `Missing bundled server at ${serverPath}. Run npm run build before using ${config.binName} start from a source checkout.`;\n if (options.json) console.error(JSON.stringify({ ok: false, error: message }, null, 2));\n else console.error(`${config.binName}: ${message}`);\n process.exit(1);\n }\n\n mkdirSync(dirname(options.dbPath), { recursive: true });\n const url = `http://${options.host}:${options.port}`;\n if (options.json) {\n console.log(JSON.stringify({ channel: config.channel, dbPath: options.dbPath, host: options.host, port: options.port, status: 'starting', url }, null, 2));\n } else {\n console.log(`${config.displayName} starting at ${url}`);\n console.log(`SQLite: ${options.dbPath}`);\n }\n if (options.open) openBrowser(url);\n\n const child = spawn(process.execPath, [serverPath], {\n env: {\n ...process.env,\n HOST: options.host,\n LINEAGE_CHANNEL: config.channel,\n LINEAGE_DB: options.dbPath,\n NODE_ENV: 'production',\n PORT: String(options.port),\n },\n stdio: 'inherit',\n });\n\n let forwardedSignal: NodeJS.Signals | undefined;\n const stop = (signal: NodeJS.Signals) => {\n forwardedSignal = signal;\n child.kill(signal);\n };\n process.once('SIGINT', stop);\n process.once('SIGTERM', stop);\n child.on('exit', code => process.exit(code ?? (forwardedSignal ? signalExitCodes[forwardedSignal] || 1 : 0)));\n child.on('error', error => {\n console.error(`${config.binName}: failed to start server: ${error.message}`);\n process.exit(1);\n });\n}\n\nexport function runLineageCli(config: LineageCliConfig, args = process.argv.slice(2)): void {\n if (args.includes('--help') || args.includes('-h') || args.length === 0) {\n printHelp(config);\n process.exit(0);\n }\n\n if (args.includes('--version') || args.includes('-v')) {\n console.log(packageVersion());\n process.exit(0);\n }\n\n const normalizedArgs = args[0] === 'lineage' ? args.slice(1) : args;\n const [command] = normalizedArgs;\n if (command === 'start') {\n start(config, normalizedArgs.slice(1));\n return;\n }\n\n if (command === 'next' || command === 'brief' || command === 'inspect' || command === 'link-child') {\n const commandArgs = normalizedArgs.slice(1);\n const json = commandArgs.includes('--json');\n try {\n printDataResult(command, runLineageDataCommand(command, commandArgs), json);\n } catch (error) {\n const message = redactAgentClaimTokens(error instanceof Error ? error.message : String(error));\n if (json) {\n const output = isAgentClaimError(error)\n ? { ok: false, command, error: error.code, message, conflicts: error.conflicts }\n : { ok: false, command, error: message };\n console.error(JSON.stringify(output, null, 2));\n }\n else console.error(`${config.binName}: ${message}`);\n process.exit(1);\n }\n process.exit(0);\n }\n\n if (command === 'agent') {\n const commandArgs = normalizedArgs.slice(2);\n const agentCommand = normalizedArgs[1] || '';\n const json = commandArgs.includes('--json');\n try {\n printAgentResult(agentCommand, runLineageAgentCommand(agentCommand, commandArgs), json);\n } catch (error) {\n const message = redactAgentClaimTokens(error instanceof Error ? error.message : String(error));\n if (json) {\n const output = isAgentClaimError(error)\n ? { ok: false, command: `agent ${agentCommand}`, error: error.code, message, conflicts: error.conflicts }\n : { ok: false, command: `agent ${agentCommand}`, error: message };\n console.error(JSON.stringify(output, null, 2));\n } else {\n console.error(`${config.binName}: ${message}`);\n }\n process.exit(1);\n }\n process.exit(0);\n }\n\n const json = args.includes('--json');\n const message = `Unknown command: ${command}`;\n if (json) console.error(JSON.stringify({ ok: false, command, error: message }, null, 2));\n else console.error(`${config.binName}: ${message}`);\n process.exit(1);\n}\n", "import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';\nimport { lineageDb, nowIso, type DatabaseSync } from './assetLineageDb';\n\nexport type AgentClaimScopeType = 'lineage_workspace' | 'content_post' | 'content_queue_lane' | 'selection_set' | 'project_channel';\ntype AgentClaimStatus = 'active' | 'expired' | 'released' | 'revoked' | 'transferred';\n\nexport interface AgentClaim {\n id: string;\n project: string;\n channel?: string;\n scope_type: AgentClaimScopeType;\n target_id: string;\n target_title?: string;\n agent_id?: string;\n agent_name: string;\n agent_kind: string;\n thread_id?: string;\n status: AgentClaimStatus;\n created_at: string;\n heartbeat_at: string;\n expires_at: string;\n released_at?: string;\n revoked_at?: string;\n revoked_by?: string;\n override_reason?: string;\n metadata?: Record<string, unknown>;\n heartbeat_age_seconds: number;\n derived_state: 'active' | 'idle' | 'stale' | 'expired';\n}\n\ninterface AgentClaimEvent {\n claim_id: string;\n event_type: string;\n actor?: string;\n message?: string;\n created_at: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CreateAgentClaimFields {\n project: string;\n channel?: string;\n scopeType: AgentClaimScopeType;\n targetId: string;\n targetTitle?: string;\n agentId?: string;\n agentName: string;\n agentKind?: string;\n threadId?: string;\n ttlSeconds?: number;\n force?: boolean;\n reason?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ValidateAgentClaimForWriteFields {\n claimToken?: string;\n project: string;\n channel?: string;\n scopeType: AgentClaimScopeType;\n targetId: string;\n writeKind: string;\n dangerLevel: 'claim' | 'warn' | 'enforce' | 'danger';\n confirmWrite?: boolean;\n}\n\nexport type AgentClaimValidationResult =\n | { ok: true; claim: AgentClaim; warnings: string[] }\n | { ok: false; code: string; message: string; conflicts: AgentClaim[] };\n\ntype Row = Record<string, unknown>;\n\nconst defaultTtlSeconds = 20 * 60;\nconst idleAfterSeconds = 5 * 60;\nconst staleAfterSeconds = 15 * 60;\nconst scopes = new Set<AgentClaimScopeType>(['lineage_workspace', 'content_post', 'content_queue_lane', 'selection_set', 'project_channel']);\nconst claimTokenPattern = /claim_[a-z0-9_-]+\\.[A-Za-z0-9_-]+/g;\n\nexport class AgentClaimError extends Error {\n constructor(message: string, public status = 400, public code = 'agent_claim_error', public conflicts: AgentClaim[] = []) {\n super(message);\n }\n}\n\nexport function isAgentClaimError(error: unknown): error is AgentClaimError {\n return error instanceof AgentClaimError;\n}\n\nexport function redactAgentClaimTokens(input: string): string {\n return input.replace(claimTokenPattern, '[redacted-claim-token]');\n}\n\nexport function parseClaimTtl(value?: string): number {\n if (!value) return defaultTtlSeconds;\n const match = value.trim().match(/^(\\d+)(s|m|h)?$/);\n if (!match) throw new AgentClaimError(`Invalid claim ttl: ${value}`);\n const amount = Number(match[1]);\n const unit = match[2] || 's';\n const multiplier = unit === 'h' ? 3600 : unit === 'm' ? 60 : 1;\n const seconds = amount * multiplier;\n if (!Number.isInteger(seconds) || seconds < 30 || seconds > 24 * 60 * 60) {\n throw new AgentClaimError('Claim ttl must be between 30 seconds and 24 hours');\n }\n return seconds;\n}\n\nfunction randomId(prefix: string): string {\n return `${prefix}_${Date.now().toString(36)}_${randomBytes(6).toString('base64url').toLowerCase()}`;\n}\n\nfunction tokenHash(token: string): string {\n return createHash('sha256').update(token).digest('hex');\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const left = Buffer.from(a);\n const right = Buffer.from(b);\n return left.length === right.length && timingSafeEqual(left, right);\n}\n\nfunction expiresAtFrom(timestamp: string, ttlSeconds: number): string {\n return new Date(new Date(timestamp).getTime() + ttlSeconds * 1000).toISOString();\n}\n\nfunction metadataJson(metadata?: Record<string, unknown>): string | null {\n return metadata ? JSON.stringify(metadata) : null;\n}\n\nfunction parseMetadata(value: unknown): Record<string, unknown> | undefined {\n if (typeof value !== 'string' || !value) return undefined;\n try {\n const parsed = JSON.parse(value) as unknown;\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed as Record<string, unknown> : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction derivedState(row: { status: AgentClaimStatus; heartbeat_at: string; expires_at: string }, now = new Date()): AgentClaim['derived_state'] {\n if (row.status !== 'active') return row.status === 'expired' ? 'expired' : 'stale';\n if (new Date(row.expires_at).getTime() <= now.getTime()) return 'expired';\n const ageSeconds = Math.max(0, Math.floor((now.getTime() - new Date(row.heartbeat_at).getTime()) / 1000));\n if (ageSeconds >= staleAfterSeconds) return 'stale';\n if (ageSeconds >= idleAfterSeconds) return 'idle';\n return 'active';\n}\n\nfunction rowToClaim(row: Row, now = new Date()): AgentClaim {\n const heartbeatAt = String(row.heartbeat_at);\n return {\n id: String(row.id),\n project: String(row.project_id),\n channel: typeof row.channel === 'string' ? row.channel : undefined,\n scope_type: String(row.scope_type) as AgentClaimScopeType,\n target_id: String(row.target_id),\n target_title: typeof row.target_title === 'string' ? row.target_title : undefined,\n agent_id: typeof row.agent_id === 'string' ? row.agent_id : undefined,\n agent_name: String(row.agent_name),\n agent_kind: String(row.agent_kind),\n thread_id: typeof row.thread_id === 'string' ? row.thread_id : undefined,\n status: String(row.status) as AgentClaimStatus,\n created_at: String(row.created_at),\n heartbeat_at: heartbeatAt,\n expires_at: String(row.expires_at),\n released_at: typeof row.released_at === 'string' ? row.released_at : undefined,\n revoked_at: typeof row.revoked_at === 'string' ? row.revoked_at : undefined,\n revoked_by: typeof row.revoked_by === 'string' ? row.revoked_by : undefined,\n override_reason: typeof row.override_reason === 'string' ? row.override_reason : undefined,\n metadata: parseMetadata(row.metadata_json),\n heartbeat_age_seconds: Math.max(0, Math.floor((now.getTime() - new Date(heartbeatAt).getTime()) / 1000)),\n derived_state: derivedState({\n expires_at: String(row.expires_at),\n heartbeat_at: heartbeatAt,\n status: String(row.status) as AgentClaimStatus,\n }, now),\n };\n}\n\nfunction eventToRow(row: Row): AgentClaimEvent {\n return {\n claim_id: String(row.claim_id),\n event_type: String(row.event_type),\n actor: typeof row.actor === 'string' ? row.actor : undefined,\n message: typeof row.message === 'string' ? row.message : undefined,\n created_at: String(row.created_at),\n metadata: parseMetadata(row.metadata_json),\n };\n}\n\nfunction ensureProject(database: DatabaseSync, project: string): void {\n const timestamp = nowIso();\n database.prepare(`\n insert into projects (id, product, created_at, updated_at)\n values (?, ?, ?, ?)\n on conflict(id) do update set product = excluded.product, updated_at = excluded.updated_at\n `).run(project, project, timestamp, timestamp);\n}\n\nfunction recordEvent(database: DatabaseSync, claimId: string, eventType: string, actor?: string, message?: string, metadata?: Record<string, unknown>): void {\n database.prepare(`\n insert into agent_claim_events (id, claim_id, event_type, actor, message, created_at, metadata_json)\n values (?, ?, ?, ?, ?, ?, ?)\n `).run(randomId('claim_event'), claimId, eventType, actor || null, message || null, nowIso(), metadataJson(metadata));\n}\n\nfunction expireActiveClaims(database: DatabaseSync): void {\n const timestamp = nowIso();\n const expired = database.prepare(`\n select id from agent_claims where status = 'active' and expires_at <= ?\n `).all(timestamp) as Array<{ id: string }>;\n if (expired.length === 0) return;\n database.prepare(`\n update agent_claims set status = 'expired' where status = 'active' and expires_at <= ?\n `).run(timestamp);\n for (const claim of expired) recordEvent(database, claim.id, 'expired', 'system', 'Claim expired after missed heartbeat.');\n}\n\nfunction normalizeScope(scopeType: AgentClaimScopeType): AgentClaimScopeType {\n if (!scopes.has(scopeType)) throw new AgentClaimError(`Unsupported claim scope: ${scopeType}`);\n return scopeType;\n}\n\nfunction channelOverlaps(left?: string, right?: string): boolean {\n return !left || !right || left === right;\n}\n\nfunction claimOverlaps(candidate: Pick<AgentClaim, 'project' | 'channel' | 'scope_type' | 'target_id'>, existing: AgentClaim): boolean {\n if (candidate.project !== existing.project) return false;\n if (!channelOverlaps(candidate.channel, existing.channel)) return false;\n if (candidate.scope_type === existing.scope_type && candidate.target_id === existing.target_id) return true;\n return candidate.scope_type === 'project_channel' || existing.scope_type === 'project_channel';\n}\n\nfunction activeClaims(database: DatabaseSync, project?: string): AgentClaim[] {\n const rows = project\n ? database.prepare(\"select * from agent_claims where project_id = ? and status = 'active' order by heartbeat_at desc\").all(project)\n : database.prepare(\"select * from agent_claims where status = 'active' order by project_id, heartbeat_at desc\").all();\n return (rows as Row[]).map(row => rowToClaim(row));\n}\n\nfunction findClaimById(database: DatabaseSync, claimId: string, project?: string): AgentClaim | null {\n const row = project\n ? database.prepare('select * from agent_claims where project_id = ? and id = ?').get(project, claimId)\n : database.prepare('select * from agent_claims where id = ?').get(claimId);\n return row ? rowToClaim(row as Row) : null;\n}\n\nfunction findClaimRowByToken(database: DatabaseSync, claimToken: string): Row | null {\n const claimId = claimToken.split('.')[0];\n const row = database.prepare('select * from agent_claims where id = ?').get(claimId) as Row | undefined;\n if (!row) return null;\n return safeEqual(String(row.token_hash), tokenHash(claimToken)) ? row : null;\n}\n\nfunction denied(code: string, message: string, conflicts: AgentClaim[] = []): AgentClaimValidationResult {\n return { ok: false, code, message, conflicts };\n}\n\nfunction scopeAllowsWrite(claim: AgentClaim, scopeType: AgentClaimScopeType, targetId: string, writeKind: string): boolean {\n if (claim.scope_type === scopeType && claim.target_id === targetId) return true;\n if (claim.scope_type === 'project_channel') return true;\n if (claim.scope_type === 'lineage_workspace' && scopeType === 'lineage_workspace') return claim.target_id === targetId;\n if (claim.scope_type === 'content_queue_lane' && writeKind === 'content_queue_next') return true;\n return false;\n}\n\nexport function createAgentClaim(fields: CreateAgentClaimFields) {\n const project = fields.project.trim();\n const targetId = fields.targetId.trim();\n const agentName = fields.agentName.trim();\n if (!project) throw new AgentClaimError('Agent claim requires project');\n if (!targetId) throw new AgentClaimError('Agent claim requires target');\n if (!agentName) throw new AgentClaimError('Agent claim requires agent name');\n const scopeType = normalizeScope(fields.scopeType);\n const ttlSeconds = fields.ttlSeconds || defaultTtlSeconds;\n const database = lineageDb();\n try {\n ensureProject(database, project);\n expireActiveClaims(database);\n const candidate = { project, channel: fields.channel?.trim() || undefined, scope_type: scopeType, target_id: targetId };\n const conflicts = activeClaims(database, project).filter(claim => claimOverlaps(candidate, claim));\n if (conflicts.length > 0 && !fields.force) {\n throw new AgentClaimError('Target already has an active overlapping agent claim.', 409, 'target_already_claimed', conflicts);\n }\n if (conflicts.length > 0 && !fields.reason?.trim()) {\n throw new AgentClaimError('Overriding an active claim requires --reason.', 400, 'override_reason_required', conflicts);\n }\n const timestamp = nowIso();\n for (const conflict of conflicts) {\n database.prepare(`\n update agent_claims\n set status = 'revoked', revoked_at = ?, revoked_by = ?, override_reason = ?\n where id = ? and status = 'active'\n `).run(timestamp, agentName, fields.reason || null, conflict.id);\n recordEvent(database, conflict.id, 'revoked', agentName, fields.reason || 'Revoked by forced claim takeover.');\n recordEvent(database, conflict.id, 'conflict', agentName, `Overridden by ${agentName}.`, { new_claim_target: targetId });\n }\n const id = randomId('claim');\n const secret = randomBytes(24).toString('base64url');\n const claimToken = `${id}.${secret}`;\n const expiresAt = expiresAtFrom(timestamp, ttlSeconds);\n database.prepare(`\n insert into agent_claims (\n id, token_hash, project_id, channel, scope_type, target_id, target_title, agent_id, agent_name,\n agent_kind, thread_id, status, created_at, heartbeat_at, expires_at, metadata_json\n ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?, ?)\n `).run(\n id,\n tokenHash(claimToken),\n project,\n candidate.channel || null,\n scopeType,\n targetId,\n fields.targetTitle?.trim() || null,\n fields.agentId?.trim() || null,\n agentName,\n fields.agentKind?.trim() || 'codex',\n fields.threadId?.trim() || null,\n timestamp,\n timestamp,\n expiresAt,\n metadataJson(fields.metadata)\n );\n recordEvent(database, id, 'created', agentName, `Claimed ${scopeType} ${targetId}.`, { ttl_seconds: ttlSeconds });\n const claim = findClaimById(database, id);\n return { ok: true as const, claim, claim_token: claimToken, conflicts_revoked: conflicts.map(conflict => conflict.id) };\n } finally {\n database.close();\n }\n}\n\nexport function listAgentClaims(project?: string) {\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const rows = project\n ? database.prepare('select * from agent_claims where project_id = ? order by status, heartbeat_at desc').all(project)\n : database.prepare('select * from agent_claims order by project_id, status, heartbeat_at desc').all();\n return { ok: true as const, claims: (rows as Row[]).map(row => rowToClaim(row)), fetchedAt: nowIso() };\n } finally {\n database.close();\n }\n}\n\nexport function inspectAgentClaim(claimId: string, project?: string) {\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const claim = findClaimById(database, claimId, project);\n if (!claim) throw new AgentClaimError(`Unknown agent claim: ${claimId}`, 404, 'claim_not_found');\n const events = database.prepare('select * from agent_claim_events where claim_id = ? order by created_at').all(claim.id) as Row[];\n return { ok: true as const, claim, events: events.map(eventToRow) };\n } finally {\n database.close();\n }\n}\n\nexport function heartbeatAgentClaim(claimToken: string, ttlSeconds = defaultTtlSeconds) {\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const row = findClaimRowByToken(database, claimToken);\n if (!row) throw new AgentClaimError('Unknown or invalid agent claim token.', 401, 'claim_token_invalid');\n const claim = rowToClaim(row);\n if (claim.status !== 'active') throw new AgentClaimError(`Agent claim is ${claim.status}.`, 409, 'claim_not_active');\n const timestamp = nowIso();\n database.prepare('update agent_claims set heartbeat_at = ?, expires_at = ? where id = ?').run(timestamp, expiresAtFrom(timestamp, ttlSeconds), claim.id);\n recordEvent(database, claim.id, 'heartbeat', claim.agent_name, 'Claim heartbeat received.');\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function releaseAgentClaim(claimToken: string) {\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const row = findClaimRowByToken(database, claimToken);\n if (!row) throw new AgentClaimError('Unknown or invalid agent claim token.', 401, 'claim_token_invalid');\n const claim = rowToClaim(row);\n if (claim.status !== 'active') throw new AgentClaimError(`Agent claim is ${claim.status}.`, 409, 'claim_not_active');\n const timestamp = nowIso();\n database.prepare(\"update agent_claims set status = 'released', released_at = ? where id = ?\").run(timestamp, claim.id);\n recordEvent(database, claim.id, 'released', claim.agent_name, 'Claim released by token holder.');\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function releaseStaleAgentClaim(project: string, claimId: string, fields: { actor?: string; confirmWrite: boolean; reason?: string }) {\n if (!fields.confirmWrite) throw new AgentClaimError('Releasing a stale agent claim requires confirmWrite=true.', 400, 'confirm_write_required');\n if (!fields.reason?.trim()) throw new AgentClaimError('Releasing a stale agent claim requires a reason.', 400, 'reason_required');\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const claim = findClaimById(database, claimId, project);\n if (!claim) throw new AgentClaimError(`Unknown agent claim: ${claimId}`, 404, 'claim_not_found');\n if (claim.status !== 'active' || claim.derived_state !== 'stale') {\n throw new AgentClaimError('Only stale active claims can be released without the claim token.', 409, 'claim_not_stale', [claim]);\n }\n const timestamp = nowIso();\n database.prepare(\"update agent_claims set status = 'released', released_at = ?, revoked_by = ?, override_reason = ? where id = ?\").run(timestamp, fields.actor || 'human', fields.reason, claim.id);\n recordEvent(database, claim.id, 'released', fields.actor || 'human', fields.reason);\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function revokeAgentClaim(project: string, claimId: string, fields: { actor?: string; confirmWrite: boolean; reason?: string }) {\n if (!fields.confirmWrite) throw new AgentClaimError('Revoking an agent claim requires confirmWrite=true.', 400, 'confirm_write_required');\n if (!fields.reason?.trim()) throw new AgentClaimError('Revoking an agent claim requires a reason.', 400, 'reason_required');\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const claim = findClaimById(database, claimId, project);\n if (!claim) throw new AgentClaimError(`Unknown agent claim: ${claimId}`, 404, 'claim_not_found');\n const timestamp = nowIso();\n database.prepare(`\n update agent_claims set status = 'revoked', revoked_at = ?, revoked_by = ?, override_reason = ?\n where id = ?\n `).run(timestamp, fields.actor || 'human', fields.reason, claim.id);\n recordEvent(database, claim.id, 'revoked', fields.actor || 'human', fields.reason);\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function transferAgentClaim(project: string, claimId: string, fields: { confirmWrite: boolean; toAgentName: string; actor?: string; reason?: string }) {\n if (!fields.confirmWrite) throw new AgentClaimError('Transferring an agent claim requires confirmWrite=true.', 400, 'confirm_write_required');\n const toAgentName = fields.toAgentName.trim();\n if (!toAgentName) throw new AgentClaimError('Transfer requires toAgentName.', 400, 'agent_name_required');\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const claim = findClaimById(database, claimId, project);\n if (!claim) throw new AgentClaimError(`Unknown agent claim: ${claimId}`, 404, 'claim_not_found');\n if (claim.status !== 'active') throw new AgentClaimError(`Agent claim is ${claim.status}.`, 409, 'claim_not_active');\n database.prepare('update agent_claims set agent_name = ? where id = ?').run(toAgentName, claim.id);\n recordEvent(database, claim.id, 'transferred', fields.actor || 'human', fields.reason || `Transferred claim to ${toAgentName}.`, { to_agent_name: toAgentName });\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function validateAgentClaimForWrite(fields: ValidateAgentClaimForWriteFields): AgentClaimValidationResult {\n if (fields.dangerLevel === 'danger' && !fields.confirmWrite) {\n return denied('human_confirmation_required', 'Dangerous write requires explicit human confirmation.');\n }\n if (!fields.claimToken) return denied('claim_required', 'Mutating agent write requires a matching claim token.');\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const row = findClaimRowByToken(database, fields.claimToken);\n if (!row) return denied('claim_token_invalid', 'Unknown or invalid claim token.');\n const claim = rowToClaim(row);\n if (claim.status !== 'active') return denied('claim_not_active', `Agent claim is ${claim.status}.`);\n if (new Date(claim.expires_at).getTime() <= Date.now()) return denied('claim_expired', 'Agent claim has expired.');\n if (claim.project !== fields.project) return denied('claim_project_mismatch', `Claim project ${claim.project} does not match ${fields.project}.`, [claim]);\n if (fields.channel && claim.channel && claim.channel !== fields.channel) {\n return denied('claim_channel_mismatch', `Claim channel ${claim.channel} does not match ${fields.channel}.`, [claim]);\n }\n if (!scopeAllowsWrite(claim, fields.scopeType, fields.targetId, fields.writeKind)) {\n return denied('claim_scope_mismatch', `Claim does not cover ${fields.scopeType} ${fields.targetId}.`, [claim]);\n }\n recordEvent(database, claim.id, 'write_allowed', claim.agent_name, `${fields.writeKind} allowed.`, {\n danger_level: fields.dangerLevel,\n target_id: fields.targetId,\n write_kind: fields.writeKind,\n });\n return { ok: true, claim, warnings: [] };\n } finally {\n database.close();\n }\n}\n", "import { createRequire } from 'node:module';\nimport type { DatabaseSync as DatabaseSyncType } from 'node:sqlite';\nimport { mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { repoRoot } from './assetCore';\n\nconst require = createRequire(import.meta.url);\nexport type DatabaseSync = DatabaseSyncType;\n\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n\nexport function lineageDbPath(): string {\n return process.env.LINEAGE_DB || join(repoRoot, '.lineage', 'asset-lineage.sqlite');\n}\n\nexport function lineageDb(): DatabaseSync {\n mkdirSync(join(lineageDbPath(), '..'), { recursive: true });\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const database = new DatabaseSync(lineageDbPath());\n database.exec('PRAGMA foreign_keys = ON'); database.exec('PRAGMA busy_timeout = 5000');\n database.exec(`\n create table if not exists projects (\n id text primary key,\n product text not null,\n catalog_path text,\n created_at text not null,\n updated_at text not null\n );\n create table if not exists assets (\n id text primary key,\n project_id text not null references projects(id),\n source text not null check (source in ('local', 'catalog')),\n local_path text,\n s3_key text,\n checksum_sha256 text,\n media_type text not null,\n title text not null,\n status text not null,\n channel text,\n campaign text,\n audience text,\n size_bytes integer,\n content_type text,\n created_at text not null,\n updated_at text not null,\n last_seen_at text not null\n );\n create index if not exists assets_project_source_seen on assets(project_id, source, last_seen_at);\n create index if not exists assets_project_checksum on assets(project_id, checksum_sha256);\n create index if not exists assets_project_channel_campaign on assets(project_id, channel, campaign);\n create table if not exists asset_edges (\n id text primary key,\n project_id text not null references projects(id),\n parent_asset_id text not null references assets(id),\n child_asset_id text not null references assets(id),\n relation_type text not null check (relation_type in ('derived_from')),\n created_at text not null,\n unique (project_id, parent_asset_id, child_asset_id, relation_type)\n );\n create index if not exists edges_parent on asset_edges(project_id, parent_asset_id);\n create index if not exists edges_child on asset_edges(project_id, child_asset_id);\n create table if not exists asset_reviews (\n asset_id text primary key references assets(id),\n review_state text not null check (review_state in ('unreviewed', 'approved', 'needs_revision', 'rejected', 'ignored')),\n reviewed_at text,\n ignored_at text,\n notes text,\n updated_at text not null\n );\n create table if not exists asset_selections (\n id text primary key,\n project_id text not null references projects(id),\n root_asset_id text not null references assets(id),\n asset_id text not null references assets(id),\n notes text,\n selected_at text not null,\n unique(project_id, root_asset_id)\n );\n create table if not exists asset_layouts (\n id text primary key,\n project_id text not null references projects(id),\n root_asset_id text not null references assets(id),\n asset_id text not null references assets(id),\n x real not null,\n y real not null,\n updated_at text not null,\n unique(project_id, root_asset_id, asset_id)\n );\n create table if not exists lineage_workspaces (\n id text primary key,\n project_id text not null references projects(id),\n root_asset_id text not null references assets(id),\n title text not null,\n status text not null check (status in ('active', 'paused', 'archived')),\n notes text,\n created_by text not null check (created_by in ('human', 'agent', 'system')),\n active_at text,\n created_at text not null,\n updated_at text not null,\n unique(project_id, root_asset_id)\n );\n create index if not exists lineage_workspaces_project_status on lineage_workspaces(project_id, status, updated_at);\n create index if not exists lineage_workspaces_project_active on lineage_workspaces(project_id, active_at);\n create table if not exists asset_ledger_records (\n id text primary key,\n project_id text not null references projects(id),\n canonical_asset_id text not null,\n checksum_sha256 text,\n media_type text not null,\n title text not null,\n status text not null,\n channel text,\n campaign text,\n audience text,\n created_at text not null,\n updated_at text not null,\n first_seen_at text not null default (datetime('now')),\n last_seen_at text not null\n );\n create index if not exists asset_ledger_records_project_seen on asset_ledger_records(project_id, last_seen_at);\n create index if not exists asset_ledger_records_project_checksum on asset_ledger_records(project_id, checksum_sha256);\n create table if not exists asset_ledger_sources (\n id text primary key,\n project_id text not null references projects(id),\n record_id text not null references asset_ledger_records(id) on delete cascade,\n source_type text not null check (source_type in ('local', 'catalog', 's3')),\n asset_id text,\n local_path text,\n s3_bucket text,\n s3_region text,\n s3_key text,\n s3_version_id text,\n etag text,\n size_bytes integer,\n content_type text,\n updated_at text,\n first_seen_at text not null default (datetime('now')),\n last_seen_at text not null\n );\n create index if not exists asset_ledger_sources_project_type on asset_ledger_sources(project_id, source_type);\n create index if not exists asset_ledger_sources_record on asset_ledger_sources(project_id, record_id);\n create index if not exists asset_ledger_sources_s3_key on asset_ledger_sources(project_id, s3_key);\n create table if not exists asset_ledger_placements (\n id text primary key,\n project_id text not null references projects(id),\n asset_id text not null,\n channel text not null,\n status text not null,\n scheduled_at text,\n posted_at text,\n url text,\n notes text,\n updated_at text not null,\n synced_at text not null,\n unique(project_id, asset_id, channel)\n );\n create index if not exists asset_ledger_placements_project_status on asset_ledger_placements(project_id, status);\n create index if not exists asset_ledger_placements_asset on asset_ledger_placements(project_id, asset_id);\n create table if not exists asset_ledger_index_runs (\n id text primary key,\n project_id text not null references projects(id),\n source_mode text not null check (source_mode in ('all', 'catalog', 'local')),\n include_live_s3 integer not null default 0,\n status text not null check (status in ('running', 'complete', 'failed')),\n started_at text not null,\n completed_at text,\n assets_indexed integer not null default 0,\n records_after integer not null default 0,\n catalog_sources_after integer not null default 0,\n local_sources_after integer not null default 0,\n s3_sources_after integer not null default 0,\n error text\n );\n create index if not exists asset_ledger_index_runs_project_started on asset_ledger_index_runs(project_id, started_at);\n create table if not exists content_batches (\n id text not null,\n project_id text not null references projects(id),\n title text not null,\n campaign text,\n channel text,\n status text not null check (status in ('active', 'archived')),\n notes text,\n created_at text not null,\n updated_at text not null,\n primary key(project_id, id)\n );\n create index if not exists content_batches_project_updated on content_batches(project_id, updated_at);\n create table if not exists content_posts (\n id text not null,\n project_id text not null references projects(id),\n batch_id text not null,\n channel text not null,\n title text not null,\n phase text not null check (phase in ('draft', 'review', 'scheduled', 'posted', 'skipped', 'archived')),\n campaign text,\n body text,\n cta text,\n scheduled_at text,\n posted_at text,\n url text,\n notes text,\n source_path text,\n created_at text not null,\n updated_at text not null,\n primary key(project_id, id),\n foreign key(project_id, batch_id) references content_batches(project_id, id) on delete cascade\n );\n create index if not exists content_posts_project_phase on content_posts(project_id, phase);\n create index if not exists content_posts_batch on content_posts(project_id, batch_id);\n create table if not exists content_post_assets (\n id text primary key,\n project_id text not null references projects(id),\n post_id text not null,\n asset_id text not null,\n role text not null,\n notes text,\n attached_at text not null,\n unique(project_id, post_id, asset_id, role),\n foreign key(project_id, post_id) references content_posts(project_id, id) on delete cascade\n );\n create index if not exists content_post_assets_post on content_post_assets(project_id, post_id);\n create index if not exists content_post_assets_asset on content_post_assets(project_id, asset_id);\n create table if not exists content_targets (\n project_id text primary key references projects(id),\n post_id text not null,\n notes text,\n selected_at text not null,\n updated_at text not null,\n foreign key(project_id, post_id) references content_posts(project_id, id) on delete cascade\n );\n create table if not exists selection_sets (\n id text primary key,\n project_id text not null references projects(id),\n kind text not null check (kind in ('current', 'review')),\n key text not null,\n label text not null,\n status text not null check (status in ('active', 'archived')),\n created_by text not null check (created_by in ('human', 'agent', 'system')),\n created_at text not null,\n updated_at text not null,\n unique(project_id, kind, key)\n );\n create index if not exists selection_sets_project_kind on selection_sets(project_id, kind, updated_at);\n create table if not exists selection_items (\n id text primary key,\n set_id text not null references selection_sets(id) on delete cascade,\n asset_id text not null,\n role text not null check (role in ('primary', 'candidate', 'next_base')),\n variation_label text,\n position integer not null default 0,\n selected_by text check (selected_by in ('human', 'agent', 'system')),\n selected_at text,\n deselected_at text,\n notes text,\n created_at text not null,\n updated_at text not null,\n unique(set_id, asset_id)\n );\n create index if not exists selection_items_set_position on selection_items(set_id, position);\n create unique index if not exists selection_items_set_label on selection_items(set_id, variation_label) where variation_label is not null;\n create table if not exists generation_jobs (\n id text primary key,\n project_id text not null references projects(id),\n provider text not null default 'codex-handoff',\n adapter_version text not null,\n source_mode text not null check (source_mode in ('lineage_selection')),\n root_asset_id text not null references assets(id),\n prompt text not null,\n expected_output_count integer not null check (expected_output_count > 0),\n status text not null check (status in ('planned', 'imported', 'failed', 'cancelled')),\n output_dir text,\n handoff_json text,\n created_at text not null,\n updated_at text not null,\n imported_at text\n );\n create index if not exists generation_jobs_project_created on generation_jobs(project_id, created_at);\n create table if not exists generation_job_inputs (\n id text primary key,\n job_id text not null references generation_jobs(id) on delete cascade,\n project_id text not null references projects(id),\n asset_id text not null references assets(id),\n root_asset_id text not null references assets(id),\n role text not null check (role in ('lineage_next_base', 'reference')),\n position integer not null,\n selection_strategy text not null,\n selection_snapshot_json text not null,\n unique(job_id, asset_id, role)\n );\n create index if not exists generation_job_inputs_job on generation_job_inputs(job_id, position);\n create table if not exists generation_job_outputs (\n id text primary key,\n job_id text not null references generation_jobs(id) on delete cascade,\n project_id text not null references projects(id),\n output_index integer not null,\n file_path text not null,\n checksum_sha256 text not null,\n size_bytes integer not null,\n content_type text not null,\n imported_asset_id text not null references assets(id),\n parent_asset_id text not null references assets(id),\n imported_at text not null,\n unique(job_id, output_index),\n unique(job_id, file_path)\n );\n create index if not exists generation_job_outputs_job on generation_job_outputs(job_id, output_index);\n create table if not exists generation_job_receipts (\n id text primary key,\n job_id text not null references generation_jobs(id) on delete cascade,\n receipt_type text not null check (receipt_type in ('plan', 'import', 'error')),\n status text not null check (status in ('ok', 'error')),\n command text not null,\n payload_json text not null,\n created_at text not null\n );\n create index if not exists generation_job_receipts_job on generation_job_receipts(job_id, created_at);\n create table if not exists adapter_settings (project_id text not null references projects(id), adapter_type text not null check (adapter_type in ('cloud', 'scheduler', 'image_generator')), provider text not null, enabled integer not null check (enabled in (0, 1)), secret_ref text, safe_config_json text not null, created_at text not null, updated_at text not null, primary key(project_id, adapter_type, provider)); create index if not exists adapter_settings_project_type on adapter_settings(project_id, adapter_type);\n create table if not exists agent_claims (\n id text primary key,\n token_hash text not null,\n project_id text not null references projects(id),\n channel text,\n scope_type text not null check (scope_type in ('lineage_workspace', 'content_post', 'content_queue_lane', 'selection_set', 'project_channel')),\n target_id text not null,\n target_title text,\n agent_id text,\n agent_name text not null,\n agent_kind text not null,\n thread_id text,\n status text not null check (status in ('active', 'expired', 'released', 'revoked', 'transferred')),\n created_at text not null,\n heartbeat_at text not null,\n expires_at text not null,\n released_at text,\n revoked_at text,\n revoked_by text,\n override_reason text,\n metadata_json text\n );\n create unique index if not exists agent_claims_token_hash on agent_claims(token_hash);\n create index if not exists agent_claims_project_status on agent_claims(project_id, status, heartbeat_at);\n create index if not exists agent_claims_target on agent_claims(project_id, channel, scope_type, target_id, status);\n create table if not exists agent_claim_events (\n id text primary key,\n claim_id text not null references agent_claims(id) on delete cascade,\n event_type text not null,\n actor text,\n message text,\n created_at text not null,\n metadata_json text\n );\n create index if not exists agent_claim_events_claim_created on agent_claim_events(claim_id, created_at);\n `);\n migrateAssetSelections(database);\n dropLegacyAssetSelectionRootUnique(database);\n ensureColumn(database, 'asset_selections', 'notes', 'text');\n ensureColumn(database, 'asset_ledger_records', 'first_seen_at', 'text');\n ensureColumn(database, 'asset_ledger_records', 'indexed_by_run_id', 'text');\n ensureColumn(database, 'asset_ledger_sources', 'first_seen_at', 'text');\n ensureColumn(database, 'asset_ledger_sources', 'indexed_by_run_id', 'text');\n ensureReviewStateValues(database);\n return database;\n}\n\nfunction ensureColumn(database: DatabaseSync, table: string, column: string, definition: string): void {\n const rows = database.prepare(`pragma table_info(${table})`).all() as Array<{ name: string }>;\n if (!rows.some(row => row.name === column)) database.exec(`alter table ${table} add column ${column} ${definition}`);\n}\n\nfunction migrateAssetSelections(database: DatabaseSync): void {\n const rows = database.prepare('pragma table_info(asset_selections)').all() as Array<{ name: string }>;\n if (rows.some(row => row.name === 'position')) return;\n const notesSelect = rows.some(row => row.name === 'notes') ? 'notes' : 'null';\n\n database.exec(`\n create table if not exists asset_selections_v2 (\n id text primary key,\n project_id text not null references projects(id),\n root_asset_id text not null references assets(id),\n asset_id text not null references assets(id),\n position integer not null default 0,\n notes text,\n selected_at text not null,\n unique(project_id, root_asset_id, asset_id)\n );\n insert or ignore into asset_selections_v2 (id, project_id, root_asset_id, asset_id, position, notes, selected_at)\n select\n project_id || ':' || root_asset_id || ':selected:' || asset_id,\n project_id,\n root_asset_id,\n asset_id,\n 0,\n ${notesSelect},\n selected_at\n from asset_selections;\n drop table asset_selections;\n alter table asset_selections_v2 rename to asset_selections;\n create index if not exists asset_selections_project_root_position\n on asset_selections(project_id, root_asset_id, position, selected_at);\n `);\n}\n\nfunction dropLegacyAssetSelectionRootUnique(database: DatabaseSync): void {\n const indexes = database.prepare('pragma index_list(asset_selections)').all() as Array<{ name: string; unique: number }>;\n for (const index of indexes) {\n if (!index.unique) continue;\n const columns = database.prepare(`pragma index_info(${index.name})`).all() as Array<{ name: string }>;\n const columnNames = columns.map(column => column.name).join(',');\n if (columnNames === 'project_id,root_asset_id') database.exec(`drop index if exists ${index.name}`);\n }\n}\n\nfunction ensureReviewStateValues(database: DatabaseSync): void {\n const createSql = database.prepare(\"select sql from sqlite_master where type = 'table' and name = 'asset_reviews'\").get() as { sql?: string } | undefined;\n if (createSql?.sql?.includes('needs_revision')) return;\n\n database.exec(`\n alter table asset_reviews rename to asset_reviews_old;\n create table asset_reviews (\n asset_id text primary key references assets(id),\n review_state text not null check (review_state in ('unreviewed', 'approved', 'needs_revision', 'rejected', 'ignored')),\n reviewed_at text,\n ignored_at text,\n notes text,\n updated_at text not null\n );\n insert into asset_reviews (asset_id, review_state, reviewed_at, ignored_at, notes, updated_at)\n select asset_id, review_state, reviewed_at, ignored_at, notes, updated_at\n from asset_reviews_old;\n drop table asset_reviews_old;\n `);\n}\n", "import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { spawnSync } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { createS3StorageAdapter } from './adapters/storage';\nimport { listLocalReviewAssets, localPreviewPath as resolveLocalPreviewPath } from './localReview';\nimport { syncLedgerPlacement } from './assetLedgerWorkflow';\nimport { appName } from '../shared/appConstants';\nimport type {\n AssetCatalog,\n AssetContentType,\n AssetFacets,\n DoctorReport,\n AssetLibrarySnapshot,\n GrowthAsset,\n ListAssetsOptions,\n LiveS3Object,\n MutationResponse,\n PlacementFields,\n PlacementStatus,\n PresignResponse,\n ProjectSummary,\n UploadFields,\n} from '../shared/types';\n\nfunction isPackageRoot(path: string): boolean {\n const packageJson = join(path, 'package.json');\n if (!existsSync(packageJson)) return false;\n try {\n const packageInfo = JSON.parse(readFileSync(packageJson, 'utf8')) as { name?: string };\n return packageInfo.name === '@mean-weasel/lineage';\n } catch {\n return false;\n }\n}\n\nfunction resolveRepoRoot(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n process.env.LINEAGE_REPO_ROOT,\n resolve(moduleDir, '..'),\n resolve(moduleDir, '../..'),\n process.cwd(),\n ].filter((candidate): candidate is string => Boolean(candidate));\n const root = candidates.find(isPackageRoot);\n if (!root) throw new Error('Unable to locate Lineage package root');\n return root;\n}\n\nexport const repoRoot = resolveRepoRoot();\nexport const defaultProject = 'demo-project';\nexport const defaultProduct = process.env.LINEAGE_DEFAULT_PRODUCT || defaultProject;\nconst publicFallbackBucket = 'lineage-demo-assets';\nconst publicFallbackRegion = 'us-east-1';\nconst contentTypes = new Set<AssetContentType>(['image', 'video', 'gif', 'audio', 'doc', 'other']);\nconst baseChannels = ['linkedin', 'meta', 'tiktok', 'x-twitter', 'youtube'];\nconst placementStatuses = new Set<PlacementStatus>(['planned', 'scheduled', 'posted', 'skipped']);\nconst projectNamePattern = /^[a-z0-9][a-z0-9-]*$/;\n\ninterface CommandResult {\n stdout: string;\n stderr: string;\n}\n\nclass LineageAssetError extends Error {\n constructor(message: string, public status = 400) {\n super(message);\n }\n}\n\nexport function isLineageAssetError(error: unknown): error is LineageAssetError {\n return error instanceof LineageAssetError;\n}\n\nexport function cleanProject(project = defaultProject): string {\n if (!projectNamePattern.test(project)) {\n throw new LineageAssetError('Project must be lowercase kebab-case');\n }\n return project;\n}\n\nexport function catalogPath(project = defaultProject): string {\n return join(repoRoot, cleanProject(project), 'assets', 'catalog.json');\n}\n\nfunction fixtureCatalogPath(project = defaultProject): string {\n return join(repoRoot, 'fixtures', cleanProject(project), 'assets', 'catalog.json');\n}\n\nfunction resolvedCatalogPath(project = defaultProject): string {\n const path = catalogPath(project);\n if (existsSync(path)) return path;\n const clean = cleanProject(project);\n if (clean === defaultProject && existsSync(fixtureCatalogPath(clean))) return fixtureCatalogPath(clean);\n return path;\n}\n\nexport function normalizeCatalog(catalog: Partial<AssetCatalog>, fallbackProject = defaultProject): AssetCatalog {\n const project = cleanProject(catalog.project || catalog.product || fallbackProject);\n const product = catalog.product || project;\n return {\n ...catalog,\n project,\n product,\n default_bucket: catalog.default_bucket || '',\n default_region: catalog.default_region || '',\n assets: (catalog.assets || []).map(asset => ({\n ...asset,\n source: asset.source || 'catalog',\n project: asset.project || asset.product || project,\n product: asset.product || asset.project || project,\n })),\n };\n}\n\nfunction fallbackS3(assetId: string, channel: string, status = 'working') {\n return {\n bucket: publicFallbackBucket,\n checksum_sha256: undefined,\n content_type: 'image/png',\n key: `products/${defaultProject}/campaigns/2026-06-public-demo/channels/${channel}/audiences/creators/statuses/${status}/types/image/assets/${assetId}/${assetId}.png`,\n region: publicFallbackRegion,\n size_bytes: 2048,\n updated_at: '2026-06-24T12:00:00.000Z',\n version_id: 'public-demo-version',\n };\n}\n\nfunction fallbackAsset(fields: Omit<GrowthAsset, 'audience' | 'campaign' | 'content_type' | 'cta' | 'hook' | 'product' | 'project' | 'source' | 'utm_content'> & {\n audience?: string;\n campaign?: string;\n cta?: string;\n hook?: string;\n utm_content?: string;\n}): GrowthAsset {\n return {\n audience: fields.audience || 'creators',\n campaign: fields.campaign || '2026-06-public-demo',\n content_type: 'image',\n cta: fields.cta || 'Save the idea',\n hook: fields.hook || 'Public demo creative for local review.',\n product: defaultProject,\n project: defaultProject,\n source: 'catalog',\n utm_content: fields.utm_content || fields.asset_id.replace(/-/g, '_'),\n ...fields,\n };\n}\n\nfunction defaultFallbackCatalog(): AssetCatalog {\n return normalizeCatalog({\n assets: [\n fallbackAsset({\n asset_id: 'demo-meta-short-form-upload-demo-post-static',\n channel: 'meta',\n s3: fallbackS3('demo-meta-short-form-upload-demo-post-static', 'meta'),\n status: 'working',\n title: 'Meta short-form demo post static',\n }),\n fallbackAsset({\n asset_id: 'demo-linkedin-ledger-catalog-shared',\n channel: 'linkedin',\n hook: 'Shared ledger creative with catalog metadata.',\n s3: fallbackS3('demo-linkedin-ledger-catalog-shared', 'linkedin'),\n status: 'working',\n title: 'LinkedIn ledger catalog shared',\n }),\n fallbackAsset({\n asset_id: 'demo-linkedin-upload-demo-done-static-grounded-v2',\n channel: 'linkedin',\n placements: [{\n channel: 'linkedin',\n notes: 'Synthetic public scheduled placement.',\n scheduled_at: '2026-06-24T16:00:00-07:00',\n status: 'scheduled',\n updated_at: '2026-06-24T12:30:00.000Z',\n }],\n s3: fallbackS3('demo-linkedin-upload-demo-done-static-grounded-v2', 'linkedin', 'approved'),\n status: 'approved',\n title: 'LinkedIn upload demo scheduled static',\n }),\n fallbackAsset({\n asset_id: 'demo-tiktok-upload-demo-export-vertical',\n channel: 'tiktok',\n format: 'vertical',\n hook: 'Fast vertical demo export for content queue tests.',\n s3: fallbackS3('demo-tiktok-upload-demo-export-vertical', 'tiktok'),\n status: 'working',\n title: 'TikTok upload demo export vertical',\n }),\n fallbackAsset({\n asset_id: 'demo-youtube-short-demo-posted-cut',\n channel: 'youtube',\n placements: [{\n channel: 'youtube',\n notes: 'Synthetic public posted placement.',\n posted_at: '2026-06-25T16:00:00-07:00',\n status: 'posted',\n updated_at: '2026-06-25T17:00:00.000Z',\n }],\n s3: fallbackS3('demo-youtube-short-demo-posted-cut', 'youtube', 'published'),\n status: 'published',\n title: 'YouTube short demo posted cut',\n }),\n fallbackAsset({\n asset_id: 'demo-x-twitter-carousel-demo-working-static',\n channel: 'x-twitter',\n format: 'static',\n s3: fallbackS3('demo-x-twitter-carousel-demo-working-static', 'x-twitter'),\n status: 'working',\n title: 'X Twitter carousel demo working static',\n }),\n ],\n default_bucket: '',\n default_region: '',\n product: defaultProject,\n project: defaultProject,\n }, defaultProject);\n}\n\nfunction isDefaultFallbackCatalog(catalog: AssetCatalog): boolean {\n return catalog.project === defaultProject && !existsSync(catalogPath(defaultProject));\n}\n\nfunction fallbackPreviewDataUrl(asset: GrowthAsset): string {\n const label = `${asset.title}\\n${asset.channel} / ${asset.status}`;\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"675\" viewBox=\"0 0 1200 675\"><rect width=\"1200\" height=\"675\" fill=\"#f7f5ef\"/><rect x=\"56\" y=\"56\" width=\"1088\" height=\"563\" rx=\"18\" fill=\"#10201c\"/><text x=\"96\" y=\"145\" fill=\"#9fe6c8\" font-family=\"Arial, sans-serif\" font-size=\"34\" font-weight=\"700\">Lineage public demo preview</text><text x=\"96\" y=\"230\" fill=\"#fff8e6\" font-family=\"Arial, sans-serif\" font-size=\"56\" font-weight=\"700\">${escapeSvgText(asset.asset_id)}</text><text x=\"96\" y=\"330\" fill=\"#d9e8df\" font-family=\"Arial, sans-serif\" font-size=\"34\">${escapeSvgText(label)}</text><text x=\"96\" y=\"500\" fill=\"#9fb7ae\" font-family=\"Arial, sans-serif\" font-size=\"26\">Synthetic local placeholder. No external storage requested.</text></svg>`;\n return `data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}`;\n}\n\nfunction escapeSvgText(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nexport function loadCatalog(project = defaultProject): AssetCatalog {\n const path = catalogPath(project);\n if (existsSync(path)) {\n try {\n return normalizeCatalog(JSON.parse(readFileSync(path, 'utf8')) as Partial<AssetCatalog>, project);\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {\n throw new LineageAssetError(`Missing catalog: ${path}`, 404);\n }\n throw error;\n }\n }\n const clean = cleanProject(project);\n if (clean === defaultProject) {\n const fixturePath = fixtureCatalogPath(clean);\n if (existsSync(fixturePath)) {\n return normalizeCatalog(JSON.parse(readFileSync(fixturePath, 'utf8')) as Partial<AssetCatalog>, project);\n }\n return defaultFallbackCatalog();\n }\n throw new LineageAssetError(`Missing catalog: ${path}`, 404);\n}\n\nfunction saveCatalog(project: string, catalog: AssetCatalog): AssetCatalog {\n const normalized = normalizeCatalog(catalog, project);\n mkdirSync(dirname(catalogPath(project)), { recursive: true });\n writeFileSync(catalogPath(project), `${JSON.stringify(normalized, null, 2)}\\n`);\n return normalized;\n}\n\nfunction run(command: string, args: string[]): CommandResult {\n const result = spawnSync(command, args, {\n cwd: repoRoot,\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'pipe'],\n env: {\n ...process.env,\n AWS_REGION: process.env.AWS_REGION || 'us-east-1',\n AWS_DEFAULT_REGION: process.env.AWS_DEFAULT_REGION || 'us-east-1',\n },\n });\n\n if (result.status !== 0) {\n const detail = result.stderr.trim() || result.stdout.trim();\n throw new LineageAssetError(`${command} ${args.join(' ')} failed${detail ? `: ${detail}` : ''}`, 502);\n }\n\n return { stdout: result.stdout, stderr: result.stderr };\n}\n\nfunction runAws(args: string[]): CommandResult {\n return run('aws', args);\n}\n\nexport function listProjects(): ProjectSummary[] {\n const projects = readdirSync(repoRoot, { withFileTypes: true })\n .filter(entry => entry.isDirectory() && projectNamePattern.test(entry.name) && existsSync(catalogPath(entry.name)))\n .flatMap(entry => {\n try {\n const catalog = loadCatalog(entry.name);\n return [{ project: catalog.project, product: catalog.product, catalogPath: resolvedCatalogPath(entry.name), default_bucket: catalog.default_bucket, default_region: catalog.default_region, asset_count: catalog.assets.length }];\n } catch (error) {\n if (error instanceof LineageAssetError && error.status === 404) return [];\n throw error;\n }\n })\n .sort((a, b) => a.project.localeCompare(b.project));\n if (!projects.some(item => item.project === defaultProject)) {\n const catalog = loadCatalog(defaultProject);\n projects.push({ project: catalog.project, product: catalog.product, catalogPath: resolvedCatalogPath(defaultProject), default_bucket: catalog.default_bucket, default_region: catalog.default_region, asset_count: catalog.assets.length });\n projects.sort((a, b) => a.project.localeCompare(b.project));\n }\n return projects;\n}\n\nfunction assetById(catalog: AssetCatalog, assetId: string): GrowthAsset {\n const asset = catalog.assets.find(item => item.asset_id === assetId);\n if (!asset) throw new LineageAssetError(`Unknown asset: ${assetId}`, 404);\n return asset;\n}\n\nconst storageAdapter = createS3StorageAdapter({\n assetById,\n cleanProject,\n createError: (message, status) => new LineageAssetError(message, status),\n defaultProject,\n loadCatalog,\n runAws,\n repoRoot,\n saveCatalog,\n supportedContentTypes: contentTypes,\n});\n\nfunction uniqueSorted<T extends string>(values: Array<T | undefined>): T[] {\n return Array.from(new Set(values.filter(Boolean) as T[])).sort();\n}\n\nfunction facetsFor(assets: GrowthAsset[]): AssetFacets {\n return {\n audiences: uniqueSorted(assets.map(asset => asset.audience)),\n campaigns: uniqueSorted(assets.map(asset => asset.campaign)),\n channels: uniqueSorted([...baseChannels, ...assets.map(asset => asset.channel)]),\n contentTypes: uniqueSorted(assets.map(asset => asset.content_type)),\n placementStatuses: uniqueSorted(assets.flatMap(asset => asset.placements?.map(placement => placement.status) || [])),\n statuses: uniqueSorted(assets.map(asset => asset.status)),\n totalSizeBytes: assets.reduce((sum, asset) => sum + (asset.s3?.size_bytes || 0), 0),\n };\n}\n\nfunction filteredAssets(assets: GrowthAsset[], options: ListAssetsOptions): GrowthAsset[] {\n const query = options.query?.trim().toLowerCase();\n return assets.filter(asset => {\n if (options.status && options.status !== 'all' && asset.status !== options.status) return false;\n if (options.channel && options.channel !== 'all' && asset.channel !== options.channel) return false;\n if (options.type && options.type !== 'all' && asset.content_type !== options.type) return false;\n if (options.placementStatus === 'not-posted' && asset.placements?.some(placement => placement.status === 'posted')) return false;\n if (options.placementStatus && !['all', 'not-posted'].includes(options.placementStatus) && !asset.placements?.some(placement => placement.status === options.placementStatus)) return false;\n if (options.campaign && options.campaign !== 'all' && asset.campaign !== options.campaign) return false;\n if (options.audience && options.audience !== 'all' && asset.audience !== options.audience) return false;\n if (!query) return true;\n return [asset.asset_id, asset.title, asset.campaign, asset.channel, asset.audience, asset.hook, asset.cta]\n .join(' ')\n .toLowerCase()\n .includes(query);\n });\n}\n\nexport function listAssets(project = defaultProject, options: ListAssetsOptions = {}): AssetLibrarySnapshot {\n const catalog = loadCatalog(project);\n const pageSize = Math.min(Math.max(Number(options.pageSize || 10), 1), 100);\n const page = Math.max(Number(options.page || 1), 1);\n const localAssets = listLocalReviewAssets(repoRoot, catalog.project, catalog);\n const source = options.source || 'catalog';\n const sourceAssets = source === 'local' ? localAssets : source === 'all' ? [...localAssets, ...catalog.assets] : catalog.assets;\n const filtered = filteredAssets(sourceAssets, options);\n const totalPages = Math.max(Math.ceil(filtered.length / pageSize), 1);\n const safePage = Math.min(page, totalPages);\n const start = (safePage - 1) * pageSize;\n const pageAssets = filtered.slice(start, start + pageSize);\n let liveObjects: LiveS3Object[] = [];\n let error: string | undefined;\n if (options.includeLive && !isDefaultFallbackCatalog(catalog)) {\n try {\n liveObjects = storageAdapter.listLiveObjects(catalog);\n } catch (err) {\n error = err instanceof Error ? err.message : String(err);\n }\n }\n return {\n catalog: { project: catalog.project, product: catalog.product, default_bucket: catalog.default_bucket, default_region: catalog.default_region, asset_count: catalog.assets.length },\n assets: pageAssets,\n facets: facetsFor(catalog.assets),\n pagination: { page: safePage, pageSize, total: filtered.length, totalPages },\n liveObjects,\n orphanObjects: liveObjects.filter(object => !object.cataloged),\n identity: options.includeLive && !isDefaultFallbackCatalog(catalog) ? storageAdapter.getIdentity() : undefined,\n fetchedAt: new Date().toISOString(),\n error,\n };\n}\n\nexport function inspectAsset(project: string, assetId: string): GrowthAsset {\n return assetById(loadCatalog(project), assetId);\n}\n\nexport function validateProject(project = defaultProject): ProjectSummary {\n const catalog = loadCatalog(project);\n return { project: catalog.project, product: catalog.product, catalogPath: resolvedCatalogPath(project), default_bucket: catalog.default_bucket, default_region: catalog.default_region, asset_count: catalog.assets.length };\n}\n\nexport function doctorProject(project = defaultProject, options: { includeLive?: boolean } = {}): DoctorReport {\n const summary = validateProject(project);\n let liveCheck: DoctorReport['liveCheck'] = 'skipped';\n let liveError: string | undefined;\n if (options.includeLive && isDefaultFallbackCatalog(loadCatalog(project))) {\n liveCheck = 'skipped';\n liveError = `${appName} public fallback uses local catalog data only.`;\n } else if (options.includeLive) {\n try {\n storageAdapter.listLiveObjects(loadCatalog(project));\n liveCheck = 'ok';\n } catch (error) {\n liveCheck = 'error';\n liveError = error instanceof Error ? error.message : String(error);\n }\n }\n return { catalogExists: true, deleteEnabled: process.env.LINEAGE_ENABLE_CLOUD_DELETE === 'true', project: summary, liveCheck, liveError };\n}\n\nexport function pullAsset(project: string, assetId: string, out = '.asset-scratch'): MutationResponse {\n return storageAdapter.pullAsset(project, assetId, out);\n}\n\nfunction placementFromFields(fields: PlacementFields) {\n if (!fields.channel) throw new LineageAssetError('Placement requires channel');\n if (!placementStatuses.has(fields.status)) throw new LineageAssetError(`Unsupported placement status: ${fields.status}`);\n const now = new Date().toISOString();\n return {\n channel: fields.channel,\n status: fields.status,\n ...(fields.scheduledAt ? { scheduled_at: fields.scheduledAt } : {}),\n ...(fields.postedAt ? { posted_at: fields.postedAt } : {}),\n ...(fields.url ? { url: fields.url } : {}),\n ...(fields.notes ? { notes: fields.notes } : {}),\n updated_at: now,\n };\n}\n\nexport function previewPlacement(project: string, fields: PlacementFields) {\n const asset = inspectAsset(project, fields.assetId);\n return { asset_id: asset.asset_id, placement: placementFromFields(fields) };\n}\n\nexport function updatePlacement(project: string, fields: PlacementFields): MutationResponse {\n if (!fields.confirmWrite) throw new LineageAssetError('Placement updates require confirmWrite=true');\n const catalog = loadCatalog(project);\n const asset = assetById(catalog, fields.assetId);\n const placement = placementFromFields(fields);\n const existing = asset.placements?.findIndex(item => item.channel === placement.channel);\n if (existing !== undefined && existing >= 0) asset.placements![existing] = placement;\n else asset.placements = [...(asset.placements || []), placement];\n saveCatalog(project, catalog);\n syncLedgerPlacement(project, asset.asset_id, placement);\n return { ok: true, message: `Marked ${asset.asset_id} ${placement.status} for ${placement.channel}`, catalog };\n}\n\nexport function presignAsset(project: string, assetId: string, expiresIn = 900): PresignResponse {\n const catalog = loadCatalog(project);\n if (isDefaultFallbackCatalog(catalog)) {\n const asset = assetById(catalog, assetId);\n return { assetId: asset.asset_id, expiresIn, url: fallbackPreviewDataUrl(asset) };\n }\n return storageAdapter.presignAsset(project, assetId, expiresIn);\n}\n\nexport function localPreviewPath(relativePath: string): string {\n try {\n return resolveLocalPreviewPath(repoRoot, relativePath);\n } catch (error) {\n throw new LineageAssetError(error instanceof Error ? error.message : 'Unknown local review asset', 404);\n }\n}\n\nexport function promoteAsset(project: string, assetId: string, confirmWrite: boolean): MutationResponse {\n return storageAdapter.promoteAsset(project, assetId, confirmWrite);\n}\n\nexport function archiveAsset(project: string, assetId: string, confirmArchive: boolean): MutationResponse {\n if (!confirmArchive) throw new LineageAssetError('Archive requires confirmArchive=true');\n const catalog = loadCatalog(project);\n const asset = assetById(catalog, assetId);\n asset.status = 'archived';\n saveCatalog(project, catalog);\n return { ok: true, message: `Archived ${assetId}`, catalog };\n}\n\nexport function uploadAsset(file: string, fields: UploadFields): MutationResponse {\n return storageAdapter.uploadAsset(file, fields);\n}\n\nexport function deleteObjectGuarded(project: string, assetId: string, confirmation: string): MutationResponse {\n return storageAdapter.deleteObjectGuarded(project, assetId, confirmation);\n}\n\nexport function ensureUploadDir(): string {\n const dir = join(repoRoot, '.asset-scratch', 'studio-uploads');\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nexport function cleanupUploadedTemp(file?: string): void {\n if (!file) return;\n const uploadRoot = ensureUploadDir();\n const resolved = resolve(file);\n if (resolved.startsWith(`${uploadRoot}/`) && existsSync(resolved)) {\n unlinkSync(resolved);\n }\n}\n", "import { copyFileSync, existsSync, mkdirSync, statSync } from 'node:fs';\nimport { basename, dirname, join } from 'node:path';\nimport { contentTypeFor, fileSha256 } from '../../localReview';\nimport type { AssetCatalog, LiveS3Object, MutationResponse, PresignResponse } from '../../../shared/types';\nimport type { StorageAdapter, StorageAdapterDependencies } from './types';\n\nexport function parseAssetIdFromS3Key(key: string): string | undefined {\n const marker = '/assets/';\n const index = key.indexOf(marker);\n if (index === -1) return undefined;\n return key.slice(index + marker.length).split('/')[0];\n}\n\nfunction previewDataUrl(asset: { asset_id: string; channel?: string; status?: string; title?: string }): string {\n const title = asset.title || asset.asset_id;\n const label = `${asset.channel || 'catalog'} / ${asset.status || 'working'}`;\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"675\" viewBox=\"0 0 1200 675\"><rect width=\"1200\" height=\"675\" fill=\"#f7f5ef\"/><rect x=\"56\" y=\"56\" width=\"1088\" height=\"563\" rx=\"18\" fill=\"#10201c\"/><text x=\"96\" y=\"145\" fill=\"#9fe6c8\" font-family=\"Arial, sans-serif\" font-size=\"34\" font-weight=\"700\">Lineage catalog preview</text><text x=\"96\" y=\"230\" fill=\"#fff8e6\" font-family=\"Arial, sans-serif\" font-size=\"56\" font-weight=\"700\">${escapeSvgText(asset.asset_id)}</text><text x=\"96\" y=\"330\" fill=\"#d9e8df\" font-family=\"Arial, sans-serif\" font-size=\"34\">${escapeSvgText(title)}</text><text x=\"96\" y=\"500\" fill=\"#9fb7ae\" font-family=\"Arial, sans-serif\" font-size=\"26\">${escapeSvgText(label)}. No external storage requested.</text></svg>`;\n return `data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}`;\n}\n\nfunction escapeSvgText(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nexport function createS3StorageAdapter(deps: StorageAdapterDependencies): StorageAdapter {\n return {\n deleteObjectGuarded(project, assetId, confirmation): MutationResponse {\n const enabled = process.env.LINEAGE_ENABLE_CLOUD_DELETE === 'true';\n if (!enabled) {\n throw deps.createError('S3 delete is disabled. Use archive unless a human enables LINEAGE_ENABLE_CLOUD_DELETE.', 403);\n }\n if (confirmation !== `delete ${assetId}`) {\n throw deps.createError(`Delete confirmation must exactly equal: delete ${assetId}`);\n }\n const catalog = deps.loadCatalog(project);\n const asset = deps.assetById(catalog, assetId);\n if (!asset.s3) throw deps.createError(`Asset has no S3 object: ${assetId}`);\n deps.runAws(['s3api', 'delete-object', '--bucket', asset.s3.bucket, '--key', asset.s3.key, '--region', asset.s3.region]);\n asset.status = 'archived';\n deps.saveCatalog(project, catalog);\n return { ok: true, message: `Deleted current S3 object and archived ${assetId}`, catalog };\n },\n\n getIdentity() {\n try {\n const output = deps.runAws(['sts', 'get-caller-identity', '--query', '{Account:Account,Arn:Arn}', '--output', 'json']);\n const parsed = JSON.parse(output.stdout) as { Account: string; Arn: string };\n return { account: parsed.Account, arn: parsed.Arn };\n } catch {\n return undefined;\n }\n },\n\n listLiveObjects(catalog: AssetCatalog): LiveS3Object[] {\n const bucket = catalog.default_bucket;\n const region = catalog.default_region;\n // Existing uploaded objects live under products/<project>; do not rewrite keys during project migration.\n const prefix = `products/${catalog.product}/`;\n const output = deps.runAws(['s3api', 'list-objects-v2', '--bucket', bucket, '--prefix', prefix, '--region', region, '--output', 'json']);\n const parsed = JSON.parse(output.stdout) as {\n Contents?: Array<{ Key: string; Size: number; LastModified: string; StorageClass?: string }>;\n };\n const catalogKeys = new Set(catalog.assets.map(asset => asset.s3?.key).filter(Boolean));\n return (parsed.Contents || []).map(item => ({\n key: item.Key,\n size: item.Size,\n lastModified: item.LastModified,\n storageClass: item.StorageClass,\n cataloged: catalogKeys.has(item.Key),\n assetId: parseAssetIdFromS3Key(item.Key),\n }));\n },\n\n presignAsset(project, assetId, expiresIn = 900): PresignResponse {\n const catalog = deps.loadCatalog(project);\n const asset = deps.assetById(catalog, assetId);\n return { assetId, expiresIn, url: previewDataUrl(asset) };\n },\n\n promoteAsset(project, assetId, confirmWrite): MutationResponse {\n if (!confirmWrite) throw deps.createError('Promote requires confirmWrite=true');\n const catalog = deps.loadCatalog(project);\n const asset = deps.assetById(catalog, assetId);\n asset.status = 'published';\n deps.saveCatalog(project, catalog);\n return {\n ok: true,\n message: `Promoted ${assetId}`,\n catalog,\n };\n },\n\n pullAsset(project, assetId, out = '.asset-scratch'): MutationResponse {\n const catalog = deps.loadCatalog(project);\n const asset = deps.assetById(catalog, assetId);\n return {\n ok: true,\n message: `Prepared ${assetId} for local review`,\n output: {\n assetId: asset.asset_id,\n out,\n storage: asset.local ? 'local' : asset.s3 ? 'catalog-s3-metadata' : 'catalog',\n note: 'Lineage public package does not pull cloud objects automatically.',\n },\n };\n },\n\n uploadAsset(file, fields): MutationResponse {\n if (!fields.confirmWrite) throw deps.createError('Upload requires confirmWrite=true');\n if (!existsSync(file)) throw deps.createError(`Upload file missing: ${file}`, 404);\n if (!['working', 'published'].includes(fields.status)) throw deps.createError('Upload status must be working or published');\n if (!deps.supportedContentTypes.has(fields.type)) throw deps.createError(`Unsupported asset type: ${fields.type}`);\n\n const project = deps.cleanProject(fields.project || fields.product || deps.defaultProject);\n const catalog = deps.loadCatalog(project);\n const relativePath = join('uploads', project, fields.assetId, basename(file));\n const absolutePath = join(deps.repoRoot, '.asset-scratch', relativePath);\n mkdirSync(dirname(absolutePath), { recursive: true });\n copyFileSync(file, absolutePath);\n const stats = statSync(absolutePath);\n const contentType = contentTypeFor(absolutePath);\n const checksumSha256 = fileSha256(absolutePath);\n const now = new Date().toISOString();\n const nextAsset = {\n asset_id: fields.assetId,\n audience: fields.audience,\n campaign: fields.campaign,\n channel: fields.channel,\n content_type: fields.type,\n cta: fields.cta,\n hook: fields.hook,\n ...(fields.format ? { format: fields.format } : {}),\n local: {\n absolute_path: absolutePath,\n checksum_sha256: checksumSha256,\n content_type: contentType,\n relative_path: relativePath,\n size_bytes: stats.size,\n updated_at: now,\n },\n ...(fields.messageFamily ? { message_family: fields.messageFamily } : {}),\n ...(fields.notes ? { notes: fields.notes } : {}),\n product: project,\n project,\n source: 'catalog' as const,\n status: fields.status,\n title: fields.title,\n utm_content: fields.utmContent,\n };\n const existing = catalog.assets.findIndex(asset => asset.asset_id === fields.assetId);\n if (existing >= 0) catalog.assets[existing] = { ...catalog.assets[existing], ...nextAsset };\n else catalog.assets.push(nextAsset);\n deps.saveCatalog(project, catalog);\n return {\n ok: true,\n message: `Recorded ${fields.assetId} locally`,\n output: {\n file: basename(absolutePath),\n relativePath,\n sizeBytes: stats.size,\n contentType,\n checksumSha256,\n },\n catalog,\n };\n },\n };\n}\n", "import { createHash } from 'node:crypto';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { basename, extname, join, relative, resolve } from 'node:path';\nimport type { AssetCatalog, AssetContentType, GrowthAsset } from '../shared/types';\n\nconst mimeByExt: Record<string, string> = {\n '.gif': 'image/gif',\n '.jpeg': 'image/jpeg',\n '.jpg': 'image/jpeg',\n '.mov': 'video/quicktime',\n '.mp4': 'video/mp4',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n '.webp': 'image/webp',\n};\nconst localReviewExts = new Set(Object.keys(mimeByExt));\nconst channelFromName = /\\b(linkedin|meta|tiktok|youtube|x-twitter|x)\\b/i;\nconst campaignFromPath = /\\b(20\\d{2}-\\d{2}-[a-z0-9-]+)\\b/i;\n\nclass LocalReviewError extends Error {\n status = 400;\n}\n\nfunction localReviewRoot(repoRoot: string): string {\n return join(repoRoot, '.asset-scratch');\n}\n\nexport function contentTypeFor(file: string): string {\n return mimeByExt[extname(file).toLowerCase()] || 'application/octet-stream';\n}\n\nexport function fileSha256(file: string): string {\n return createHash('sha256').update(readFileSync(file)).digest('hex');\n}\n\nfunction isPathInside(child: string, parent: string): boolean {\n const relativePath = relative(parent, child);\n return Boolean(relativePath) && !relativePath.startsWith('..') && !relativePath.startsWith('/');\n}\n\nfunction walkLocalReviewFiles(dir: string, files: string[] = []): string[] {\n if (!existsSync(dir)) return files;\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return files;\n throw error;\n }\n for (const entry of entries) {\n if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === 'studio-uploads' || entry.name === 'playwright-results' || entry.name === 'lineage-demo') continue;\n if (process.env.NODE_ENV !== 'test' && /^vitest-/.test(entry.name)) continue;\n const path = join(dir, entry.name);\n if (entry.isDirectory()) walkLocalReviewFiles(path, files);\n else if (entry.isFile() && localReviewExts.has(extname(entry.name).toLowerCase())) files.push(path);\n }\n return files;\n}\n\nfunction inferCampaign(relativePath: string): string {\n return campaignFromPath.exec(relativePath)?.[1] || 'local-review';\n}\n\nfunction inferChannel(relativePath: string): string {\n const match = channelFromName.exec(relativePath);\n if (!match) return 'local';\n return match[1].toLowerCase() === 'x' ? 'x-twitter' : match[1].toLowerCase();\n}\n\nfunction inferContentType(file: string): AssetContentType {\n const mime = contentTypeFor(file);\n if (mime.startsWith('image/gif')) return 'gif';\n if (mime.startsWith('image/')) return 'image';\n if (mime.startsWith('video/')) return 'video';\n return 'other';\n}\n\nexport function listLocalReviewAssets(repoRoot: string, project: string, catalog: AssetCatalog): GrowthAsset[] {\n const catalogChecksums = new Set(catalog.assets.map(asset => asset.s3?.checksum_sha256).filter(Boolean));\n const root = localReviewRoot(repoRoot);\n return walkLocalReviewFiles(root)\n .flatMap(file => {\n try {\n const stats = statSync(file);\n const checksum = fileSha256(file);\n const relativePath = relative(root, file);\n return [{ checksum, file, relativePath, stats }];\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw error;\n }\n })\n .filter(item => !catalogChecksums.has(item.checksum))\n .map(item => {\n const fileSlug = basename(item.file, extname(item.file));\n const channel = inferChannel(item.relativePath);\n return {\n asset_id: `local-${item.checksum.slice(0, 12)}`,\n project,\n product: project,\n source: 'local',\n campaign: inferCampaign(item.relativePath),\n channel,\n audience: 'local-review',\n status: 'planned',\n content_type: inferContentType(item.file),\n title: fileSlug.replace(/[-_]+/g, ' '),\n hook: item.relativePath,\n cta: 'Review before upload',\n utm_content: fileSlug.replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_+|_+$/g, '').toLowerCase() || 'local_review',\n notes: 'Local pre-push asset. Review and refine before uploading to S3.',\n local: {\n relative_path: item.relativePath,\n absolute_path: item.file,\n size_bytes: item.stats.size,\n content_type: contentTypeFor(item.file),\n checksum_sha256: item.checksum,\n updated_at: item.stats.mtime.toISOString(),\n },\n };\n });\n}\n\nexport function localPreviewPath(repoRoot: string, relativePath: string): string {\n const root = localReviewRoot(repoRoot);\n const resolved = resolve(root, relativePath);\n if (!isPathInside(resolved, root) || !existsSync(resolved)) throw new LocalReviewError('Unknown local review asset');\n if (!localReviewExts.has(extname(resolved).toLowerCase())) throw new LocalReviewError('Local preview type is not supported');\n return resolved;\n}\n", "import type { SelectionFields } from '../shared/types';\nimport type { DatabaseSync } from './assetLineageDb';\n\nexport const LINEAGE_NEXT_VARIATION_LIMIT = 3;\n\nexport interface LineageSelectionRow {\n asset_id: string;\n notes?: string;\n position: number;\n selected_at: string;\n}\n\nexport function selectionId(project: string, root: string, assetId: string): string {\n return `${project}:${root}:selected:${assetId}`;\n}\n\nexport function selectedRows(database: DatabaseSync, project: string, root: string): LineageSelectionRow[] {\n return database.prepare(`\n select asset_id, notes, position, selected_at\n from asset_selections\n where project_id = ? and root_asset_id = ?\n order by position, selected_at, asset_id\n `).all(project, root) as unknown as LineageSelectionRow[];\n}\n\nexport function normalizeSelectionInput(fields: SelectionFields): string[] {\n return [...new Set([...(fields.assetIds || []), fields.assetId || ''].map(assetId => assetId.trim()).filter(Boolean))];\n}\n", "import { lineageDb, nowIso, type DatabaseSync } from './assetLineageDb';\nimport type {\n LineageWorkspace,\n LineageWorkspaceActor,\n LineageWorkspaceFields,\n LineageWorkspaceSnapshot,\n LineageWorkspaceStatus,\n LineageWorkspaceUpdateFields,\n} from '../shared/types';\n\ntype Row = Record<string, unknown>;\n\nconst actors = new Set<LineageWorkspaceActor>(['human', 'agent', 'system']);\nconst statuses = new Set<LineageWorkspaceStatus>(['active', 'paused', 'archived']);\n\nexport class LineageWorkspaceError extends Error {\n constructor(message: string, public status = 400) {\n super(message);\n }\n}\n\nexport function isLineageWorkspaceError(error: unknown): error is LineageWorkspaceError {\n return error instanceof LineageWorkspaceError;\n}\n\nexport function lineageWorkspaceId(project: string, rootAssetId: string): string {\n return `${project}:lineage-workspace:${rootAssetId}`;\n}\n\nfunction ensureProject(database: DatabaseSync, project: string): void {\n const timestamp = nowIso();\n database.prepare(`\n insert into projects (id, product, created_at, updated_at)\n values (?, ?, ?, ?)\n on conflict(id) do update set product = excluded.product, updated_at = excluded.updated_at\n `).run(project, project, timestamp, timestamp);\n}\n\nfunction normalizeStatus(value: LineageWorkspaceStatus | undefined, fallback: LineageWorkspaceStatus): LineageWorkspaceStatus {\n const status = value || fallback;\n if (!statuses.has(status)) throw new LineageWorkspaceError(`Unsupported lineage workspace status: ${status}`);\n return status;\n}\n\nfunction normalizeActor(value: LineageWorkspaceActor | undefined): LineageWorkspaceActor {\n const actor = value || 'human';\n if (!actors.has(actor)) throw new LineageWorkspaceError(`Unsupported lineage workspace actor: ${actor}`);\n return actor;\n}\n\nfunction requireAsset(database: DatabaseSync, project: string, assetId: string): { id: string; title: string } {\n const row = database.prepare('select id, title from assets where project_id = ? and id = ?').get(project, assetId) as { id: string; title: string } | undefined;\n if (!row) throw new LineageWorkspaceError(`Unknown indexed asset: ${assetId}`, 404);\n return row;\n}\n\nfunction rowToWorkspace(row: Row): LineageWorkspace {\n return {\n id: String(row.id),\n project: String(row.project_id),\n root_asset_id: String(row.root_asset_id),\n title: String(row.title),\n status: String(row.status) as LineageWorkspaceStatus,\n notes: typeof row.notes === 'string' ? row.notes : undefined,\n created_by: String(row.created_by) as LineageWorkspaceActor,\n active_at: typeof row.active_at === 'string' ? row.active_at : undefined,\n created_at: String(row.created_at),\n updated_at: String(row.updated_at),\n };\n}\n\nfunction workspaceById(database: DatabaseSync, project: string, id: string): LineageWorkspace | null {\n const row = database.prepare('select * from lineage_workspaces where project_id = ? and id = ?').get(project, id) as Row | undefined;\n return row ? rowToWorkspace(row) : null;\n}\n\nfunction workspaceByRoot(database: DatabaseSync, project: string, rootAssetId: string): LineageWorkspace | null {\n const row = database.prepare('select * from lineage_workspaces where project_id = ? and root_asset_id = ?').get(project, rootAssetId) as Row | undefined;\n return row ? rowToWorkspace(row) : null;\n}\n\nfunction knownRoots(database: DatabaseSync, project: string): Array<{ root_asset_id: string; selected_at?: string }> {\n const rows = database.prepare(`\n select root_asset_id, max(selected_at) selected_at from asset_selections where project_id = ? group by root_asset_id\n union\n select root_asset_id, null selected_at from asset_layouts where project_id = ? group by root_asset_id\n union\n select parent_asset_id root_asset_id, null selected_at\n from asset_edges\n where project_id = ?\n and parent_asset_id not in (select child_asset_id from asset_edges where project_id = ?)\n group by parent_asset_id\n `).all(project, project, project, project) as Array<{ root_asset_id: string; selected_at?: string | null }>;\n return rows.map(row => ({ root_asset_id: row.root_asset_id, selected_at: row.selected_at || undefined }));\n}\n\nfunction seedLegacyWorkspaces(database: DatabaseSync, project: string): void {\n ensureProject(database, project);\n const timestamp = nowIso();\n const statement = database.prepare(`\n insert into lineage_workspaces (\n id, project_id, root_asset_id, title, status, notes, created_by, active_at, created_at, updated_at\n )\n select ?, ?, a.id, a.title || ' lineage', 'active', null, 'system', ?, ?, ?\n from assets a\n where a.project_id = ? and a.id = ?\n on conflict(project_id, root_asset_id) do nothing\n `);\n for (const root of knownRoots(database, project)) {\n statement.run(\n lineageWorkspaceId(project, root.root_asset_id),\n project,\n root.selected_at || null,\n timestamp,\n timestamp,\n project,\n root.root_asset_id\n );\n }\n}\n\nfunction listRows(database: DatabaseSync, project: string): LineageWorkspace[] {\n return (database.prepare(`\n select * from lineage_workspaces\n where project_id = ?\n order by\n case status when 'active' then 0 when 'paused' then 1 else 2 end,\n active_at desc nulls last,\n updated_at desc,\n title\n `).all(project) as Row[]).map(rowToWorkspace);\n}\n\nfunction activeWorkspace(database: DatabaseSync, project: string): LineageWorkspace | null {\n const row = database.prepare(`\n select * from lineage_workspaces\n where project_id = ? and status != 'archived'\n order by active_at desc nulls last, updated_at desc\n limit 1\n `).get(project) as Row | undefined;\n return row ? rowToWorkspace(row) : null;\n}\n\nexport function listLineageWorkspaces(project: string): LineageWorkspaceSnapshot {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n return {\n project,\n active_workspace: activeWorkspace(database, project),\n workspaces: listRows(database, project),\n fetchedAt: nowIso(),\n };\n } finally {\n database.close();\n }\n}\n\nexport function inspectLineageWorkspace(project: string, workspaceId: string): LineageWorkspace {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n const workspace = workspaceById(database, project, workspaceId) || workspaceByRoot(database, project, workspaceId);\n if (!workspace) throw new LineageWorkspaceError(`Unknown lineage workspace: ${workspaceId}`, 404);\n return workspace;\n } finally {\n database.close();\n }\n}\n\nexport function createLineageWorkspace(project: string, fields: LineageWorkspaceFields) {\n const rootAssetId = fields.rootAssetId.trim();\n if (!rootAssetId) throw new LineageWorkspaceError('Lineage workspace requires rootAssetId');\n const status = normalizeStatus(fields.status, 'active');\n const actor = normalizeActor(fields.createdBy);\n const database = lineageDb();\n try {\n const root = requireAsset(database, project, rootAssetId);\n const timestamp = nowIso();\n const workspace: LineageWorkspace = {\n id: lineageWorkspaceId(project, rootAssetId),\n project,\n root_asset_id: rootAssetId,\n title: fields.title?.trim() || `${root.title} lineage`,\n status,\n notes: fields.notes?.trim() || undefined,\n created_by: actor,\n active_at: fields.activate !== false && status !== 'archived' ? timestamp : undefined,\n created_at: timestamp,\n updated_at: timestamp,\n };\n if (!fields.confirmWrite) return { ok: true as const, dryRun: true as const, workspace };\n ensureProject(database, project);\n database.prepare(`\n insert into lineage_workspaces (\n id, project_id, root_asset_id, title, status, notes, created_by, active_at, created_at, updated_at\n ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n on conflict(project_id, root_asset_id) do update set\n title = excluded.title,\n status = excluded.status,\n notes = excluded.notes,\n active_at = coalesce(excluded.active_at, lineage_workspaces.active_at),\n updated_at = excluded.updated_at\n `).run(\n workspace.id,\n project,\n workspace.root_asset_id,\n workspace.title,\n workspace.status,\n workspace.notes || null,\n workspace.created_by,\n workspace.active_at || null,\n workspace.created_at,\n workspace.updated_at\n );\n return {\n ok: true as const,\n message: `Saved lineage workspace ${workspace.title}`,\n workspace: workspaceById(database, project, workspace.id),\n };\n } finally {\n database.close();\n }\n}\n\nexport function updateLineageWorkspace(project: string, workspaceId: string, fields: LineageWorkspaceUpdateFields) {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n const current = workspaceById(database, project, workspaceId) || workspaceByRoot(database, project, workspaceId);\n if (!current) throw new LineageWorkspaceError(`Unknown lineage workspace: ${workspaceId}`, 404);\n const timestamp = nowIso();\n const next: LineageWorkspace = {\n ...current,\n title: fields.title?.trim() || current.title,\n status: normalizeStatus(fields.status, current.status),\n notes: fields.notes === undefined ? current.notes : fields.notes.trim() || undefined,\n active_at: fields.activate ? timestamp : current.active_at,\n updated_at: timestamp,\n };\n if (!fields.confirmWrite) return { ok: true as const, dryRun: true as const, workspace: next };\n database.prepare(`\n update lineage_workspaces\n set title = ?, status = ?, notes = ?, active_at = ?, updated_at = ?\n where project_id = ? and id = ?\n `).run(next.title, next.status, next.notes || null, next.active_at || null, timestamp, project, current.id);\n return {\n ok: true as const,\n message: `Updated lineage workspace ${next.title}`,\n workspace: workspaceById(database, project, current.id),\n };\n } finally {\n database.close();\n }\n}\n\nexport function activateLineageWorkspace(project: string, workspaceId: string, confirmWrite: boolean) {\n return updateLineageWorkspace(project, workspaceId, { activate: true, status: 'active', confirmWrite });\n}\n\nexport function archiveLineageWorkspace(project: string, workspaceId: string, confirmWrite: boolean) {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n const current = workspaceById(database, project, workspaceId) || workspaceByRoot(database, project, workspaceId);\n if (!current) throw new LineageWorkspaceError(`Unknown lineage workspace: ${workspaceId}`, 404);\n const timestamp = nowIso();\n const next: LineageWorkspace = {\n ...current,\n status: 'archived',\n active_at: undefined,\n updated_at: timestamp,\n };\n if (!confirmWrite) return { ok: true as const, dryRun: true as const, workspace: next };\n database.prepare(`\n update lineage_workspaces\n set status = 'archived', active_at = null, updated_at = ?\n where project_id = ? and id = ?\n `).run(timestamp, project, current.id);\n database.prepare('delete from asset_selections where project_id = ? and root_asset_id = ?').run(project, current.root_asset_id);\n return {\n ok: true as const,\n message: `Archived lineage workspace ${current.title}`,\n workspace: workspaceById(database, project, current.id),\n };\n } finally {\n database.close();\n }\n}\n\nexport function activeLineageWorkspaceRoot(project: string): string | undefined {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n return activeWorkspace(database, project)?.root_asset_id;\n } finally {\n database.close();\n }\n}\n", "import { join } from 'node:path';\nimport { defaultProject, listAssets, repoRoot } from './assetCore';\nimport { lineageDb as db, lineageDbPath, nowIso, type DatabaseSync } from './assetLineageDb';\nimport { LINEAGE_NEXT_VARIATION_LIMIT, normalizeSelectionInput, selectedRows, selectionId } from './assetLineageSelection';\nimport { activeLineageWorkspaceRoot } from './assetLineageWorkspaces';\nimport type {\n AssetReviewState,\n GrowthAsset,\n LineageEdge,\n LineageChildrenResponse,\n LineageIndexSummary,\n LineageLayoutFields,\n LineageLinkFields,\n LineageNode,\n LineageNextResponse,\n LineagePosition,\n LineageSnapshot,\n ReviewFields,\n SelectionFields,\n} from '../shared/types';\n\nexport class LineageError extends Error {\n constructor(message: string, public status = 400) {\n super(message);\n }\n}\n\nexport function isLineageError(error: unknown): error is LineageError {\n return error instanceof LineageError;\n}\n\nfunction collectAssets(project: string, source: 'catalog' | 'local'): GrowthAsset[] {\n const first = listAssets(project, { source, page: 1, pageSize: 100 });\n const assets = [...first.assets];\n for (let page = 2; page <= first.pagination.totalPages; page += 1) {\n assets.push(...listAssets(project, { source, page, pageSize: 100 }).assets);\n }\n return assets;\n}\n\nfunction upsertProject(database: DatabaseSync, project: string): void {\n const timestamp = nowIso();\n database.prepare(`\n insert into projects (id, product, catalog_path, created_at, updated_at)\n values (?, ?, ?, ?, ?)\n on conflict(id) do update set product = excluded.product, updated_at = excluded.updated_at\n `).run(project, project, join(repoRoot, project, 'assets', 'catalog.json'), timestamp, timestamp);\n}\n\nfunction upsertAsset(database: DatabaseSync, project: string, asset: GrowthAsset): void {\n const timestamp = nowIso();\n const source = asset.source === 'local' ? 'local' : 'catalog';\n database.prepare(`\n insert into assets (\n id, project_id, source, local_path, s3_key, checksum_sha256, media_type, title, status,\n channel, campaign, audience, size_bytes, content_type, created_at, updated_at, last_seen_at\n ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n on conflict(id) do update set\n source = excluded.source, local_path = excluded.local_path, s3_key = excluded.s3_key,\n checksum_sha256 = excluded.checksum_sha256, media_type = excluded.media_type,\n title = excluded.title, status = excluded.status, channel = excluded.channel,\n campaign = excluded.campaign, audience = excluded.audience, size_bytes = excluded.size_bytes,\n content_type = excluded.content_type, updated_at = excluded.updated_at, last_seen_at = excluded.last_seen_at\n `).run(\n asset.asset_id, project, source, asset.local?.relative_path || null, asset.s3?.key || null,\n asset.local?.checksum_sha256 || asset.s3?.checksum_sha256 || null, asset.content_type, asset.title,\n asset.status, asset.channel || null, asset.campaign || null, asset.audience || null,\n asset.local?.size_bytes || asset.s3?.size_bytes || null, asset.local?.content_type || asset.s3?.content_type || null,\n timestamp, timestamp, timestamp\n );\n database.prepare(`\n insert into asset_reviews (asset_id, review_state, updated_at)\n values (?, 'unreviewed', ?)\n on conflict(asset_id) do nothing\n `).run(asset.asset_id, timestamp);\n}\n\nexport function indexLineageAssets(project = defaultProject): LineageIndexSummary {\n const database = db();\n const catalog = collectAssets(project, 'catalog');\n const local = collectAssets(project, 'local');\n upsertProject(database, project);\n for (const asset of [...catalog, ...local]) upsertAsset(database, project, asset);\n database.close();\n return { catalog: catalog.length, local: local.length, total: catalog.length + local.length, database: lineageDbPath() };\n}\n\nfunction requireAsset(database: DatabaseSync, project: string, assetId: string): void {\n const row = database.prepare('select id from assets where project_id = ? and id = ?').get(project, assetId);\n if (!row) throw new LineageError(`Unknown indexed asset: ${assetId}`, 404);\n}\n\nfunction parentOf(database: DatabaseSync, project: string, assetId: string): string | undefined {\n const row = database.prepare('select parent_asset_id from asset_edges where project_id = ? and child_asset_id = ? order by created_at limit 1').get(project, assetId) as { parent_asset_id?: string } | undefined;\n return row?.parent_asset_id;\n}\n\nfunction rootFor(database: DatabaseSync, project: string, assetId: string): string {\n let root = assetId;\n const seen = new Set<string>();\n while (!seen.has(root)) {\n seen.add(root);\n const parent = parentOf(database, project, root);\n if (!parent) return root;\n root = parent;\n }\n return assetId;\n}\n\nfunction latestSelectedRoot(database: DatabaseSync, project: string): string | undefined {\n const row = database.prepare('select root_asset_id from asset_selections where project_id = ? order by selected_at desc limit 1').get(project) as { root_asset_id?: string } | undefined;\n return row?.root_asset_id;\n}\n\nfunction resolveRoot(database: DatabaseSync, project: string, rootAssetId?: string): string {\n if (rootAssetId) {\n requireAsset(database, project, rootAssetId);\n return rootAssetId;\n }\n const root = activeLineageWorkspaceRoot(project) || latestSelectedRoot(database, project);\n if (!root) throw new LineageError('Lineage command requires --root unless a project selection exists');\n requireAsset(database, project, root);\n return root;\n}\n\nfunction edgeId(project: string, parent: string, child: string): string {\n return `${project}:${parent}:derived_from:${child}`;\n}\n\nfunction canPreviewLocally(mediaType: string, localPath?: string): boolean {\n return Boolean(localPath && ['image', 'video', 'gif'].includes(mediaType));\n}\n\nfunction localPreviewUrl(project: string, localPath?: string): string | undefined {\n if (!localPath) return undefined;\n const params = new URLSearchParams({ project, path: localPath });\n return `/api/assets/local-preview?${params.toString()}`;\n}\n\nexport function linkLineageAssets(project: string, fields: LineageLinkFields) {\n const database = db();\n requireAsset(database, project, fields.parentAssetId);\n requireAsset(database, project, fields.childAssetId);\n if (fields.parentAssetId === fields.childAssetId) throw new LineageError('Lineage link cannot point to itself');\n const edge = {\n id: edgeId(project, fields.parentAssetId, fields.childAssetId), parent_asset_id: fields.parentAssetId,\n child_asset_id: fields.childAssetId, relation_type: 'derived_from' as const, created_at: nowIso(),\n };\n if (!fields.confirmWrite) {\n database.close();\n return { ok: true as const, dryRun: true, edge };\n }\n database.prepare(`\n insert into asset_edges (id, project_id, parent_asset_id, child_asset_id, relation_type, created_at)\n values (?, ?, ?, ?, 'derived_from', ?)\n on conflict(project_id, parent_asset_id, child_asset_id, relation_type) do nothing\n `).run(edge.id, project, edge.parent_asset_id, edge.child_asset_id, edge.created_at);\n database.close();\n return { ok: true as const, message: `Linked ${edge.child_asset_id} from ${edge.parent_asset_id}`, edge };\n}\n\nfunction descendants(database: DatabaseSync, project: string, root: string): LineageEdge[] {\n const edges: LineageEdge[] = [];\n const queue = [root];\n const seen = new Set<string>();\n while (queue.length > 0) {\n const parent = queue.shift()!;\n if (seen.has(parent)) continue;\n seen.add(parent);\n const rows = database.prepare('select id, parent_asset_id, child_asset_id, relation_type, created_at from asset_edges where project_id = ? and parent_asset_id = ? order by created_at').all(project, parent) as unknown as LineageEdge[];\n edges.push(...rows);\n queue.push(...rows.map(row => row.child_asset_id));\n }\n return edges;\n}\n\nexport function getLineageSnapshot(project: string, assetId: string): LineageSnapshot {\n const database = db();\n requireAsset(database, project, assetId);\n const root = rootFor(database, project, assetId);\n const edges = descendants(database, project, root);\n const ids = [...new Set([root, ...edges.flatMap(edge => [edge.parent_asset_id, edge.child_asset_id])])];\n const placeholders = ids.map(() => '?').join(',');\n const rows = database.prepare(`\n select a.id asset_id, a.project_id project, a.source, a.title, a.media_type, a.status, a.channel, a.campaign,\n a.local_path, a.s3_key, a.checksum_sha256, coalesce(r.review_state, 'unreviewed') review_state,\n r.notes review_notes, l.x layout_x, l.y layout_y\n from assets a left join asset_reviews r on r.asset_id = a.id\n left join asset_layouts l on l.project_id = a.project_id and l.root_asset_id = ? and l.asset_id = a.id\n where a.project_id = ? and a.id in (${placeholders})\n `).all(root, project, ...ids) as Array<Omit<LineageNode, 'is_latest' | 'position' | 'preview_url' | 'selection_note' | 'user_selected'> & { layout_x?: number; layout_y?: number }>;\n const selected = selectedRows(database, project, root);\n const childIds = new Set(edges.map(edge => edge.parent_asset_id));\n const selectedIds = new Set(selected.map(row => row.asset_id));\n const selections = selected.map(row => ({\n asset_id: row.asset_id, notes: row.notes || undefined,\n position: Number(row.position || 0), selected_at: row.selected_at,\n }));\n const selection = selections[0] || null;\n const nodes = rows.map(row => {\n const position: LineagePosition | undefined = typeof row.layout_x === 'number' && typeof row.layout_y === 'number' ? { x: row.layout_x, y: row.layout_y } : undefined;\n const { layout_x: _layoutX, layout_y: _layoutY, ...node } = row;\n const nodeSelection = selections.find(item => item.asset_id === row.asset_id);\n return {\n ...node,\n is_latest: !childIds.has(row.asset_id),\n position,\n preview_url: canPreviewLocally(row.media_type, row.local_path) ? localPreviewUrl(project, row.local_path) : undefined,\n selection_note: nodeSelection?.notes,\n user_selected: selectedIds.has(row.asset_id),\n };\n });\n database.close();\n return {\n project,\n root_asset_id: root,\n active_asset_id: assetId,\n selected: selections.map(row => row.asset_id),\n selection,\n selections,\n latest: nodes.filter(node => node.is_latest).map(node => node.asset_id),\n nodes,\n edges,\n fetchedAt: nowIso(),\n };\n}\n\nexport function updateLineageLayout(project: string, fields: LineageLayoutFields) {\n if (fields.positions.length === 0) throw new LineageError('Lineage layout requires at least one position');\n const database = db();\n requireAsset(database, project, fields.rootAssetId);\n for (const position of fields.positions) requireAsset(database, project, position.assetId);\n if (!fields.confirmWrite) {\n database.close();\n return { ok: true as const, dryRun: true, root_asset_id: fields.rootAssetId, positions: fields.positions };\n }\n const timestamp = nowIso();\n const statement = database.prepare(`\n insert into asset_layouts (id, project_id, root_asset_id, asset_id, x, y, updated_at)\n values (?, ?, ?, ?, ?, ?, ?)\n on conflict(project_id, root_asset_id, asset_id) do update set\n x = excluded.x, y = excluded.y, updated_at = excluded.updated_at\n `);\n for (const position of fields.positions) {\n statement.run(`${project}:${fields.rootAssetId}:layout:${position.assetId}`, project, fields.rootAssetId, position.assetId, position.x, position.y, timestamp);\n }\n database.close();\n return { ok: true as const, message: `Saved ${fields.positions.length} lineage positions`, root_asset_id: fields.rootAssetId, positions: fields.positions };\n}\n\nexport function getLineageNextAsset(project: string, rootAssetId?: string): LineageNextResponse {\n const database = db();\n const root = resolveRoot(database, project, rootAssetId);\n database.close();\n const snapshot = getLineageSnapshot(project, root);\n const selectedNodes = snapshot.selected\n .map(assetId => snapshot.nodes.find(node => node.asset_id === assetId))\n .filter((node): node is LineageNode => Boolean(node));\n const latestNodes = snapshot.nodes.filter(node => snapshot.latest.includes(node.asset_id));\n const warnings: string[] = [];\n for (const selectedNode of selectedNodes) {\n if (selectedNode.is_latest) continue;\n warnings.push('Selected asset is not a latest leaf; agents should treat this as an intentional branch choice.');\n }\n if (selectedNodes.length > 0) {\n return {\n project,\n root_asset_id: snapshot.root_asset_id,\n strategy: 'selected',\n selection_mode: selectedNodes.length > 1 ? 'multiple' : 'single',\n recommended_action: 'evolve_variations',\n reason: 'user_selected',\n next_asset: selectedNodes[0],\n next_assets: selectedNodes,\n latest: snapshot.latest,\n selected: snapshot.selected,\n selection: snapshot.selection,\n selections: snapshot.selections,\n candidates: latestNodes,\n warnings,\n fetchedAt: nowIso(),\n };\n }\n if (latestNodes.length === 1) {\n return {\n project,\n root_asset_id: snapshot.root_asset_id,\n strategy: 'single_latest',\n selection_mode: 'fallback',\n recommended_action: 'evolve_variations',\n reason: 'single_latest_fallback',\n next_asset: latestNodes[0],\n next_assets: [latestNodes[0]],\n latest: snapshot.latest,\n selected: snapshot.selected,\n selection: snapshot.selection,\n selections: snapshot.selections,\n candidates: latestNodes,\n warnings,\n fetchedAt: nowIso(),\n };\n }\n return {\n project,\n root_asset_id: snapshot.root_asset_id,\n strategy: latestNodes.length > 1 ? 'ambiguous_latest' : 'empty',\n selection_mode: 'none',\n recommended_action: latestNodes.length > 1 ? 'choose_next_base' : 'none',\n reason: latestNodes.length > 1 ? 'multiple_latest_no_selection' : 'no_lineage_candidates',\n next_asset: null,\n next_assets: [],\n latest: snapshot.latest,\n selected: snapshot.selected,\n selection: snapshot.selection,\n selections: snapshot.selections,\n candidates: latestNodes,\n warnings,\n fetchedAt: nowIso(),\n };\n}\n\nexport function getLineageChildren(project: string, parentAssetId: string): LineageChildrenResponse {\n const snapshot = getLineageSnapshot(project, parentAssetId);\n const edges = snapshot.edges.filter(edge => edge.parent_asset_id === parentAssetId);\n const childIds = new Set(edges.map(edge => edge.child_asset_id));\n return {\n project, parent_asset_id: parentAssetId,\n children: snapshot.nodes.filter(node => childIds.has(node.asset_id)),\n edges, fetchedAt: nowIso(),\n };\n}\n\nexport function updateSelectedAsset(project: string, fields: SelectionFields) {\n const database = db();\n const inputAssetIds = normalizeSelectionInput(fields);\n const root = fields.rootAssetId || (inputAssetIds[0] ? rootFor(database, project, inputAssetIds[0]) : '');\n if (!root) throw new LineageError('Selection requires rootAssetId or assetId');\n requireAsset(database, project, root);\n for (const assetId of inputAssetIds) requireAsset(database, project, assetId);\n const mode = fields.mode || 'replace';\n const limit = fields.maxSelections || LINEAGE_NEXT_VARIATION_LIMIT;\n if (!fields.confirmWrite) {\n database.close();\n return { ok: true as const, dryRun: true, root_asset_id: root, asset_ids: inputAssetIds, mode, clear: Boolean(fields.clear), max_selections: limit };\n }\n const current = selectedRows(database, project, root);\n let nextIds = current.map(row => row.asset_id);\n if (fields.clear) {\n nextIds = [];\n } else if (mode === 'replace') {\n nextIds = inputAssetIds;\n } else if (mode === 'add') {\n nextIds = [...nextIds, ...inputAssetIds];\n } else if (mode === 'remove') {\n nextIds = nextIds.filter(assetId => !inputAssetIds.includes(assetId));\n } else if (mode === 'toggle') {\n for (const assetId of inputAssetIds) {\n nextIds = nextIds.includes(assetId) ? nextIds.filter(id => id !== assetId) : [...nextIds, assetId];\n }\n }\n nextIds = [...new Set(nextIds)];\n if (!fields.clear && inputAssetIds.length === 0) throw new LineageError('Selection set requires assetId or assetIds');\n if (nextIds.length > limit) throw new LineageError(`Select at most ${limit} assets for next variation`);\n database.prepare('delete from asset_selections where project_id = ? and root_asset_id = ?').run(project, root);\n const timestamp = nowIso();\n const insert = database.prepare(`\n insert into asset_selections (id, project_id, root_asset_id, asset_id, position, notes, selected_at)\n values (?, ?, ?, ?, ?, ?, ?)\n `);\n nextIds.forEach((assetId, position) => {\n const existing = current.find(row => row.asset_id === assetId);\n const notes = inputAssetIds.includes(assetId) ? fields.notes || existing?.notes : existing?.notes;\n insert.run(selectionId(project, root, assetId), project, root, assetId, position, notes || null, timestamp);\n });\n database.close();\n const message = nextIds.length === 0 ? `Cleared selected assets for ${root}` : `Selected ${nextIds.length} asset${nextIds.length === 1 ? '' : 's'} for ${root}`;\n return { ok: true as const, message, root_asset_id: root, asset_id: nextIds[0] || null, asset_ids: nextIds, mode };\n}\n\nexport function updateAssetReview(project: string, fields: ReviewFields) {\n const allowed = new Set<AssetReviewState>(['unreviewed', 'approved', 'needs_revision', 'rejected', 'ignored']);\n if (!allowed.has(fields.reviewState)) throw new LineageError(`Unsupported review state: ${fields.reviewState}`);\n const database = db();\n requireAsset(database, project, fields.assetId);\n if (!fields.confirmWrite) {\n database.close();\n return { ok: true as const, dryRun: true, asset_id: fields.assetId, review_state: fields.reviewState, notes: fields.notes };\n }\n const timestamp = nowIso();\n database.prepare(`\n insert into asset_reviews (asset_id, review_state, reviewed_at, ignored_at, notes, updated_at)\n values (?, ?, ?, ?, ?, ?)\n on conflict(asset_id) do update set\n review_state = excluded.review_state, reviewed_at = excluded.reviewed_at,\n ignored_at = excluded.ignored_at, notes = excluded.notes, updated_at = excluded.updated_at\n `).run(fields.assetId, fields.reviewState, timestamp, fields.reviewState === 'ignored' ? timestamp : null, fields.notes || null, timestamp);\n database.close();\n return { ok: true as const, message: `Marked ${fields.assetId} ${fields.reviewState}`, asset_id: fields.assetId, review_state: fields.reviewState };\n}\n", "import type { LineageBriefResponse, LineageSelectedChildFields } from '../shared/types';\nimport { AgentClaimError, validateAgentClaimForWrite } from './agentClaims';\nimport { getLineageNextAsset, LineageError, linkLineageAssets } from './assetLineage';\nimport { lineageDbPath, nowIso } from './assetLineageDb';\nimport { lineageWorkspaceId } from './assetLineageWorkspaces';\n\nconst publicPackageCommand = 'npx @mean-weasel/lineage';\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nfunction lineageCommand(command: string, project: string, rootAssetId: string): string {\n return `${publicPackageCommand} ${command} --project ${shellQuote(project)} --root ${shellQuote(rootAssetId)} --db ${shellQuote(lineageDbPath())} --json`;\n}\n\nfunction linkChildCommand(project: string, rootAssetId: string): string {\n return `${publicPackageCommand} link-child --project ${shellQuote(project)} --root ${shellQuote(rootAssetId)} --child <asset-id> --confirm-write --db ${shellQuote(lineageDbPath())} --json`;\n}\n\nexport function getLineageBrief(project: string, rootAssetId?: string): LineageBriefResponse {\n const next = getLineageNextAsset(project, rootAssetId);\n const assets = next.next_assets;\n const asset = next.next_asset;\n const referenceAssetIds = assets.map(item => item.asset_id);\n const rationale = next.selections.map(selection => selection.notes).find(Boolean) || asset?.selection_note || next.selection?.notes;\n const channels = [...new Set(assets.map(item => item.channel || 'unknown'))];\n const campaigns = [...new Set(assets.map(item => item.campaign || 'unknown'))];\n const prompt = assets.length > 0\n ? [\n assets.length === 1\n ? `Create 3-4 variations from asset ${assets[0].asset_id} (${assets[0].title}).`\n : `Create 3-4 variations using these ${assets.length} selected references: ${referenceAssetIds.join(', ')}.`,\n rationale ? `Preserve this selection rationale: ${rationale}` : 'Preserve the strongest visible ideas while exploring distinct alternatives.',\n `Keep project=${project}, root=${next.root_asset_id}, channels=${channels.join(',')}, campaigns=${campaigns.join(',')}.`,\n 'After generation, index outputs and link chosen children with lineage link-child.',\n ].join(' ')\n : 'Select one to three latest lineage candidates before generating variations.';\n return {\n project,\n root_asset_id: next.root_asset_id,\n strategy: next.strategy,\n selection_mode: next.selection_mode,\n recommended_action: next.recommended_action,\n reason: next.reason,\n next_asset: asset,\n next_assets: assets,\n selection: next.selection,\n selections: next.selections,\n latest: next.latest,\n warnings: next.warnings,\n brief: {\n title: asset ? `Evolve ${assets.length > 1 ? `${assets.length} selected bases` : asset.title}` : 'Choose next lineage base',\n objective: asset ? 'Generate the next branch of visual variations from the selected lineage base or bases.' : 'Resolve the next base before generation.',\n prompt,\n reference_asset_id: asset?.asset_id,\n reference_asset_ids: referenceAssetIds,\n rationale,\n },\n handoff: {\n next_command: lineageCommand('next', project, next.root_asset_id),\n inspect_command: asset ? `${publicPackageCommand} inspect --project ${shellQuote(project)} --asset-id ${shellQuote(asset.asset_id)} --db ${shellQuote(lineageDbPath())} --json` : undefined,\n link_child_command: asset ? linkChildCommand(project, next.root_asset_id) : undefined,\n },\n fetchedAt: nowIso(),\n };\n}\n\nexport function linkSelectedLineageChild(project: string, fields: LineageSelectedChildFields) {\n const next = getLineageNextAsset(project, fields.rootAssetId);\n if (!next.next_asset) throw new LineageError('Cannot link child until a next base is selected or unambiguous');\n if (fields.confirmWrite) {\n const validation = validateAgentClaimForWrite({\n channel: next.next_asset.channel,\n claimToken: fields.claimToken,\n confirmWrite: fields.confirmWrite,\n dangerLevel: 'enforce',\n project,\n scopeType: 'lineage_workspace',\n targetId: lineageWorkspaceId(project, next.root_asset_id),\n writeKind: 'link_child',\n });\n if (!validation.ok) throw new AgentClaimError(validation.message, validation.code === 'claim_required' ? 401 : 403, validation.code, validation.conflicts);\n }\n const result = linkLineageAssets(project, {\n childAssetId: fields.childAssetId,\n confirmWrite: fields.confirmWrite,\n claimToken: fields.claimToken,\n parentAssetId: next.next_asset.asset_id,\n });\n return {\n ...result,\n root_asset_id: next.root_asset_id,\n parent_asset_id: next.next_asset.asset_id,\n child_asset_id: fields.childAssetId,\n reference_asset_ids: next.next_assets.map(asset => asset.asset_id),\n warning: next.next_assets.length > 1\n ? 'Linked child to the primary selected base; add explicit edges to other selected references if the child derives from them too.'\n : undefined,\n };\n}\n", "#!/usr/bin/env node\n\nimport { runLineageCli } from './lineageCli';\n\nrunLineageCli({ binName: 'lineage', channel: 'stable', defaultHost: 'lineage.localhost', defaultPort: 5197, displayName: 'Lineage' });\n"],
5
- "mappings": "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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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",
6
- "names": ["existsSync", "mkdirSync", "readFileSync", "dirname", "join", "resolve", "fileURLToPath", "createHash", "mkdirSync", "join", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "dirname", "join", "resolve", "existsSync", "statSync", "basename", "join", "existsSync", "join", "basename", "statSync", "join", "existsSync", "readFileSync", "dirname", "resolve", "join", "existsSync", "readFileSync", "mkdirSync", "dirname", "require", "join", "mkdirSync", "createHash", "claim", "ensureProject", "ensureProject", "resolve", "dirname", "fileURLToPath", "readFileSync", "join", "existsSync", "mkdirSync", "json", "message"]
3
+ "sources": ["../../src/cli/lineageCli.ts", "../../src/server/agentClaims.ts", "../../src/server/assetLineageDb.ts", "../../src/server/assetCore.ts", "../../src/server/adapters/storage/s3StorageAdapter.ts", "../../src/server/localReview.ts", "../../src/server/assetLineageSelection.ts", "../../src/server/assetLineageWorkspaces.ts", "../../src/server/lineageClaimGuards.ts", "../../src/server/assetLineage.ts", "../../src/server/assetLineageHandoff.ts", "../../src/cli/lineage.ts"],
4
+ "sourcesContent": ["import { existsSync, mkdirSync, readFileSync } from 'node:fs';\nimport { homedir, platform } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport {\n createAgentClaim,\n heartbeatAgentClaim,\n inspectAgentClaim,\n isAgentClaimError,\n listAgentClaims,\n parseClaimTtl,\n redactAgentClaimTokens,\n releaseAgentClaim,\n revokeAgentClaim,\n transferAgentClaim,\n type AgentClaimScopeType,\n} from '../server/agentClaims';\nimport { defaultProduct } from '../server/assetCore';\nimport { getLineageNextAsset, getLineageSnapshot } from '../server/assetLineage';\nimport { getLineageBrief, linkSelectedLineageChild } from '../server/assetLineageHandoff';\n\nexport interface LineageCliConfig {\n binName: 'lineage' | 'lineage-dev';\n channel: 'stable' | 'development';\n defaultHost: string;\n defaultPort: number;\n displayName: string;\n}\n\ninterface StartOptions {\n dbPath: string;\n host: string;\n json: boolean;\n open: boolean;\n port: number;\n}\n\ninterface DataCommandOptions {\n assetId?: string;\n childAssetId?: string;\n claimToken?: string;\n confirmWrite: boolean;\n dbPath?: string;\n json: boolean;\n project: string;\n rootAssetId?: string;\n}\n\nconst signalExitCodes: Partial<Record<NodeJS.Signals, number>> = {\n SIGINT: 130,\n SIGTERM: 143,\n};\n\nfunction packageRoot(): string {\n return resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');\n}\n\nfunction packageVersion(): string {\n try {\n const packageInfo = JSON.parse(readFileSync(join(packageRoot(), 'package.json'), 'utf8')) as { version?: string };\n return packageInfo.version || '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n\nfunction dataRoot(displayName: string): string {\n if (process.env.LINEAGE_HOME) return process.env.LINEAGE_HOME;\n if (platform() === 'darwin') return join(homedir(), 'Library', 'Application Support', displayName);\n if (platform() === 'win32') return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), displayName);\n return join(process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share'), displayName.toLowerCase().replace(/\\s+/g, '-'));\n}\n\nfunction readOption(args: string[], name: string): string | undefined {\n const prefix = `${name}=`;\n const inline = args.find(arg => arg.startsWith(prefix));\n if (inline) return inline.slice(prefix.length);\n const index = args.indexOf(name);\n if (index >= 0) return args[index + 1];\n return undefined;\n}\n\nexport function resolveStartOptions(config: LineageCliConfig, args: string[]): StartOptions {\n const runtimeDir = dataRoot(config.displayName);\n const rawPort = readOption(args, '--port') || process.env.PORT || String(config.defaultPort);\n const port = Number(rawPort);\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`Invalid port: ${rawPort}`);\n }\n return {\n dbPath: readOption(args, '--db') || process.env.LINEAGE_DB || join(runtimeDir, `${config.binName}.sqlite`),\n host: readOption(args, '--host') || process.env.HOST || config.defaultHost,\n json: args.includes('--json'),\n open: args.includes('--open'),\n port,\n };\n}\n\nfunction printHelp(config: LineageCliConfig): void {\n console.log(`${config.binName} ${packageVersion()}\n\nUsage:\n ${config.binName} start [--port <port>] [--host <host>] [--db <path>] [--open] [--json]\n ${config.binName} next [--project <project>] [--root <asset-id>] [--db <path>] [--json]\n ${config.binName} brief [--project <project>] [--root <asset-id>] [--db <path>] [--json]\n ${config.binName} inspect --asset-id <asset-id> [--project <project>] [--db <path>] [--json]\n ${config.binName} link-child --root <asset-id> --child <asset-id> [--project <project>] [--claim-token <claim-id.secret>] [--confirm-write] [--db <path>] [--json]\n ${config.binName} agent claim --project <project> --scope <scope> --target <target-id> --agent-name <name> [--channel <channel>] [--ttl 20m] [--json]\n ${config.binName} agent graph --root <asset-id> [--project <project>] [--db <path>] [--json]\n ${config.binName} agent status [--project <project>] [--json]\n ${config.binName} agent inspect --claim <claim-id> [--project <project>] [--json]\n ${config.binName} agent heartbeat --claim-token <claim-id.secret> [--json]\n ${config.binName} agent release --claim-token <claim-id.secret> [--json]\n ${config.binName} agent revoke --claim <claim-id> --project <project> --reason <text> --confirm-write [--json]\n ${config.binName} agent transfer --claim <claim-id> --to-agent-name <name> --confirm-write [--project <project>] [--json]\n ${config.binName} --help\n ${config.binName} --version\n\n${config.displayName} runs the bundled Lineage server for the ${config.channel} channel.`);\n}\n\nfunction openBrowser(url: string): void {\n const command = platform() === 'darwin' ? 'open' : platform() === 'win32' ? 'cmd' : 'xdg-open';\n const args = platform() === 'win32' ? ['/c', 'start', '', url] : [url];\n const opener = spawn(command, args, { detached: true, stdio: 'ignore' });\n opener.unref();\n}\n\nfunction positionalArgs(args: string[]): string[] {\n const values: string[] = [];\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n if (arg.startsWith('--')) {\n if (!arg.includes('=') && args[index + 1] && !args[index + 1].startsWith('--')) index += 1;\n continue;\n }\n values.push(arg);\n }\n return values;\n}\n\nfunction resolveDataCommandOptions(args: string[]): DataCommandOptions {\n const positions = positionalArgs(args);\n const options = {\n assetId: readOption(args, '--asset-id') || positions[0],\n childAssetId: readOption(args, '--child'),\n claimToken: readOption(args, '--claim-token') || process.env.LINEAGE_CLAIM_TOKEN,\n confirmWrite: args.includes('--confirm-write'),\n dbPath: readOption(args, '--db'),\n json: args.includes('--json'),\n project: readOption(args, '--project') || process.env.LINEAGE_DEFAULT_PRODUCT || defaultProduct,\n rootAssetId: readOption(args, '--root'),\n };\n if (options.dbPath) process.env.LINEAGE_DB = options.dbPath;\n return options;\n}\n\nexport function runLineageDataCommand(command: string, args: string[]): unknown {\n const options = resolveDataCommandOptions(args);\n if (command === 'next') return getLineageNextAsset(options.project, options.rootAssetId || options.assetId);\n if (command === 'brief') return getLineageBrief(options.project, options.rootAssetId || options.assetId);\n if (command === 'inspect') {\n if (!options.assetId) throw new Error('lineage inspect requires --asset-id');\n return getLineageSnapshot(options.project, options.assetId);\n }\n if (command === 'link-child') {\n if (!options.childAssetId) throw new Error('lineage link-child requires --child');\n return linkSelectedLineageChild(options.project, {\n childAssetId: options.childAssetId,\n claimToken: options.claimToken,\n confirmWrite: options.confirmWrite,\n rootAssetId: options.rootAssetId || options.assetId,\n });\n }\n throw new Error(`Unknown command: ${command}`);\n}\n\nfunction printDataResult(command: string, result: unknown, json: boolean): void {\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n if (command === 'next' && result && typeof result === 'object' && 'reason' in result) {\n const next = result as { next_asset?: { asset_id: string; title: string } | null; reason: string; root_asset_id: string };\n console.log(next.next_asset ? `${next.next_asset.asset_id}: ${next.next_asset.title}` : `No next asset: ${next.reason}`);\n console.log(`Root: ${next.root_asset_id}`);\n return;\n }\n if (command === 'brief' && result && typeof result === 'object' && 'brief' in result) {\n const brief = result as { brief: { title: string; prompt: string } };\n console.log(brief.brief.title);\n console.log(brief.brief.prompt);\n return;\n }\n if (command === 'inspect' && result && typeof result === 'object' && 'nodes' in result) {\n const snapshot = result as { active_asset_id: string; edges: unknown[]; nodes: unknown[]; root_asset_id: string };\n console.log(`${snapshot.root_asset_id}: ${snapshot.nodes.length} node(s), ${snapshot.edges.length} edge(s)`);\n console.log(`Active: ${snapshot.active_asset_id}`);\n return;\n }\n if (command === 'link-child' && result && typeof result === 'object') {\n const link = result as { dryRun?: boolean; edge?: { child_asset_id: string; parent_asset_id: string }; message?: string };\n console.log(link.message || `${link.dryRun ? 'Dry run: ' : ''}Link ${link.edge?.child_asset_id || 'child'} from ${link.edge?.parent_asset_id || 'parent'}`);\n return;\n }\n console.log(String(result));\n}\n\nexport function runLineageAgentCommand(command: string, args: string[]): unknown {\n const dbPath = readOption(args, '--db');\n if (dbPath) process.env.LINEAGE_DB = dbPath;\n const project = readOption(args, '--project') || process.env.LINEAGE_DEFAULT_PRODUCT || defaultProduct;\n const claimId = readOption(args, '--claim');\n const claimToken = readOption(args, '--claim-token') || process.env.LINEAGE_CLAIM_TOKEN;\n if (command === 'claim') {\n return createAgentClaim({\n agentId: readOption(args, '--agent-id'),\n agentKind: readOption(args, '--agent-kind'),\n agentName: readOption(args, '--agent-name') || '',\n channel: readOption(args, '--channel'),\n force: args.includes('--force'),\n project,\n reason: readOption(args, '--reason'),\n scopeType: (readOption(args, '--scope') || '') as AgentClaimScopeType,\n targetId: readOption(args, '--target') || '',\n targetTitle: readOption(args, '--target-title'),\n threadId: readOption(args, '--thread-id'),\n ttlSeconds: parseClaimTtl(readOption(args, '--ttl')),\n });\n }\n if (command === 'status') return listAgentClaims(project);\n if (command === 'graph') {\n const rootAssetId = readOption(args, '--root') || readOption(args, '--asset-id') || positionalArgs(args)[0];\n if (!rootAssetId) throw new Error('lineage agent graph requires --root');\n return getLineageSnapshot(project, rootAssetId);\n }\n if (command === 'inspect') {\n if (!claimId) throw new Error('lineage agent inspect requires --claim');\n return inspectAgentClaim(claimId, project);\n }\n if (command === 'heartbeat') {\n if (!claimToken) throw new Error('lineage agent heartbeat requires --claim-token');\n return heartbeatAgentClaim(claimToken, parseClaimTtl(readOption(args, '--ttl')));\n }\n if (command === 'release') {\n if (!claimToken) throw new Error('lineage agent release requires --claim-token');\n return releaseAgentClaim(claimToken);\n }\n if (command === 'revoke') {\n if (!claimId) throw new Error('lineage agent revoke requires --claim');\n return revokeAgentClaim(project, claimId, {\n actor: readOption(args, '--actor') || 'human',\n confirmWrite: args.includes('--confirm-write'),\n reason: readOption(args, '--reason'),\n });\n }\n if (command === 'transfer') {\n if (!claimId) throw new Error('lineage agent transfer requires --claim');\n return transferAgentClaim(project, claimId, {\n actor: readOption(args, '--actor') || 'human',\n confirmWrite: args.includes('--confirm-write'),\n reason: readOption(args, '--reason'),\n toAgentName: readOption(args, '--to-agent-name') || '',\n });\n }\n throw new Error(`Unknown agent command: ${command}`);\n}\n\nfunction printAgentResult(command: string, result: unknown, json: boolean): void {\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n if (command === 'claim' && result && typeof result === 'object' && 'claim' in result) {\n const created = result as { claim?: { id: string; target_id: string }; claim_token?: string };\n console.log(`Claimed ${created.claim?.target_id || 'target'} as ${created.claim?.id || 'claim'}`);\n if (created.claim_token) console.log(`Token: ${created.claim_token}`);\n return;\n }\n if (command === 'status' && result && typeof result === 'object' && 'claims' in result) {\n const status = result as { claims: Array<{ agent_name: string; derived_state: string; target_id: string }> };\n if (status.claims.length === 0) {\n console.log('No agent claims.');\n return;\n }\n for (const claim of status.claims) console.log(`${claim.agent_name} ${claim.derived_state} ${claim.target_id}`);\n return;\n }\n if (result && typeof result === 'object' && 'claim' in result) {\n const inspected = result as { claim?: { id: string; status: string; target_id: string } };\n console.log(`${inspected.claim?.id || 'claim'} ${inspected.claim?.status || 'unknown'} ${inspected.claim?.target_id || ''}`.trim());\n return;\n }\n if (command === 'graph' && result && typeof result === 'object' && 'nodes' in result) {\n console.log(formatAgentGraphDigest(result as AgentGraphDigestSnapshot));\n return;\n }\n console.log(String(result));\n}\n\ninterface AgentGraphDigestSnapshot {\n active_asset_id: string;\n edges: Array<{ child_asset_id: string; parent_asset_id: string }>;\n latest?: string[];\n nodes: Array<{ asset_id: string; is_latest?: boolean; title?: string }>;\n root_asset_id: string;\n selected?: string[];\n}\n\nexport function formatAgentGraphDigest(snapshot: AgentGraphDigestSnapshot): string {\n const lines: string[] = [];\n const titleFor = (assetId: string) => {\n const node = snapshot.nodes.find(item => item.asset_id === assetId);\n return node?.title ? `${node.title} (${assetId})` : assetId;\n };\n const root = snapshot.nodes.find(node => node.asset_id === snapshot.root_asset_id);\n lines.push(`Lineage graph: ${root?.title || snapshot.root_asset_id}`);\n lines.push(`Root: ${snapshot.root_asset_id}`);\n lines.push(`Active: ${titleFor(snapshot.active_asset_id)}`);\n lines.push(`Nodes: ${snapshot.nodes.length} Edges: ${snapshot.edges.length}`);\n const selected = snapshot.selected || [];\n if (selected.length > 0) {\n lines.push('Next variation:');\n for (const assetId of selected) lines.push(`- ${titleFor(assetId)}`);\n }\n const latest = snapshot.latest || snapshot.nodes.filter(node => node.is_latest).map(node => node.asset_id);\n if (latest.length > 0) {\n lines.push('Latest leaves:');\n for (const assetId of latest) lines.push(`- ${titleFor(assetId)}`);\n }\n lines.push('Edges:');\n for (const edge of snapshot.edges) lines.push(`- ${titleFor(edge.parent_asset_id)} -> ${titleFor(edge.child_asset_id)}`);\n return lines.join('\\n');\n}\n\nfunction start(config: LineageCliConfig, args: string[]): void {\n let options: StartOptions;\n const json = args.includes('--json');\n try {\n options = resolveStartOptions(config, args);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (json) console.error(JSON.stringify({ ok: false, error: message }, null, 2));\n else console.error(`${config.binName}: ${message}`);\n process.exit(1);\n }\n const serverPath = join(packageRoot(), 'dist', 'server.js');\n if (!existsSync(serverPath)) {\n const message = `Missing bundled server at ${serverPath}. Run npm run build before using ${config.binName} start from a source checkout.`;\n if (options.json) console.error(JSON.stringify({ ok: false, error: message }, null, 2));\n else console.error(`${config.binName}: ${message}`);\n process.exit(1);\n }\n\n mkdirSync(dirname(options.dbPath), { recursive: true });\n const url = `http://${options.host}:${options.port}`;\n if (options.json) {\n console.log(JSON.stringify({ channel: config.channel, dbPath: options.dbPath, host: options.host, port: options.port, status: 'starting', url }, null, 2));\n } else {\n console.log(`${config.displayName} starting at ${url}`);\n console.log(`SQLite: ${options.dbPath}`);\n }\n if (options.open) openBrowser(url);\n\n const child = spawn(process.execPath, [serverPath], {\n env: {\n ...process.env,\n HOST: options.host,\n LINEAGE_CHANNEL: config.channel,\n LINEAGE_DB: options.dbPath,\n NODE_ENV: 'production',\n PORT: String(options.port),\n },\n stdio: 'inherit',\n });\n\n let forwardedSignal: NodeJS.Signals | undefined;\n const stop = (signal: NodeJS.Signals) => {\n forwardedSignal = signal;\n child.kill(signal);\n };\n process.once('SIGINT', stop);\n process.once('SIGTERM', stop);\n child.on('exit', code => process.exit(code ?? (forwardedSignal ? signalExitCodes[forwardedSignal] || 1 : 0)));\n child.on('error', error => {\n console.error(`${config.binName}: failed to start server: ${error.message}`);\n process.exit(1);\n });\n}\n\nexport function runLineageCli(config: LineageCliConfig, args = process.argv.slice(2)): void {\n if (args.includes('--help') || args.includes('-h') || args.length === 0) {\n printHelp(config);\n process.exit(0);\n }\n\n if (args.includes('--version') || args.includes('-v')) {\n console.log(packageVersion());\n process.exit(0);\n }\n\n const normalizedArgs = args[0] === 'lineage' ? args.slice(1) : args;\n const [command] = normalizedArgs;\n if (command === 'start') {\n start(config, normalizedArgs.slice(1));\n return;\n }\n\n if (command === 'next' || command === 'brief' || command === 'inspect' || command === 'link-child') {\n const commandArgs = normalizedArgs.slice(1);\n const json = commandArgs.includes('--json');\n try {\n printDataResult(command, runLineageDataCommand(command, commandArgs), json);\n } catch (error) {\n const message = redactAgentClaimTokens(error instanceof Error ? error.message : String(error));\n if (json) {\n const output = isAgentClaimError(error)\n ? { ok: false, command, error: error.code, message, conflicts: error.conflicts }\n : { ok: false, command, error: message };\n console.error(JSON.stringify(output, null, 2));\n }\n else console.error(`${config.binName}: ${message}`);\n process.exit(1);\n }\n process.exit(0);\n }\n\n if (command === 'agent') {\n const commandArgs = normalizedArgs.slice(2);\n const agentCommand = normalizedArgs[1] || '';\n const json = commandArgs.includes('--json');\n try {\n printAgentResult(agentCommand, runLineageAgentCommand(agentCommand, commandArgs), json);\n } catch (error) {\n const message = redactAgentClaimTokens(error instanceof Error ? error.message : String(error));\n if (json) {\n const output = isAgentClaimError(error)\n ? { ok: false, command: `agent ${agentCommand}`, error: error.code, message, conflicts: error.conflicts }\n : { ok: false, command: `agent ${agentCommand}`, error: message };\n console.error(JSON.stringify(output, null, 2));\n } else {\n console.error(`${config.binName}: ${message}`);\n }\n process.exit(1);\n }\n process.exit(0);\n }\n\n const json = args.includes('--json');\n const message = `Unknown command: ${command}`;\n if (json) console.error(JSON.stringify({ ok: false, command, error: message }, null, 2));\n else console.error(`${config.binName}: ${message}`);\n process.exit(1);\n}\n", "import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';\nimport { lineageDb, nowIso, type DatabaseSync } from './assetLineageDb';\n\nexport type AgentClaimScopeType = 'lineage_workspace' | 'content_post' | 'content_queue_lane' | 'selection_set' | 'project_channel';\ntype AgentClaimStatus = 'active' | 'expired' | 'released' | 'revoked' | 'transferred';\n\nexport interface AgentClaim {\n id: string;\n project: string;\n channel?: string;\n scope_type: AgentClaimScopeType;\n target_id: string;\n target_title?: string;\n agent_id?: string;\n agent_name: string;\n agent_kind: string;\n thread_id?: string;\n status: AgentClaimStatus;\n created_at: string;\n heartbeat_at: string;\n expires_at: string;\n released_at?: string;\n revoked_at?: string;\n revoked_by?: string;\n override_reason?: string;\n metadata?: Record<string, unknown>;\n heartbeat_age_seconds: number;\n derived_state: 'active' | 'idle' | 'stale' | 'expired';\n}\n\ninterface AgentClaimEvent {\n claim_id: string;\n event_type: string;\n actor?: string;\n message?: string;\n created_at: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CreateAgentClaimFields {\n project: string;\n channel?: string;\n scopeType: AgentClaimScopeType;\n targetId: string;\n targetTitle?: string;\n agentId?: string;\n agentName: string;\n agentKind?: string;\n threadId?: string;\n ttlSeconds?: number;\n force?: boolean;\n reason?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ValidateAgentClaimForWriteFields {\n claimToken?: string;\n project: string;\n channel?: string;\n scopeType: AgentClaimScopeType;\n targetId: string;\n writeKind: string;\n dangerLevel: 'claim' | 'warn' | 'enforce' | 'danger';\n confirmWrite?: boolean;\n}\n\nexport type AgentClaimValidationResult =\n | { ok: true; claim: AgentClaim; warnings: string[] }\n | { ok: false; code: string; message: string; conflicts: AgentClaim[] };\n\ntype Row = Record<string, unknown>;\n\nconst defaultTtlSeconds = 20 * 60;\nconst idleAfterSeconds = 5 * 60;\nconst staleAfterSeconds = 15 * 60;\nconst scopes = new Set<AgentClaimScopeType>(['lineage_workspace', 'content_post', 'content_queue_lane', 'selection_set', 'project_channel']);\nconst claimTokenPattern = /claim_[a-z0-9_-]+\\.[A-Za-z0-9_-]+/g;\n\nexport class AgentClaimError extends Error {\n constructor(message: string, public status = 400, public code = 'agent_claim_error', public conflicts: AgentClaim[] = []) {\n super(message);\n }\n}\n\nexport function isAgentClaimError(error: unknown): error is AgentClaimError {\n return error instanceof AgentClaimError;\n}\n\nexport function redactAgentClaimTokens(input: string): string {\n return input.replace(claimTokenPattern, '[redacted-claim-token]');\n}\n\nexport function parseClaimTtl(value?: string): number {\n if (!value) return defaultTtlSeconds;\n const match = value.trim().match(/^(\\d+)(s|m|h)?$/);\n if (!match) throw new AgentClaimError(`Invalid claim ttl: ${value}`);\n const amount = Number(match[1]);\n const unit = match[2] || 's';\n const multiplier = unit === 'h' ? 3600 : unit === 'm' ? 60 : 1;\n const seconds = amount * multiplier;\n if (!Number.isInteger(seconds) || seconds < 30 || seconds > 24 * 60 * 60) {\n throw new AgentClaimError('Claim ttl must be between 30 seconds and 24 hours');\n }\n return seconds;\n}\n\nfunction randomId(prefix: string): string {\n return `${prefix}_${Date.now().toString(36)}_${randomBytes(6).toString('base64url').toLowerCase()}`;\n}\n\nfunction tokenHash(token: string): string {\n return createHash('sha256').update(token).digest('hex');\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const left = Buffer.from(a);\n const right = Buffer.from(b);\n return left.length === right.length && timingSafeEqual(left, right);\n}\n\nfunction expiresAtFrom(timestamp: string, ttlSeconds: number): string {\n return new Date(new Date(timestamp).getTime() + ttlSeconds * 1000).toISOString();\n}\n\nfunction metadataJson(metadata?: Record<string, unknown>): string | null {\n return metadata ? JSON.stringify(metadata) : null;\n}\n\nfunction parseMetadata(value: unknown): Record<string, unknown> | undefined {\n if (typeof value !== 'string' || !value) return undefined;\n try {\n const parsed = JSON.parse(value) as unknown;\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed as Record<string, unknown> : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction derivedState(row: { status: AgentClaimStatus; heartbeat_at: string; expires_at: string }, now = new Date()): AgentClaim['derived_state'] {\n if (row.status !== 'active') return row.status === 'expired' ? 'expired' : 'stale';\n if (new Date(row.expires_at).getTime() <= now.getTime()) return 'expired';\n const ageSeconds = Math.max(0, Math.floor((now.getTime() - new Date(row.heartbeat_at).getTime()) / 1000));\n if (ageSeconds >= staleAfterSeconds) return 'stale';\n if (ageSeconds >= idleAfterSeconds) return 'idle';\n return 'active';\n}\n\nfunction rowToClaim(row: Row, now = new Date()): AgentClaim {\n const heartbeatAt = String(row.heartbeat_at);\n return {\n id: String(row.id),\n project: String(row.project_id),\n channel: typeof row.channel === 'string' ? row.channel : undefined,\n scope_type: String(row.scope_type) as AgentClaimScopeType,\n target_id: String(row.target_id),\n target_title: typeof row.target_title === 'string' ? row.target_title : undefined,\n agent_id: typeof row.agent_id === 'string' ? row.agent_id : undefined,\n agent_name: String(row.agent_name),\n agent_kind: String(row.agent_kind),\n thread_id: typeof row.thread_id === 'string' ? row.thread_id : undefined,\n status: String(row.status) as AgentClaimStatus,\n created_at: String(row.created_at),\n heartbeat_at: heartbeatAt,\n expires_at: String(row.expires_at),\n released_at: typeof row.released_at === 'string' ? row.released_at : undefined,\n revoked_at: typeof row.revoked_at === 'string' ? row.revoked_at : undefined,\n revoked_by: typeof row.revoked_by === 'string' ? row.revoked_by : undefined,\n override_reason: typeof row.override_reason === 'string' ? row.override_reason : undefined,\n metadata: parseMetadata(row.metadata_json),\n heartbeat_age_seconds: Math.max(0, Math.floor((now.getTime() - new Date(heartbeatAt).getTime()) / 1000)),\n derived_state: derivedState({\n expires_at: String(row.expires_at),\n heartbeat_at: heartbeatAt,\n status: String(row.status) as AgentClaimStatus,\n }, now),\n };\n}\n\nfunction eventToRow(row: Row): AgentClaimEvent {\n return {\n claim_id: String(row.claim_id),\n event_type: String(row.event_type),\n actor: typeof row.actor === 'string' ? row.actor : undefined,\n message: typeof row.message === 'string' ? row.message : undefined,\n created_at: String(row.created_at),\n metadata: parseMetadata(row.metadata_json),\n };\n}\n\nfunction ensureProject(database: DatabaseSync, project: string): void {\n const timestamp = nowIso();\n database.prepare(`\n insert into projects (id, product, created_at, updated_at)\n values (?, ?, ?, ?)\n on conflict(id) do update set product = excluded.product, updated_at = excluded.updated_at\n `).run(project, project, timestamp, timestamp);\n}\n\nfunction recordEvent(database: DatabaseSync, claimId: string, eventType: string, actor?: string, message?: string, metadata?: Record<string, unknown>): void {\n database.prepare(`\n insert into agent_claim_events (id, claim_id, event_type, actor, message, created_at, metadata_json)\n values (?, ?, ?, ?, ?, ?, ?)\n `).run(randomId('claim_event'), claimId, eventType, actor || null, message || null, nowIso(), metadataJson(metadata));\n}\n\nfunction expireActiveClaims(database: DatabaseSync): void {\n const timestamp = nowIso();\n const expired = database.prepare(`\n select id from agent_claims where status = 'active' and expires_at <= ?\n `).all(timestamp) as Array<{ id: string }>;\n if (expired.length === 0) return;\n database.prepare(`\n update agent_claims set status = 'expired' where status = 'active' and expires_at <= ?\n `).run(timestamp);\n for (const claim of expired) recordEvent(database, claim.id, 'expired', 'system', 'Claim expired after missed heartbeat.');\n}\n\nfunction normalizeScope(scopeType: AgentClaimScopeType): AgentClaimScopeType {\n if (!scopes.has(scopeType)) throw new AgentClaimError(`Unsupported claim scope: ${scopeType}`);\n return scopeType;\n}\n\nfunction channelOverlaps(left?: string, right?: string): boolean {\n return !left || !right || left === right;\n}\n\nfunction claimOverlaps(candidate: Pick<AgentClaim, 'project' | 'channel' | 'scope_type' | 'target_id'>, existing: AgentClaim): boolean {\n if (candidate.project !== existing.project) return false;\n if (!channelOverlaps(candidate.channel, existing.channel)) return false;\n if (candidate.scope_type === existing.scope_type && candidate.target_id === existing.target_id) return true;\n return candidate.scope_type === 'project_channel' || existing.scope_type === 'project_channel';\n}\n\nfunction activeClaims(database: DatabaseSync, project?: string): AgentClaim[] {\n const rows = project\n ? database.prepare(\"select * from agent_claims where project_id = ? and status = 'active' order by heartbeat_at desc\").all(project)\n : database.prepare(\"select * from agent_claims where status = 'active' order by project_id, heartbeat_at desc\").all();\n return (rows as Row[]).map(row => rowToClaim(row));\n}\n\nfunction findClaimById(database: DatabaseSync, claimId: string, project?: string): AgentClaim | null {\n const row = project\n ? database.prepare('select * from agent_claims where project_id = ? and id = ?').get(project, claimId)\n : database.prepare('select * from agent_claims where id = ?').get(claimId);\n return row ? rowToClaim(row as Row) : null;\n}\n\nfunction findClaimRowByToken(database: DatabaseSync, claimToken: string): Row | null {\n const claimId = claimToken.split('.')[0];\n const row = database.prepare('select * from agent_claims where id = ?').get(claimId) as Row | undefined;\n if (!row) return null;\n return safeEqual(String(row.token_hash), tokenHash(claimToken)) ? row : null;\n}\n\nfunction denied(code: string, message: string, conflicts: AgentClaim[] = []): AgentClaimValidationResult {\n return { ok: false, code, message, conflicts };\n}\n\nfunction scopeAllowsWrite(claim: AgentClaim, scopeType: AgentClaimScopeType, targetId: string, writeKind: string): boolean {\n if (claim.scope_type === scopeType && claim.target_id === targetId) return true;\n if (claim.scope_type === 'project_channel') return true;\n if (claim.scope_type === 'lineage_workspace' && scopeType === 'lineage_workspace') return claim.target_id === targetId;\n if (claim.scope_type === 'content_queue_lane' && writeKind === 'content_queue_next') return true;\n return false;\n}\n\nexport function createAgentClaim(fields: CreateAgentClaimFields) {\n const project = fields.project.trim();\n const targetId = fields.targetId.trim();\n const agentName = fields.agentName.trim();\n if (!project) throw new AgentClaimError('Agent claim requires project');\n if (!targetId) throw new AgentClaimError('Agent claim requires target');\n if (!agentName) throw new AgentClaimError('Agent claim requires agent name');\n const scopeType = normalizeScope(fields.scopeType);\n const ttlSeconds = fields.ttlSeconds || defaultTtlSeconds;\n const database = lineageDb();\n try {\n ensureProject(database, project);\n expireActiveClaims(database);\n const candidate = { project, channel: fields.channel?.trim() || undefined, scope_type: scopeType, target_id: targetId };\n const conflicts = activeClaims(database, project).filter(claim => claimOverlaps(candidate, claim));\n if (conflicts.length > 0 && !fields.force) {\n throw new AgentClaimError('Target already has an active overlapping agent claim.', 409, 'target_already_claimed', conflicts);\n }\n if (conflicts.length > 0 && !fields.reason?.trim()) {\n throw new AgentClaimError('Overriding an active claim requires --reason.', 400, 'override_reason_required', conflicts);\n }\n const timestamp = nowIso();\n for (const conflict of conflicts) {\n database.prepare(`\n update agent_claims\n set status = 'revoked', revoked_at = ?, revoked_by = ?, override_reason = ?\n where id = ? and status = 'active'\n `).run(timestamp, agentName, fields.reason || null, conflict.id);\n recordEvent(database, conflict.id, 'revoked', agentName, fields.reason || 'Revoked by forced claim takeover.');\n recordEvent(database, conflict.id, 'conflict', agentName, `Overridden by ${agentName}.`, { new_claim_target: targetId });\n }\n const id = randomId('claim');\n const secret = randomBytes(24).toString('base64url');\n const claimToken = `${id}.${secret}`;\n const expiresAt = expiresAtFrom(timestamp, ttlSeconds);\n database.prepare(`\n insert into agent_claims (\n id, token_hash, project_id, channel, scope_type, target_id, target_title, agent_id, agent_name,\n agent_kind, thread_id, status, created_at, heartbeat_at, expires_at, metadata_json\n ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?, ?)\n `).run(\n id,\n tokenHash(claimToken),\n project,\n candidate.channel || null,\n scopeType,\n targetId,\n fields.targetTitle?.trim() || null,\n fields.agentId?.trim() || null,\n agentName,\n fields.agentKind?.trim() || 'codex',\n fields.threadId?.trim() || null,\n timestamp,\n timestamp,\n expiresAt,\n metadataJson(fields.metadata)\n );\n recordEvent(database, id, 'created', agentName, `Claimed ${scopeType} ${targetId}.`, { ttl_seconds: ttlSeconds });\n const claim = findClaimById(database, id);\n return { ok: true as const, claim, claim_token: claimToken, conflicts_revoked: conflicts.map(conflict => conflict.id) };\n } finally {\n database.close();\n }\n}\n\nexport function listAgentClaims(project?: string) {\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const rows = project\n ? database.prepare('select * from agent_claims where project_id = ? order by status, heartbeat_at desc').all(project)\n : database.prepare('select * from agent_claims order by project_id, status, heartbeat_at desc').all();\n return { ok: true as const, claims: (rows as Row[]).map(row => rowToClaim(row)), fetchedAt: nowIso() };\n } finally {\n database.close();\n }\n}\n\nexport function inspectAgentClaim(claimId: string, project?: string) {\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const claim = findClaimById(database, claimId, project);\n if (!claim) throw new AgentClaimError(`Unknown agent claim: ${claimId}`, 404, 'claim_not_found');\n const events = database.prepare('select * from agent_claim_events where claim_id = ? order by created_at').all(claim.id) as Row[];\n return { ok: true as const, claim, events: events.map(eventToRow) };\n } finally {\n database.close();\n }\n}\n\nexport function heartbeatAgentClaim(claimToken: string, ttlSeconds = defaultTtlSeconds) {\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const row = findClaimRowByToken(database, claimToken);\n if (!row) throw new AgentClaimError('Unknown or invalid agent claim token.', 401, 'claim_token_invalid');\n const claim = rowToClaim(row);\n if (claim.status !== 'active') throw new AgentClaimError(`Agent claim is ${claim.status}.`, 409, 'claim_not_active');\n const timestamp = nowIso();\n database.prepare('update agent_claims set heartbeat_at = ?, expires_at = ? where id = ?').run(timestamp, expiresAtFrom(timestamp, ttlSeconds), claim.id);\n recordEvent(database, claim.id, 'heartbeat', claim.agent_name, 'Claim heartbeat received.');\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function releaseAgentClaim(claimToken: string) {\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const row = findClaimRowByToken(database, claimToken);\n if (!row) throw new AgentClaimError('Unknown or invalid agent claim token.', 401, 'claim_token_invalid');\n const claim = rowToClaim(row);\n if (claim.status !== 'active') throw new AgentClaimError(`Agent claim is ${claim.status}.`, 409, 'claim_not_active');\n const timestamp = nowIso();\n database.prepare(\"update agent_claims set status = 'released', released_at = ? where id = ?\").run(timestamp, claim.id);\n recordEvent(database, claim.id, 'released', claim.agent_name, 'Claim released by token holder.');\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function releaseStaleAgentClaim(project: string, claimId: string, fields: { actor?: string; confirmWrite: boolean; reason?: string }) {\n if (!fields.confirmWrite) throw new AgentClaimError('Releasing a stale agent claim requires confirmWrite=true.', 400, 'confirm_write_required');\n if (!fields.reason?.trim()) throw new AgentClaimError('Releasing a stale agent claim requires a reason.', 400, 'reason_required');\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const claim = findClaimById(database, claimId, project);\n if (!claim) throw new AgentClaimError(`Unknown agent claim: ${claimId}`, 404, 'claim_not_found');\n if (claim.status !== 'active' || claim.derived_state !== 'stale') {\n throw new AgentClaimError('Only stale active claims can be released without the claim token.', 409, 'claim_not_stale', [claim]);\n }\n const timestamp = nowIso();\n database.prepare(\"update agent_claims set status = 'released', released_at = ?, revoked_by = ?, override_reason = ? where id = ?\").run(timestamp, fields.actor || 'human', fields.reason, claim.id);\n recordEvent(database, claim.id, 'released', fields.actor || 'human', fields.reason);\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function revokeAgentClaim(project: string, claimId: string, fields: { actor?: string; confirmWrite: boolean; reason?: string }) {\n if (!fields.confirmWrite) throw new AgentClaimError('Revoking an agent claim requires confirmWrite=true.', 400, 'confirm_write_required');\n if (!fields.reason?.trim()) throw new AgentClaimError('Revoking an agent claim requires a reason.', 400, 'reason_required');\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const claim = findClaimById(database, claimId, project);\n if (!claim) throw new AgentClaimError(`Unknown agent claim: ${claimId}`, 404, 'claim_not_found');\n const timestamp = nowIso();\n database.prepare(`\n update agent_claims set status = 'revoked', revoked_at = ?, revoked_by = ?, override_reason = ?\n where id = ?\n `).run(timestamp, fields.actor || 'human', fields.reason, claim.id);\n recordEvent(database, claim.id, 'revoked', fields.actor || 'human', fields.reason);\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function transferAgentClaim(project: string, claimId: string, fields: { confirmWrite: boolean; toAgentName: string; actor?: string; reason?: string }) {\n if (!fields.confirmWrite) throw new AgentClaimError('Transferring an agent claim requires confirmWrite=true.', 400, 'confirm_write_required');\n const toAgentName = fields.toAgentName.trim();\n if (!toAgentName) throw new AgentClaimError('Transfer requires toAgentName.', 400, 'agent_name_required');\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const claim = findClaimById(database, claimId, project);\n if (!claim) throw new AgentClaimError(`Unknown agent claim: ${claimId}`, 404, 'claim_not_found');\n if (claim.status !== 'active') throw new AgentClaimError(`Agent claim is ${claim.status}.`, 409, 'claim_not_active');\n database.prepare('update agent_claims set agent_name = ? where id = ?').run(toAgentName, claim.id);\n recordEvent(database, claim.id, 'transferred', fields.actor || 'human', fields.reason || `Transferred claim to ${toAgentName}.`, { to_agent_name: toAgentName });\n return { ok: true as const, claim: findClaimById(database, claim.id) };\n } finally {\n database.close();\n }\n}\n\nexport function validateAgentClaimForWrite(fields: ValidateAgentClaimForWriteFields): AgentClaimValidationResult {\n if (fields.dangerLevel === 'danger' && !fields.confirmWrite) {\n return denied('human_confirmation_required', 'Dangerous write requires explicit human confirmation.');\n }\n if (!fields.claimToken) return denied('claim_required', 'Mutating agent write requires a matching claim token.');\n const database = lineageDb();\n try {\n expireActiveClaims(database);\n const row = findClaimRowByToken(database, fields.claimToken);\n if (!row) return denied('claim_token_invalid', 'Unknown or invalid claim token.');\n const claim = rowToClaim(row);\n if (claim.status !== 'active') return denied('claim_not_active', `Agent claim is ${claim.status}.`);\n if (new Date(claim.expires_at).getTime() <= Date.now()) return denied('claim_expired', 'Agent claim has expired.');\n if (claim.project !== fields.project) return denied('claim_project_mismatch', `Claim project ${claim.project} does not match ${fields.project}.`, [claim]);\n if (fields.channel && claim.channel && claim.channel !== fields.channel) {\n return denied('claim_channel_mismatch', `Claim channel ${claim.channel} does not match ${fields.channel}.`, [claim]);\n }\n if (!scopeAllowsWrite(claim, fields.scopeType, fields.targetId, fields.writeKind)) {\n return denied('claim_scope_mismatch', `Claim does not cover ${fields.scopeType} ${fields.targetId}.`, [claim]);\n }\n recordEvent(database, claim.id, 'write_allowed', claim.agent_name, `${fields.writeKind} allowed.`, {\n danger_level: fields.dangerLevel,\n target_id: fields.targetId,\n write_kind: fields.writeKind,\n });\n return { ok: true, claim, warnings: [] };\n } finally {\n database.close();\n }\n}\n", "import { createRequire } from 'node:module';\nimport type { DatabaseSync as DatabaseSyncType } from 'node:sqlite';\nimport { mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { repoRoot } from './assetCore';\n\nconst require = createRequire(import.meta.url);\nexport type DatabaseSync = DatabaseSyncType;\n\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n\nexport function lineageDbPath(): string {\n return process.env.LINEAGE_DB || join(repoRoot, '.lineage', 'asset-lineage.sqlite');\n}\n\nexport function lineageDb(): DatabaseSync {\n mkdirSync(join(lineageDbPath(), '..'), { recursive: true });\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const database = new DatabaseSync(lineageDbPath());\n database.exec('PRAGMA foreign_keys = ON'); database.exec('PRAGMA busy_timeout = 5000');\n database.exec(`\n create table if not exists projects (\n id text primary key,\n product text not null,\n catalog_path text,\n created_at text not null,\n updated_at text not null\n );\n create table if not exists assets (\n id text primary key,\n project_id text not null references projects(id),\n source text not null check (source in ('local', 'catalog')),\n local_path text,\n s3_key text,\n checksum_sha256 text,\n media_type text not null,\n title text not null,\n status text not null,\n channel text,\n campaign text,\n audience text,\n size_bytes integer,\n content_type text,\n created_at text not null,\n updated_at text not null,\n last_seen_at text not null\n );\n create index if not exists assets_project_source_seen on assets(project_id, source, last_seen_at);\n create index if not exists assets_project_checksum on assets(project_id, checksum_sha256);\n create index if not exists assets_project_channel_campaign on assets(project_id, channel, campaign);\n create table if not exists asset_edges (\n id text primary key,\n project_id text not null references projects(id),\n parent_asset_id text not null references assets(id),\n child_asset_id text not null references assets(id),\n relation_type text not null check (relation_type in ('derived_from')),\n created_at text not null,\n unique (project_id, parent_asset_id, child_asset_id, relation_type)\n );\n create index if not exists edges_parent on asset_edges(project_id, parent_asset_id);\n create index if not exists edges_child on asset_edges(project_id, child_asset_id);\n create table if not exists asset_reviews (\n asset_id text primary key references assets(id),\n review_state text not null check (review_state in ('unreviewed', 'approved', 'needs_revision', 'rejected', 'ignored')),\n reviewed_at text,\n ignored_at text,\n notes text,\n updated_at text not null\n );\n create table if not exists asset_selections (\n id text primary key,\n project_id text not null references projects(id),\n root_asset_id text not null references assets(id),\n asset_id text not null references assets(id),\n notes text,\n selected_at text not null,\n unique(project_id, root_asset_id)\n );\n create table if not exists asset_layouts (\n id text primary key,\n project_id text not null references projects(id),\n root_asset_id text not null references assets(id),\n asset_id text not null references assets(id),\n x real not null,\n y real not null,\n updated_at text not null,\n unique(project_id, root_asset_id, asset_id)\n );\n create table if not exists lineage_workspaces (\n id text primary key,\n project_id text not null references projects(id),\n root_asset_id text not null references assets(id),\n title text not null,\n status text not null check (status in ('active', 'paused', 'archived')),\n notes text,\n created_by text not null check (created_by in ('human', 'agent', 'system')),\n active_at text,\n created_at text not null,\n updated_at text not null,\n unique(project_id, root_asset_id)\n );\n create index if not exists lineage_workspaces_project_status on lineage_workspaces(project_id, status, updated_at);\n create index if not exists lineage_workspaces_project_active on lineage_workspaces(project_id, active_at);\n create table if not exists asset_ledger_records (\n id text primary key,\n project_id text not null references projects(id),\n canonical_asset_id text not null,\n checksum_sha256 text,\n media_type text not null,\n title text not null,\n status text not null,\n channel text,\n campaign text,\n audience text,\n created_at text not null,\n updated_at text not null,\n first_seen_at text not null default (datetime('now')),\n last_seen_at text not null\n );\n create index if not exists asset_ledger_records_project_seen on asset_ledger_records(project_id, last_seen_at);\n create index if not exists asset_ledger_records_project_checksum on asset_ledger_records(project_id, checksum_sha256);\n create table if not exists asset_ledger_sources (\n id text primary key,\n project_id text not null references projects(id),\n record_id text not null references asset_ledger_records(id) on delete cascade,\n source_type text not null check (source_type in ('local', 'catalog', 's3')),\n asset_id text,\n local_path text,\n s3_bucket text,\n s3_region text,\n s3_key text,\n s3_version_id text,\n etag text,\n size_bytes integer,\n content_type text,\n updated_at text,\n first_seen_at text not null default (datetime('now')),\n last_seen_at text not null\n );\n create index if not exists asset_ledger_sources_project_type on asset_ledger_sources(project_id, source_type);\n create index if not exists asset_ledger_sources_record on asset_ledger_sources(project_id, record_id);\n create index if not exists asset_ledger_sources_s3_key on asset_ledger_sources(project_id, s3_key);\n create table if not exists asset_ledger_placements (\n id text primary key,\n project_id text not null references projects(id),\n asset_id text not null,\n channel text not null,\n status text not null,\n scheduled_at text,\n posted_at text,\n url text,\n notes text,\n updated_at text not null,\n synced_at text not null,\n unique(project_id, asset_id, channel)\n );\n create index if not exists asset_ledger_placements_project_status on asset_ledger_placements(project_id, status);\n create index if not exists asset_ledger_placements_asset on asset_ledger_placements(project_id, asset_id);\n create table if not exists asset_ledger_index_runs (\n id text primary key,\n project_id text not null references projects(id),\n source_mode text not null check (source_mode in ('all', 'catalog', 'local')),\n include_live_s3 integer not null default 0,\n status text not null check (status in ('running', 'complete', 'failed')),\n started_at text not null,\n completed_at text,\n assets_indexed integer not null default 0,\n records_after integer not null default 0,\n catalog_sources_after integer not null default 0,\n local_sources_after integer not null default 0,\n s3_sources_after integer not null default 0,\n error text\n );\n create index if not exists asset_ledger_index_runs_project_started on asset_ledger_index_runs(project_id, started_at);\n create table if not exists content_batches (\n id text not null,\n project_id text not null references projects(id),\n title text not null,\n campaign text,\n channel text,\n status text not null check (status in ('active', 'archived')),\n notes text,\n created_at text not null,\n updated_at text not null,\n primary key(project_id, id)\n );\n create index if not exists content_batches_project_updated on content_batches(project_id, updated_at);\n create table if not exists content_posts (\n id text not null,\n project_id text not null references projects(id),\n batch_id text not null,\n channel text not null,\n title text not null,\n phase text not null check (phase in ('draft', 'review', 'scheduled', 'posted', 'skipped', 'archived')),\n campaign text,\n body text,\n cta text,\n scheduled_at text,\n posted_at text,\n url text,\n notes text,\n source_path text,\n created_at text not null,\n updated_at text not null,\n primary key(project_id, id),\n foreign key(project_id, batch_id) references content_batches(project_id, id) on delete cascade\n );\n create index if not exists content_posts_project_phase on content_posts(project_id, phase);\n create index if not exists content_posts_batch on content_posts(project_id, batch_id);\n create table if not exists content_post_assets (\n id text primary key,\n project_id text not null references projects(id),\n post_id text not null,\n asset_id text not null,\n role text not null,\n notes text,\n attached_at text not null,\n unique(project_id, post_id, asset_id, role),\n foreign key(project_id, post_id) references content_posts(project_id, id) on delete cascade\n );\n create index if not exists content_post_assets_post on content_post_assets(project_id, post_id);\n create index if not exists content_post_assets_asset on content_post_assets(project_id, asset_id);\n create table if not exists content_targets (\n project_id text primary key references projects(id),\n post_id text not null,\n notes text,\n selected_at text not null,\n updated_at text not null,\n foreign key(project_id, post_id) references content_posts(project_id, id) on delete cascade\n );\n create table if not exists selection_sets (\n id text primary key,\n project_id text not null references projects(id),\n kind text not null check (kind in ('current', 'review')),\n key text not null,\n label text not null,\n status text not null check (status in ('active', 'archived')),\n created_by text not null check (created_by in ('human', 'agent', 'system')),\n created_at text not null,\n updated_at text not null,\n unique(project_id, kind, key)\n );\n create index if not exists selection_sets_project_kind on selection_sets(project_id, kind, updated_at);\n create table if not exists selection_items (\n id text primary key,\n set_id text not null references selection_sets(id) on delete cascade,\n asset_id text not null,\n role text not null check (role in ('primary', 'candidate', 'next_base')),\n variation_label text,\n position integer not null default 0,\n selected_by text check (selected_by in ('human', 'agent', 'system')),\n selected_at text,\n deselected_at text,\n notes text,\n created_at text not null,\n updated_at text not null,\n unique(set_id, asset_id)\n );\n create index if not exists selection_items_set_position on selection_items(set_id, position);\n create unique index if not exists selection_items_set_label on selection_items(set_id, variation_label) where variation_label is not null;\n create table if not exists generation_jobs (\n id text primary key,\n project_id text not null references projects(id),\n provider text not null default 'codex-handoff',\n adapter_version text not null,\n source_mode text not null check (source_mode in ('lineage_selection')),\n root_asset_id text not null references assets(id),\n prompt text not null,\n expected_output_count integer not null check (expected_output_count > 0),\n status text not null check (status in ('planned', 'imported', 'failed', 'cancelled')),\n output_dir text,\n handoff_json text,\n created_at text not null,\n updated_at text not null,\n imported_at text\n );\n create index if not exists generation_jobs_project_created on generation_jobs(project_id, created_at);\n create table if not exists generation_job_inputs (\n id text primary key,\n job_id text not null references generation_jobs(id) on delete cascade,\n project_id text not null references projects(id),\n asset_id text not null references assets(id),\n root_asset_id text not null references assets(id),\n role text not null check (role in ('lineage_next_base', 'reference')),\n position integer not null,\n selection_strategy text not null,\n selection_snapshot_json text not null,\n unique(job_id, asset_id, role)\n );\n create index if not exists generation_job_inputs_job on generation_job_inputs(job_id, position);\n create table if not exists generation_job_outputs (\n id text primary key,\n job_id text not null references generation_jobs(id) on delete cascade,\n project_id text not null references projects(id),\n output_index integer not null,\n file_path text not null,\n checksum_sha256 text not null,\n size_bytes integer not null,\n content_type text not null,\n imported_asset_id text not null references assets(id),\n parent_asset_id text not null references assets(id),\n imported_at text not null,\n unique(job_id, output_index),\n unique(job_id, file_path)\n );\n create index if not exists generation_job_outputs_job on generation_job_outputs(job_id, output_index);\n create table if not exists generation_job_receipts (\n id text primary key,\n job_id text not null references generation_jobs(id) on delete cascade,\n receipt_type text not null check (receipt_type in ('plan', 'import', 'error')),\n status text not null check (status in ('ok', 'error')),\n command text not null,\n payload_json text not null,\n created_at text not null\n );\n create index if not exists generation_job_receipts_job on generation_job_receipts(job_id, created_at);\n create table if not exists adapter_settings (project_id text not null references projects(id), adapter_type text not null check (adapter_type in ('cloud', 'scheduler', 'image_generator')), provider text not null, enabled integer not null check (enabled in (0, 1)), secret_ref text, safe_config_json text not null, created_at text not null, updated_at text not null, primary key(project_id, adapter_type, provider)); create index if not exists adapter_settings_project_type on adapter_settings(project_id, adapter_type);\n create table if not exists agent_claims (\n id text primary key,\n token_hash text not null,\n project_id text not null references projects(id),\n channel text,\n scope_type text not null check (scope_type in ('lineage_workspace', 'content_post', 'content_queue_lane', 'selection_set', 'project_channel')),\n target_id text not null,\n target_title text,\n agent_id text,\n agent_name text not null,\n agent_kind text not null,\n thread_id text,\n status text not null check (status in ('active', 'expired', 'released', 'revoked', 'transferred')),\n created_at text not null,\n heartbeat_at text not null,\n expires_at text not null,\n released_at text,\n revoked_at text,\n revoked_by text,\n override_reason text,\n metadata_json text\n );\n create unique index if not exists agent_claims_token_hash on agent_claims(token_hash);\n create index if not exists agent_claims_project_status on agent_claims(project_id, status, heartbeat_at);\n create index if not exists agent_claims_target on agent_claims(project_id, channel, scope_type, target_id, status);\n create table if not exists agent_claim_events (\n id text primary key,\n claim_id text not null references agent_claims(id) on delete cascade,\n event_type text not null,\n actor text,\n message text,\n created_at text not null,\n metadata_json text\n );\n create index if not exists agent_claim_events_claim_created on agent_claim_events(claim_id, created_at);\n `);\n migrateAssetSelections(database);\n dropLegacyAssetSelectionRootUnique(database);\n ensureColumn(database, 'asset_selections', 'notes', 'text');\n ensureColumn(database, 'asset_ledger_records', 'first_seen_at', 'text');\n ensureColumn(database, 'asset_ledger_records', 'indexed_by_run_id', 'text');\n ensureColumn(database, 'asset_ledger_sources', 'first_seen_at', 'text');\n ensureColumn(database, 'asset_ledger_sources', 'indexed_by_run_id', 'text');\n ensureReviewStateValues(database);\n return database;\n}\n\nfunction ensureColumn(database: DatabaseSync, table: string, column: string, definition: string): void {\n const rows = database.prepare(`pragma table_info(${table})`).all() as Array<{ name: string }>;\n if (!rows.some(row => row.name === column)) database.exec(`alter table ${table} add column ${column} ${definition}`);\n}\n\nfunction migrateAssetSelections(database: DatabaseSync): void {\n const rows = database.prepare('pragma table_info(asset_selections)').all() as Array<{ name: string }>;\n if (rows.some(row => row.name === 'position')) return;\n const notesSelect = rows.some(row => row.name === 'notes') ? 'notes' : 'null';\n\n database.exec(`\n create table if not exists asset_selections_v2 (\n id text primary key,\n project_id text not null references projects(id),\n root_asset_id text not null references assets(id),\n asset_id text not null references assets(id),\n position integer not null default 0,\n notes text,\n selected_at text not null,\n unique(project_id, root_asset_id, asset_id)\n );\n insert or ignore into asset_selections_v2 (id, project_id, root_asset_id, asset_id, position, notes, selected_at)\n select\n project_id || ':' || root_asset_id || ':selected:' || asset_id,\n project_id,\n root_asset_id,\n asset_id,\n 0,\n ${notesSelect},\n selected_at\n from asset_selections;\n drop table asset_selections;\n alter table asset_selections_v2 rename to asset_selections;\n create index if not exists asset_selections_project_root_position\n on asset_selections(project_id, root_asset_id, position, selected_at);\n `);\n}\n\nfunction dropLegacyAssetSelectionRootUnique(database: DatabaseSync): void {\n const indexes = database.prepare('pragma index_list(asset_selections)').all() as Array<{ name: string; unique: number }>;\n for (const index of indexes) {\n if (!index.unique) continue;\n const columns = database.prepare(`pragma index_info(${index.name})`).all() as Array<{ name: string }>;\n const columnNames = columns.map(column => column.name).join(',');\n if (columnNames === 'project_id,root_asset_id') database.exec(`drop index if exists ${index.name}`);\n }\n}\n\nfunction ensureReviewStateValues(database: DatabaseSync): void {\n const createSql = database.prepare(\"select sql from sqlite_master where type = 'table' and name = 'asset_reviews'\").get() as { sql?: string } | undefined;\n if (createSql?.sql?.includes('needs_revision')) return;\n\n database.exec(`\n alter table asset_reviews rename to asset_reviews_old;\n create table asset_reviews (\n asset_id text primary key references assets(id),\n review_state text not null check (review_state in ('unreviewed', 'approved', 'needs_revision', 'rejected', 'ignored')),\n reviewed_at text,\n ignored_at text,\n notes text,\n updated_at text not null\n );\n insert into asset_reviews (asset_id, review_state, reviewed_at, ignored_at, notes, updated_at)\n select asset_id, review_state, reviewed_at, ignored_at, notes, updated_at\n from asset_reviews_old;\n drop table asset_reviews_old;\n `);\n}\n", "import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { spawnSync } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { createS3StorageAdapter } from './adapters/storage';\nimport { listLocalReviewAssets, localPreviewPath as resolveLocalPreviewPath } from './localReview';\nimport { syncLedgerPlacement } from './assetLedgerWorkflow';\nimport { appName } from '../shared/appConstants';\nimport type {\n AssetCatalog,\n AssetContentType,\n AssetFacets,\n DoctorReport,\n AssetLibrarySnapshot,\n GrowthAsset,\n ListAssetsOptions,\n LiveS3Object,\n MutationResponse,\n PlacementFields,\n PlacementStatus,\n PresignResponse,\n ProjectSummary,\n UploadFields,\n} from '../shared/types';\n\nfunction isPackageRoot(path: string): boolean {\n const packageJson = join(path, 'package.json');\n if (!existsSync(packageJson)) return false;\n try {\n const packageInfo = JSON.parse(readFileSync(packageJson, 'utf8')) as { name?: string };\n return packageInfo.name === '@mean-weasel/lineage';\n } catch {\n return false;\n }\n}\n\nfunction resolveRepoRoot(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n process.env.LINEAGE_REPO_ROOT,\n resolve(moduleDir, '..'),\n resolve(moduleDir, '../..'),\n process.cwd(),\n ].filter((candidate): candidate is string => Boolean(candidate));\n const root = candidates.find(isPackageRoot);\n if (!root) throw new Error('Unable to locate Lineage package root');\n return root;\n}\n\nexport const repoRoot = resolveRepoRoot();\nexport const defaultProject = 'demo-project';\nexport const defaultProduct = process.env.LINEAGE_DEFAULT_PRODUCT || defaultProject;\nconst publicFallbackBucket = 'lineage-demo-assets';\nconst publicFallbackRegion = 'us-east-1';\nconst contentTypes = new Set<AssetContentType>(['image', 'video', 'gif', 'audio', 'doc', 'other']);\nconst baseChannels = ['linkedin', 'meta', 'tiktok', 'x-twitter', 'youtube'];\nconst placementStatuses = new Set<PlacementStatus>(['planned', 'scheduled', 'posted', 'skipped']);\nconst projectNamePattern = /^[a-z0-9][a-z0-9-]*$/;\n\ninterface CommandResult {\n stdout: string;\n stderr: string;\n}\n\nclass LineageAssetError extends Error {\n constructor(message: string, public status = 400) {\n super(message);\n }\n}\n\nexport function isLineageAssetError(error: unknown): error is LineageAssetError {\n return error instanceof LineageAssetError;\n}\n\nexport function cleanProject(project = defaultProject): string {\n if (!projectNamePattern.test(project)) {\n throw new LineageAssetError('Project must be lowercase kebab-case');\n }\n return project;\n}\n\nexport function catalogPath(project = defaultProject): string {\n return join(repoRoot, cleanProject(project), 'assets', 'catalog.json');\n}\n\nfunction fixtureCatalogPath(project = defaultProject): string {\n return join(repoRoot, 'fixtures', cleanProject(project), 'assets', 'catalog.json');\n}\n\nfunction resolvedCatalogPath(project = defaultProject): string {\n const path = catalogPath(project);\n if (existsSync(path)) return path;\n const clean = cleanProject(project);\n if (clean === defaultProject && existsSync(fixtureCatalogPath(clean))) return fixtureCatalogPath(clean);\n return path;\n}\n\nexport function normalizeCatalog(catalog: Partial<AssetCatalog>, fallbackProject = defaultProject): AssetCatalog {\n const project = cleanProject(catalog.project || catalog.product || fallbackProject);\n const product = catalog.product || project;\n return {\n ...catalog,\n project,\n product,\n default_bucket: catalog.default_bucket || '',\n default_region: catalog.default_region || '',\n assets: (catalog.assets || []).map(asset => ({\n ...asset,\n source: asset.source || 'catalog',\n project: asset.project || asset.product || project,\n product: asset.product || asset.project || project,\n })),\n };\n}\n\nfunction fallbackS3(assetId: string, channel: string, status = 'working') {\n return {\n bucket: publicFallbackBucket,\n checksum_sha256: undefined,\n content_type: 'image/png',\n key: `products/${defaultProject}/campaigns/2026-06-public-demo/channels/${channel}/audiences/creators/statuses/${status}/types/image/assets/${assetId}/${assetId}.png`,\n region: publicFallbackRegion,\n size_bytes: 2048,\n updated_at: '2026-06-24T12:00:00.000Z',\n version_id: 'public-demo-version',\n };\n}\n\nfunction fallbackAsset(fields: Omit<GrowthAsset, 'audience' | 'campaign' | 'content_type' | 'cta' | 'hook' | 'product' | 'project' | 'source' | 'utm_content'> & {\n audience?: string;\n campaign?: string;\n cta?: string;\n hook?: string;\n utm_content?: string;\n}): GrowthAsset {\n return {\n audience: fields.audience || 'creators',\n campaign: fields.campaign || '2026-06-public-demo',\n content_type: 'image',\n cta: fields.cta || 'Save the idea',\n hook: fields.hook || 'Public demo creative for local review.',\n product: defaultProject,\n project: defaultProject,\n source: 'catalog',\n utm_content: fields.utm_content || fields.asset_id.replace(/-/g, '_'),\n ...fields,\n };\n}\n\nfunction defaultFallbackCatalog(): AssetCatalog {\n return normalizeCatalog({\n assets: [\n fallbackAsset({\n asset_id: 'demo-meta-short-form-upload-demo-post-static',\n channel: 'meta',\n s3: fallbackS3('demo-meta-short-form-upload-demo-post-static', 'meta'),\n status: 'working',\n title: 'Meta short-form demo post static',\n }),\n fallbackAsset({\n asset_id: 'demo-linkedin-ledger-catalog-shared',\n channel: 'linkedin',\n hook: 'Shared ledger creative with catalog metadata.',\n s3: fallbackS3('demo-linkedin-ledger-catalog-shared', 'linkedin'),\n status: 'working',\n title: 'LinkedIn ledger catalog shared',\n }),\n fallbackAsset({\n asset_id: 'demo-linkedin-upload-demo-done-static-grounded-v2',\n channel: 'linkedin',\n placements: [{\n channel: 'linkedin',\n notes: 'Synthetic public scheduled placement.',\n scheduled_at: '2026-06-24T16:00:00-07:00',\n status: 'scheduled',\n updated_at: '2026-06-24T12:30:00.000Z',\n }],\n s3: fallbackS3('demo-linkedin-upload-demo-done-static-grounded-v2', 'linkedin', 'approved'),\n status: 'approved',\n title: 'LinkedIn upload demo scheduled static',\n }),\n fallbackAsset({\n asset_id: 'demo-tiktok-upload-demo-export-vertical',\n channel: 'tiktok',\n format: 'vertical',\n hook: 'Fast vertical demo export for content queue tests.',\n s3: fallbackS3('demo-tiktok-upload-demo-export-vertical', 'tiktok'),\n status: 'working',\n title: 'TikTok upload demo export vertical',\n }),\n fallbackAsset({\n asset_id: 'demo-youtube-short-demo-posted-cut',\n channel: 'youtube',\n placements: [{\n channel: 'youtube',\n notes: 'Synthetic public posted placement.',\n posted_at: '2026-06-25T16:00:00-07:00',\n status: 'posted',\n updated_at: '2026-06-25T17:00:00.000Z',\n }],\n s3: fallbackS3('demo-youtube-short-demo-posted-cut', 'youtube', 'published'),\n status: 'published',\n title: 'YouTube short demo posted cut',\n }),\n fallbackAsset({\n asset_id: 'demo-x-twitter-carousel-demo-working-static',\n channel: 'x-twitter',\n format: 'static',\n s3: fallbackS3('demo-x-twitter-carousel-demo-working-static', 'x-twitter'),\n status: 'working',\n title: 'X Twitter carousel demo working static',\n }),\n ],\n default_bucket: '',\n default_region: '',\n product: defaultProject,\n project: defaultProject,\n }, defaultProject);\n}\n\nfunction isDefaultFallbackCatalog(catalog: AssetCatalog): boolean {\n return catalog.project === defaultProject && !existsSync(catalogPath(defaultProject));\n}\n\nfunction fallbackPreviewDataUrl(asset: GrowthAsset): string {\n const label = `${asset.title}\\n${asset.channel} / ${asset.status}`;\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"675\" viewBox=\"0 0 1200 675\"><rect width=\"1200\" height=\"675\" fill=\"#f7f5ef\"/><rect x=\"56\" y=\"56\" width=\"1088\" height=\"563\" rx=\"18\" fill=\"#10201c\"/><text x=\"96\" y=\"145\" fill=\"#9fe6c8\" font-family=\"Arial, sans-serif\" font-size=\"34\" font-weight=\"700\">Lineage public demo preview</text><text x=\"96\" y=\"230\" fill=\"#fff8e6\" font-family=\"Arial, sans-serif\" font-size=\"56\" font-weight=\"700\">${escapeSvgText(asset.asset_id)}</text><text x=\"96\" y=\"330\" fill=\"#d9e8df\" font-family=\"Arial, sans-serif\" font-size=\"34\">${escapeSvgText(label)}</text><text x=\"96\" y=\"500\" fill=\"#9fb7ae\" font-family=\"Arial, sans-serif\" font-size=\"26\">Synthetic local placeholder. No external storage requested.</text></svg>`;\n return `data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}`;\n}\n\nfunction escapeSvgText(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nexport function loadCatalog(project = defaultProject): AssetCatalog {\n const path = catalogPath(project);\n if (existsSync(path)) {\n try {\n return normalizeCatalog(JSON.parse(readFileSync(path, 'utf8')) as Partial<AssetCatalog>, project);\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {\n throw new LineageAssetError(`Missing catalog: ${path}`, 404);\n }\n throw error;\n }\n }\n const clean = cleanProject(project);\n if (clean === defaultProject) {\n const fixturePath = fixtureCatalogPath(clean);\n if (existsSync(fixturePath)) {\n return normalizeCatalog(JSON.parse(readFileSync(fixturePath, 'utf8')) as Partial<AssetCatalog>, project);\n }\n return defaultFallbackCatalog();\n }\n throw new LineageAssetError(`Missing catalog: ${path}`, 404);\n}\n\nfunction saveCatalog(project: string, catalog: AssetCatalog): AssetCatalog {\n const normalized = normalizeCatalog(catalog, project);\n mkdirSync(dirname(catalogPath(project)), { recursive: true });\n writeFileSync(catalogPath(project), `${JSON.stringify(normalized, null, 2)}\\n`);\n return normalized;\n}\n\nfunction run(command: string, args: string[]): CommandResult {\n const result = spawnSync(command, args, {\n cwd: repoRoot,\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'pipe'],\n env: {\n ...process.env,\n AWS_REGION: process.env.AWS_REGION || 'us-east-1',\n AWS_DEFAULT_REGION: process.env.AWS_DEFAULT_REGION || 'us-east-1',\n },\n });\n\n if (result.status !== 0) {\n const detail = result.stderr.trim() || result.stdout.trim();\n throw new LineageAssetError(`${command} ${args.join(' ')} failed${detail ? `: ${detail}` : ''}`, 502);\n }\n\n return { stdout: result.stdout, stderr: result.stderr };\n}\n\nfunction runAws(args: string[]): CommandResult {\n return run('aws', args);\n}\n\nexport function listProjects(): ProjectSummary[] {\n const projects = readdirSync(repoRoot, { withFileTypes: true })\n .filter(entry => entry.isDirectory() && projectNamePattern.test(entry.name) && existsSync(catalogPath(entry.name)))\n .flatMap(entry => {\n try {\n const catalog = loadCatalog(entry.name);\n return [{ project: catalog.project, product: catalog.product, catalogPath: resolvedCatalogPath(entry.name), default_bucket: catalog.default_bucket, default_region: catalog.default_region, asset_count: catalog.assets.length }];\n } catch (error) {\n if (error instanceof LineageAssetError && error.status === 404) return [];\n throw error;\n }\n })\n .sort((a, b) => a.project.localeCompare(b.project));\n if (!projects.some(item => item.project === defaultProject)) {\n const catalog = loadCatalog(defaultProject);\n projects.push({ project: catalog.project, product: catalog.product, catalogPath: resolvedCatalogPath(defaultProject), default_bucket: catalog.default_bucket, default_region: catalog.default_region, asset_count: catalog.assets.length });\n projects.sort((a, b) => a.project.localeCompare(b.project));\n }\n return projects;\n}\n\nfunction assetById(catalog: AssetCatalog, assetId: string): GrowthAsset {\n const asset = catalog.assets.find(item => item.asset_id === assetId);\n if (!asset) throw new LineageAssetError(`Unknown asset: ${assetId}`, 404);\n return asset;\n}\n\nconst storageAdapter = createS3StorageAdapter({\n assetById,\n cleanProject,\n createError: (message, status) => new LineageAssetError(message, status),\n defaultProject,\n loadCatalog,\n runAws,\n repoRoot,\n saveCatalog,\n supportedContentTypes: contentTypes,\n});\n\nfunction uniqueSorted<T extends string>(values: Array<T | undefined>): T[] {\n return Array.from(new Set(values.filter(Boolean) as T[])).sort();\n}\n\nfunction facetsFor(assets: GrowthAsset[]): AssetFacets {\n return {\n audiences: uniqueSorted(assets.map(asset => asset.audience)),\n campaigns: uniqueSorted(assets.map(asset => asset.campaign)),\n channels: uniqueSorted([...baseChannels, ...assets.map(asset => asset.channel)]),\n contentTypes: uniqueSorted(assets.map(asset => asset.content_type)),\n placementStatuses: uniqueSorted(assets.flatMap(asset => asset.placements?.map(placement => placement.status) || [])),\n statuses: uniqueSorted(assets.map(asset => asset.status)),\n totalSizeBytes: assets.reduce((sum, asset) => sum + (asset.s3?.size_bytes || 0), 0),\n };\n}\n\nfunction filteredAssets(assets: GrowthAsset[], options: ListAssetsOptions): GrowthAsset[] {\n const query = options.query?.trim().toLowerCase();\n return assets.filter(asset => {\n if (options.status && options.status !== 'all' && asset.status !== options.status) return false;\n if (options.channel && options.channel !== 'all' && asset.channel !== options.channel) return false;\n if (options.type && options.type !== 'all' && asset.content_type !== options.type) return false;\n if (options.placementStatus === 'not-posted' && asset.placements?.some(placement => placement.status === 'posted')) return false;\n if (options.placementStatus && !['all', 'not-posted'].includes(options.placementStatus) && !asset.placements?.some(placement => placement.status === options.placementStatus)) return false;\n if (options.campaign && options.campaign !== 'all' && asset.campaign !== options.campaign) return false;\n if (options.audience && options.audience !== 'all' && asset.audience !== options.audience) return false;\n if (!query) return true;\n return [asset.asset_id, asset.title, asset.campaign, asset.channel, asset.audience, asset.hook, asset.cta]\n .join(' ')\n .toLowerCase()\n .includes(query);\n });\n}\n\nexport function listAssets(project = defaultProject, options: ListAssetsOptions = {}): AssetLibrarySnapshot {\n const catalog = loadCatalog(project);\n const pageSize = Math.min(Math.max(Number(options.pageSize || 10), 1), 100);\n const page = Math.max(Number(options.page || 1), 1);\n const localAssets = listLocalReviewAssets(repoRoot, catalog.project, catalog);\n const source = options.source || 'catalog';\n const sourceAssets = source === 'local' ? localAssets : source === 'all' ? [...localAssets, ...catalog.assets] : catalog.assets;\n const filtered = filteredAssets(sourceAssets, options);\n const totalPages = Math.max(Math.ceil(filtered.length / pageSize), 1);\n const safePage = Math.min(page, totalPages);\n const start = (safePage - 1) * pageSize;\n const pageAssets = filtered.slice(start, start + pageSize);\n let liveObjects: LiveS3Object[] = [];\n let error: string | undefined;\n if (options.includeLive && !isDefaultFallbackCatalog(catalog)) {\n try {\n liveObjects = storageAdapter.listLiveObjects(catalog);\n } catch (err) {\n error = err instanceof Error ? err.message : String(err);\n }\n }\n return {\n catalog: { project: catalog.project, product: catalog.product, default_bucket: catalog.default_bucket, default_region: catalog.default_region, asset_count: catalog.assets.length },\n assets: pageAssets,\n facets: facetsFor(catalog.assets),\n pagination: { page: safePage, pageSize, total: filtered.length, totalPages },\n liveObjects,\n orphanObjects: liveObjects.filter(object => !object.cataloged),\n identity: options.includeLive && !isDefaultFallbackCatalog(catalog) ? storageAdapter.getIdentity() : undefined,\n fetchedAt: new Date().toISOString(),\n error,\n };\n}\n\nexport function inspectAsset(project: string, assetId: string): GrowthAsset {\n return assetById(loadCatalog(project), assetId);\n}\n\nexport function validateProject(project = defaultProject): ProjectSummary {\n const catalog = loadCatalog(project);\n return { project: catalog.project, product: catalog.product, catalogPath: resolvedCatalogPath(project), default_bucket: catalog.default_bucket, default_region: catalog.default_region, asset_count: catalog.assets.length };\n}\n\nexport function doctorProject(project = defaultProject, options: { includeLive?: boolean } = {}): DoctorReport {\n const summary = validateProject(project);\n let liveCheck: DoctorReport['liveCheck'] = 'skipped';\n let liveError: string | undefined;\n if (options.includeLive && isDefaultFallbackCatalog(loadCatalog(project))) {\n liveCheck = 'skipped';\n liveError = `${appName} public fallback uses local catalog data only.`;\n } else if (options.includeLive) {\n try {\n storageAdapter.listLiveObjects(loadCatalog(project));\n liveCheck = 'ok';\n } catch (error) {\n liveCheck = 'error';\n liveError = error instanceof Error ? error.message : String(error);\n }\n }\n return { catalogExists: true, deleteEnabled: process.env.LINEAGE_ENABLE_CLOUD_DELETE === 'true', project: summary, liveCheck, liveError };\n}\n\nexport function pullAsset(project: string, assetId: string, out = '.asset-scratch'): MutationResponse {\n return storageAdapter.pullAsset(project, assetId, out);\n}\n\nfunction placementFromFields(fields: PlacementFields) {\n if (!fields.channel) throw new LineageAssetError('Placement requires channel');\n if (!placementStatuses.has(fields.status)) throw new LineageAssetError(`Unsupported placement status: ${fields.status}`);\n const now = new Date().toISOString();\n return {\n channel: fields.channel,\n status: fields.status,\n ...(fields.scheduledAt ? { scheduled_at: fields.scheduledAt } : {}),\n ...(fields.postedAt ? { posted_at: fields.postedAt } : {}),\n ...(fields.url ? { url: fields.url } : {}),\n ...(fields.notes ? { notes: fields.notes } : {}),\n updated_at: now,\n };\n}\n\nexport function previewPlacement(project: string, fields: PlacementFields) {\n const asset = inspectAsset(project, fields.assetId);\n return { asset_id: asset.asset_id, placement: placementFromFields(fields) };\n}\n\nexport function updatePlacement(project: string, fields: PlacementFields): MutationResponse {\n if (!fields.confirmWrite) throw new LineageAssetError('Placement updates require confirmWrite=true');\n const catalog = loadCatalog(project);\n const asset = assetById(catalog, fields.assetId);\n const placement = placementFromFields(fields);\n const existing = asset.placements?.findIndex(item => item.channel === placement.channel);\n if (existing !== undefined && existing >= 0) asset.placements![existing] = placement;\n else asset.placements = [...(asset.placements || []), placement];\n saveCatalog(project, catalog);\n syncLedgerPlacement(project, asset.asset_id, placement);\n return { ok: true, message: `Marked ${asset.asset_id} ${placement.status} for ${placement.channel}`, catalog };\n}\n\nexport function presignAsset(project: string, assetId: string, expiresIn = 900): PresignResponse {\n const catalog = loadCatalog(project);\n if (isDefaultFallbackCatalog(catalog)) {\n const asset = assetById(catalog, assetId);\n return { assetId: asset.asset_id, expiresIn, url: fallbackPreviewDataUrl(asset) };\n }\n return storageAdapter.presignAsset(project, assetId, expiresIn);\n}\n\nexport function localPreviewPath(relativePath: string): string {\n try {\n return resolveLocalPreviewPath(repoRoot, relativePath);\n } catch (error) {\n throw new LineageAssetError(error instanceof Error ? error.message : 'Unknown local review asset', 404);\n }\n}\n\nexport function promoteAsset(project: string, assetId: string, confirmWrite: boolean): MutationResponse {\n return storageAdapter.promoteAsset(project, assetId, confirmWrite);\n}\n\nexport function archiveAsset(project: string, assetId: string, confirmArchive: boolean): MutationResponse {\n if (!confirmArchive) throw new LineageAssetError('Archive requires confirmArchive=true');\n const catalog = loadCatalog(project);\n const asset = assetById(catalog, assetId);\n asset.status = 'archived';\n saveCatalog(project, catalog);\n return { ok: true, message: `Archived ${assetId}`, catalog };\n}\n\nexport function uploadAsset(file: string, fields: UploadFields): MutationResponse {\n return storageAdapter.uploadAsset(file, fields);\n}\n\nexport function deleteObjectGuarded(project: string, assetId: string, confirmation: string): MutationResponse {\n return storageAdapter.deleteObjectGuarded(project, assetId, confirmation);\n}\n\nexport function ensureUploadDir(): string {\n const dir = join(repoRoot, '.asset-scratch', 'studio-uploads');\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nexport function cleanupUploadedTemp(file?: string): void {\n if (!file) return;\n const uploadRoot = ensureUploadDir();\n const resolved = resolve(file);\n if (resolved.startsWith(`${uploadRoot}/`) && existsSync(resolved)) {\n unlinkSync(resolved);\n }\n}\n", "import { copyFileSync, existsSync, mkdirSync, statSync } from 'node:fs';\nimport { basename, dirname, join } from 'node:path';\nimport { contentTypeFor, fileSha256 } from '../../localReview';\nimport type { AssetCatalog, LiveS3Object, MutationResponse, PresignResponse } from '../../../shared/types';\nimport type { StorageAdapter, StorageAdapterDependencies } from './types';\n\nexport function parseAssetIdFromS3Key(key: string): string | undefined {\n const marker = '/assets/';\n const index = key.indexOf(marker);\n if (index === -1) return undefined;\n return key.slice(index + marker.length).split('/')[0];\n}\n\nfunction previewDataUrl(asset: { asset_id: string; channel?: string; status?: string; title?: string }): string {\n const title = asset.title || asset.asset_id;\n const label = `${asset.channel || 'catalog'} / ${asset.status || 'working'}`;\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"675\" viewBox=\"0 0 1200 675\"><rect width=\"1200\" height=\"675\" fill=\"#f7f5ef\"/><rect x=\"56\" y=\"56\" width=\"1088\" height=\"563\" rx=\"18\" fill=\"#10201c\"/><text x=\"96\" y=\"145\" fill=\"#9fe6c8\" font-family=\"Arial, sans-serif\" font-size=\"34\" font-weight=\"700\">Lineage catalog preview</text><text x=\"96\" y=\"230\" fill=\"#fff8e6\" font-family=\"Arial, sans-serif\" font-size=\"56\" font-weight=\"700\">${escapeSvgText(asset.asset_id)}</text><text x=\"96\" y=\"330\" fill=\"#d9e8df\" font-family=\"Arial, sans-serif\" font-size=\"34\">${escapeSvgText(title)}</text><text x=\"96\" y=\"500\" fill=\"#9fb7ae\" font-family=\"Arial, sans-serif\" font-size=\"26\">${escapeSvgText(label)}. No external storage requested.</text></svg>`;\n return `data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}`;\n}\n\nfunction escapeSvgText(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nexport function createS3StorageAdapter(deps: StorageAdapterDependencies): StorageAdapter {\n return {\n deleteObjectGuarded(project, assetId, confirmation): MutationResponse {\n const enabled = process.env.LINEAGE_ENABLE_CLOUD_DELETE === 'true';\n if (!enabled) {\n throw deps.createError('S3 delete is disabled. Use archive unless a human enables LINEAGE_ENABLE_CLOUD_DELETE.', 403);\n }\n if (confirmation !== `delete ${assetId}`) {\n throw deps.createError(`Delete confirmation must exactly equal: delete ${assetId}`);\n }\n const catalog = deps.loadCatalog(project);\n const asset = deps.assetById(catalog, assetId);\n if (!asset.s3) throw deps.createError(`Asset has no S3 object: ${assetId}`);\n deps.runAws(['s3api', 'delete-object', '--bucket', asset.s3.bucket, '--key', asset.s3.key, '--region', asset.s3.region]);\n asset.status = 'archived';\n deps.saveCatalog(project, catalog);\n return { ok: true, message: `Deleted current S3 object and archived ${assetId}`, catalog };\n },\n\n getIdentity() {\n try {\n const output = deps.runAws(['sts', 'get-caller-identity', '--query', '{Account:Account,Arn:Arn}', '--output', 'json']);\n const parsed = JSON.parse(output.stdout) as { Account: string; Arn: string };\n return { account: parsed.Account, arn: parsed.Arn };\n } catch {\n return undefined;\n }\n },\n\n listLiveObjects(catalog: AssetCatalog): LiveS3Object[] {\n const bucket = catalog.default_bucket;\n const region = catalog.default_region;\n // Existing uploaded objects live under products/<project>; do not rewrite keys during project migration.\n const prefix = `products/${catalog.product}/`;\n const output = deps.runAws(['s3api', 'list-objects-v2', '--bucket', bucket, '--prefix', prefix, '--region', region, '--output', 'json']);\n const parsed = JSON.parse(output.stdout) as {\n Contents?: Array<{ Key: string; Size: number; LastModified: string; StorageClass?: string }>;\n };\n const catalogKeys = new Set(catalog.assets.map(asset => asset.s3?.key).filter(Boolean));\n return (parsed.Contents || []).map(item => ({\n key: item.Key,\n size: item.Size,\n lastModified: item.LastModified,\n storageClass: item.StorageClass,\n cataloged: catalogKeys.has(item.Key),\n assetId: parseAssetIdFromS3Key(item.Key),\n }));\n },\n\n presignAsset(project, assetId, expiresIn = 900): PresignResponse {\n const catalog = deps.loadCatalog(project);\n const asset = deps.assetById(catalog, assetId);\n return { assetId, expiresIn, url: previewDataUrl(asset) };\n },\n\n promoteAsset(project, assetId, confirmWrite): MutationResponse {\n if (!confirmWrite) throw deps.createError('Promote requires confirmWrite=true');\n const catalog = deps.loadCatalog(project);\n const asset = deps.assetById(catalog, assetId);\n asset.status = 'published';\n deps.saveCatalog(project, catalog);\n return {\n ok: true,\n message: `Promoted ${assetId}`,\n catalog,\n };\n },\n\n pullAsset(project, assetId, out = '.asset-scratch'): MutationResponse {\n const catalog = deps.loadCatalog(project);\n const asset = deps.assetById(catalog, assetId);\n return {\n ok: true,\n message: `Prepared ${assetId} for local review`,\n output: {\n assetId: asset.asset_id,\n out,\n storage: asset.local ? 'local' : asset.s3 ? 'catalog-s3-metadata' : 'catalog',\n note: 'Lineage public package does not pull cloud objects automatically.',\n },\n };\n },\n\n uploadAsset(file, fields): MutationResponse {\n if (!fields.confirmWrite) throw deps.createError('Upload requires confirmWrite=true');\n if (!existsSync(file)) throw deps.createError(`Upload file missing: ${file}`, 404);\n if (!['working', 'published'].includes(fields.status)) throw deps.createError('Upload status must be working or published');\n if (!deps.supportedContentTypes.has(fields.type)) throw deps.createError(`Unsupported asset type: ${fields.type}`);\n\n const project = deps.cleanProject(fields.project || fields.product || deps.defaultProject);\n const catalog = deps.loadCatalog(project);\n const relativePath = join('uploads', project, fields.assetId, basename(file));\n const absolutePath = join(deps.repoRoot, '.asset-scratch', relativePath);\n mkdirSync(dirname(absolutePath), { recursive: true });\n copyFileSync(file, absolutePath);\n const stats = statSync(absolutePath);\n const contentType = contentTypeFor(absolutePath);\n const checksumSha256 = fileSha256(absolutePath);\n const now = new Date().toISOString();\n const nextAsset = {\n asset_id: fields.assetId,\n audience: fields.audience,\n campaign: fields.campaign,\n channel: fields.channel,\n content_type: fields.type,\n cta: fields.cta,\n hook: fields.hook,\n ...(fields.format ? { format: fields.format } : {}),\n local: {\n absolute_path: absolutePath,\n checksum_sha256: checksumSha256,\n content_type: contentType,\n relative_path: relativePath,\n size_bytes: stats.size,\n updated_at: now,\n },\n ...(fields.messageFamily ? { message_family: fields.messageFamily } : {}),\n ...(fields.notes ? { notes: fields.notes } : {}),\n product: project,\n project,\n source: 'catalog' as const,\n status: fields.status,\n title: fields.title,\n utm_content: fields.utmContent,\n };\n const existing = catalog.assets.findIndex(asset => asset.asset_id === fields.assetId);\n if (existing >= 0) catalog.assets[existing] = { ...catalog.assets[existing], ...nextAsset };\n else catalog.assets.push(nextAsset);\n deps.saveCatalog(project, catalog);\n return {\n ok: true,\n message: `Recorded ${fields.assetId} locally`,\n output: {\n file: basename(absolutePath),\n relativePath,\n sizeBytes: stats.size,\n contentType,\n checksumSha256,\n },\n catalog,\n };\n },\n };\n}\n", "import { createHash } from 'node:crypto';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { basename, extname, join, relative, resolve } from 'node:path';\nimport type { AssetCatalog, AssetContentType, GrowthAsset } from '../shared/types';\n\nconst mimeByExt: Record<string, string> = {\n '.gif': 'image/gif',\n '.jpeg': 'image/jpeg',\n '.jpg': 'image/jpeg',\n '.mov': 'video/quicktime',\n '.mp4': 'video/mp4',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n '.webp': 'image/webp',\n};\nconst localReviewExts = new Set(Object.keys(mimeByExt));\nconst channelFromName = /\\b(linkedin|meta|tiktok|youtube|x-twitter|x)\\b/i;\nconst campaignFromPath = /\\b(20\\d{2}-\\d{2}-[a-z0-9-]+)\\b/i;\n\nclass LocalReviewError extends Error {\n status = 400;\n}\n\nfunction localReviewRoot(repoRoot: string): string {\n return join(repoRoot, '.asset-scratch');\n}\n\nexport function contentTypeFor(file: string): string {\n return mimeByExt[extname(file).toLowerCase()] || 'application/octet-stream';\n}\n\nexport function fileSha256(file: string): string {\n return createHash('sha256').update(readFileSync(file)).digest('hex');\n}\n\nfunction isPathInside(child: string, parent: string): boolean {\n const relativePath = relative(parent, child);\n return Boolean(relativePath) && !relativePath.startsWith('..') && !relativePath.startsWith('/');\n}\n\nfunction walkLocalReviewFiles(dir: string, files: string[] = []): string[] {\n if (!existsSync(dir)) return files;\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return files;\n throw error;\n }\n for (const entry of entries) {\n if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === 'studio-uploads' || entry.name === 'playwright-results' || entry.name === 'lineage-demo') continue;\n if (process.env.NODE_ENV !== 'test' && /^vitest-/.test(entry.name)) continue;\n const path = join(dir, entry.name);\n if (entry.isDirectory()) walkLocalReviewFiles(path, files);\n else if (entry.isFile() && localReviewExts.has(extname(entry.name).toLowerCase())) files.push(path);\n }\n return files;\n}\n\nfunction inferCampaign(relativePath: string): string {\n return campaignFromPath.exec(relativePath)?.[1] || 'local-review';\n}\n\nfunction inferChannel(relativePath: string): string {\n const match = channelFromName.exec(relativePath);\n if (!match) return 'local';\n return match[1].toLowerCase() === 'x' ? 'x-twitter' : match[1].toLowerCase();\n}\n\nfunction inferContentType(file: string): AssetContentType {\n const mime = contentTypeFor(file);\n if (mime.startsWith('image/gif')) return 'gif';\n if (mime.startsWith('image/')) return 'image';\n if (mime.startsWith('video/')) return 'video';\n return 'other';\n}\n\nexport function listLocalReviewAssets(repoRoot: string, project: string, catalog: AssetCatalog): GrowthAsset[] {\n const catalogChecksums = new Set(catalog.assets.map(asset => asset.s3?.checksum_sha256).filter(Boolean));\n const root = localReviewRoot(repoRoot);\n return walkLocalReviewFiles(root)\n .flatMap(file => {\n try {\n const stats = statSync(file);\n const checksum = fileSha256(file);\n const relativePath = relative(root, file);\n return [{ checksum, file, relativePath, stats }];\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw error;\n }\n })\n .filter(item => !catalogChecksums.has(item.checksum))\n .map(item => {\n const fileSlug = basename(item.file, extname(item.file));\n const channel = inferChannel(item.relativePath);\n return {\n asset_id: `local-${item.checksum.slice(0, 12)}`,\n project,\n product: project,\n source: 'local',\n campaign: inferCampaign(item.relativePath),\n channel,\n audience: 'local-review',\n status: 'planned',\n content_type: inferContentType(item.file),\n title: fileSlug.replace(/[-_]+/g, ' '),\n hook: item.relativePath,\n cta: 'Review before upload',\n utm_content: fileSlug.replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_+|_+$/g, '').toLowerCase() || 'local_review',\n notes: 'Local pre-push asset. Review and refine before uploading to S3.',\n local: {\n relative_path: item.relativePath,\n absolute_path: item.file,\n size_bytes: item.stats.size,\n content_type: contentTypeFor(item.file),\n checksum_sha256: item.checksum,\n updated_at: item.stats.mtime.toISOString(),\n },\n };\n });\n}\n\nexport function localPreviewPath(repoRoot: string, relativePath: string): string {\n const root = localReviewRoot(repoRoot);\n const resolved = resolve(root, relativePath);\n if (!isPathInside(resolved, root) || !existsSync(resolved)) throw new LocalReviewError('Unknown local review asset');\n if (!localReviewExts.has(extname(resolved).toLowerCase())) throw new LocalReviewError('Local preview type is not supported');\n return resolved;\n}\n", "import type { SelectionFields } from '../shared/types';\nimport type { DatabaseSync } from './assetLineageDb';\n\nexport const LINEAGE_NEXT_VARIATION_LIMIT = 3;\n\nexport interface LineageSelectionRow {\n asset_id: string;\n notes?: string;\n position: number;\n selected_at: string;\n}\n\nexport function selectionId(project: string, root: string, assetId: string): string {\n return `${project}:${root}:selected:${assetId}`;\n}\n\nexport function selectedRows(database: DatabaseSync, project: string, root: string): LineageSelectionRow[] {\n return database.prepare(`\n select asset_id, notes, position, selected_at\n from asset_selections\n where project_id = ? and root_asset_id = ?\n order by position, selected_at, asset_id\n `).all(project, root) as unknown as LineageSelectionRow[];\n}\n\nexport function normalizeSelectionInput(fields: SelectionFields): string[] {\n return [...new Set([...(fields.assetIds || []), fields.assetId || ''].map(assetId => assetId.trim()).filter(Boolean))];\n}\n", "import { lineageDb, nowIso, type DatabaseSync } from './assetLineageDb';\nimport type {\n LineageWorkspace,\n LineageWorkspaceActor,\n LineageWorkspaceFields,\n LineageWorkspaceSnapshot,\n LineageWorkspaceStatus,\n LineageWorkspaceUpdateFields,\n} from '../shared/types';\n\ntype Row = Record<string, unknown>;\n\nconst actors = new Set<LineageWorkspaceActor>(['human', 'agent', 'system']);\nconst statuses = new Set<LineageWorkspaceStatus>(['active', 'paused', 'archived']);\n\nexport class LineageWorkspaceError extends Error {\n constructor(message: string, public status = 400) {\n super(message);\n }\n}\n\nexport function isLineageWorkspaceError(error: unknown): error is LineageWorkspaceError {\n return error instanceof LineageWorkspaceError;\n}\n\nexport function lineageWorkspaceId(project: string, rootAssetId: string): string {\n return `${project}:lineage-workspace:${rootAssetId}`;\n}\n\nfunction ensureProject(database: DatabaseSync, project: string): void {\n const timestamp = nowIso();\n database.prepare(`\n insert into projects (id, product, created_at, updated_at)\n values (?, ?, ?, ?)\n on conflict(id) do update set product = excluded.product, updated_at = excluded.updated_at\n `).run(project, project, timestamp, timestamp);\n}\n\nfunction normalizeStatus(value: LineageWorkspaceStatus | undefined, fallback: LineageWorkspaceStatus): LineageWorkspaceStatus {\n const status = value || fallback;\n if (!statuses.has(status)) throw new LineageWorkspaceError(`Unsupported lineage workspace status: ${status}`);\n return status;\n}\n\nfunction normalizeActor(value: LineageWorkspaceActor | undefined): LineageWorkspaceActor {\n const actor = value || 'human';\n if (!actors.has(actor)) throw new LineageWorkspaceError(`Unsupported lineage workspace actor: ${actor}`);\n return actor;\n}\n\nfunction requireAsset(database: DatabaseSync, project: string, assetId: string): { id: string; title: string } {\n const row = database.prepare('select id, title from assets where project_id = ? and id = ?').get(project, assetId) as { id: string; title: string } | undefined;\n if (!row) throw new LineageWorkspaceError(`Unknown indexed asset: ${assetId}`, 404);\n return row;\n}\n\nfunction rowToWorkspace(row: Row): LineageWorkspace {\n return {\n id: String(row.id),\n project: String(row.project_id),\n root_asset_id: String(row.root_asset_id),\n title: String(row.title),\n status: String(row.status) as LineageWorkspaceStatus,\n notes: typeof row.notes === 'string' ? row.notes : undefined,\n created_by: String(row.created_by) as LineageWorkspaceActor,\n active_at: typeof row.active_at === 'string' ? row.active_at : undefined,\n created_at: String(row.created_at),\n updated_at: String(row.updated_at),\n };\n}\n\nfunction workspaceById(database: DatabaseSync, project: string, id: string): LineageWorkspace | null {\n const row = database.prepare('select * from lineage_workspaces where project_id = ? and id = ?').get(project, id) as Row | undefined;\n return row ? rowToWorkspace(row) : null;\n}\n\nfunction workspaceByRoot(database: DatabaseSync, project: string, rootAssetId: string): LineageWorkspace | null {\n const row = database.prepare('select * from lineage_workspaces where project_id = ? and root_asset_id = ?').get(project, rootAssetId) as Row | undefined;\n return row ? rowToWorkspace(row) : null;\n}\n\nfunction knownRoots(database: DatabaseSync, project: string): Array<{ root_asset_id: string; selected_at?: string }> {\n const rows = database.prepare(`\n select root_asset_id, max(selected_at) selected_at from asset_selections where project_id = ? group by root_asset_id\n union\n select root_asset_id, null selected_at from asset_layouts where project_id = ? group by root_asset_id\n union\n select parent_asset_id root_asset_id, null selected_at\n from asset_edges\n where project_id = ?\n and parent_asset_id not in (select child_asset_id from asset_edges where project_id = ?)\n group by parent_asset_id\n `).all(project, project, project, project) as Array<{ root_asset_id: string; selected_at?: string | null }>;\n return rows.map(row => ({ root_asset_id: row.root_asset_id, selected_at: row.selected_at || undefined }));\n}\n\nfunction seedLegacyWorkspaces(database: DatabaseSync, project: string): void {\n ensureProject(database, project);\n const timestamp = nowIso();\n const statement = database.prepare(`\n insert into lineage_workspaces (\n id, project_id, root_asset_id, title, status, notes, created_by, active_at, created_at, updated_at\n )\n select ?, ?, a.id, a.title || ' lineage', 'active', null, 'system', ?, ?, ?\n from assets a\n where a.project_id = ? and a.id = ?\n on conflict(project_id, root_asset_id) do nothing\n `);\n for (const root of knownRoots(database, project)) {\n statement.run(\n lineageWorkspaceId(project, root.root_asset_id),\n project,\n root.selected_at || null,\n timestamp,\n timestamp,\n project,\n root.root_asset_id\n );\n }\n}\n\nfunction listRows(database: DatabaseSync, project: string): LineageWorkspace[] {\n return (database.prepare(`\n select * from lineage_workspaces\n where project_id = ?\n order by\n case status when 'active' then 0 when 'paused' then 1 else 2 end,\n active_at desc nulls last,\n updated_at desc,\n title\n `).all(project) as Row[]).map(rowToWorkspace);\n}\n\nfunction activeWorkspace(database: DatabaseSync, project: string): LineageWorkspace | null {\n const row = database.prepare(`\n select * from lineage_workspaces\n where project_id = ? and status != 'archived'\n order by active_at desc nulls last, updated_at desc\n limit 1\n `).get(project) as Row | undefined;\n return row ? rowToWorkspace(row) : null;\n}\n\nexport function listLineageWorkspaces(project: string): LineageWorkspaceSnapshot {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n return {\n project,\n active_workspace: activeWorkspace(database, project),\n workspaces: listRows(database, project),\n fetchedAt: nowIso(),\n };\n } finally {\n database.close();\n }\n}\n\nexport function inspectLineageWorkspace(project: string, workspaceId: string): LineageWorkspace {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n const workspace = workspaceById(database, project, workspaceId) || workspaceByRoot(database, project, workspaceId);\n if (!workspace) throw new LineageWorkspaceError(`Unknown lineage workspace: ${workspaceId}`, 404);\n return workspace;\n } finally {\n database.close();\n }\n}\n\nexport function createLineageWorkspace(project: string, fields: LineageWorkspaceFields) {\n const rootAssetId = fields.rootAssetId.trim();\n if (!rootAssetId) throw new LineageWorkspaceError('Lineage workspace requires rootAssetId');\n const status = normalizeStatus(fields.status, 'active');\n const actor = normalizeActor(fields.createdBy);\n const database = lineageDb();\n try {\n const root = requireAsset(database, project, rootAssetId);\n const timestamp = nowIso();\n const workspace: LineageWorkspace = {\n id: lineageWorkspaceId(project, rootAssetId),\n project,\n root_asset_id: rootAssetId,\n title: fields.title?.trim() || `${root.title} lineage`,\n status,\n notes: fields.notes?.trim() || undefined,\n created_by: actor,\n active_at: fields.activate !== false && status !== 'archived' ? timestamp : undefined,\n created_at: timestamp,\n updated_at: timestamp,\n };\n if (!fields.confirmWrite) return { ok: true as const, dryRun: true as const, workspace };\n ensureProject(database, project);\n database.prepare(`\n insert into lineage_workspaces (\n id, project_id, root_asset_id, title, status, notes, created_by, active_at, created_at, updated_at\n ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n on conflict(project_id, root_asset_id) do update set\n title = excluded.title,\n status = excluded.status,\n notes = excluded.notes,\n active_at = coalesce(excluded.active_at, lineage_workspaces.active_at),\n updated_at = excluded.updated_at\n `).run(\n workspace.id,\n project,\n workspace.root_asset_id,\n workspace.title,\n workspace.status,\n workspace.notes || null,\n workspace.created_by,\n workspace.active_at || null,\n workspace.created_at,\n workspace.updated_at\n );\n return {\n ok: true as const,\n message: `Saved lineage workspace ${workspace.title}`,\n workspace: workspaceById(database, project, workspace.id),\n };\n } finally {\n database.close();\n }\n}\n\nexport function updateLineageWorkspace(project: string, workspaceId: string, fields: LineageWorkspaceUpdateFields) {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n const current = workspaceById(database, project, workspaceId) || workspaceByRoot(database, project, workspaceId);\n if (!current) throw new LineageWorkspaceError(`Unknown lineage workspace: ${workspaceId}`, 404);\n const timestamp = nowIso();\n const next: LineageWorkspace = {\n ...current,\n title: fields.title?.trim() || current.title,\n status: normalizeStatus(fields.status, current.status),\n notes: fields.notes === undefined ? current.notes : fields.notes.trim() || undefined,\n active_at: fields.activate ? timestamp : current.active_at,\n updated_at: timestamp,\n };\n if (!fields.confirmWrite) return { ok: true as const, dryRun: true as const, workspace: next };\n database.prepare(`\n update lineage_workspaces\n set title = ?, status = ?, notes = ?, active_at = ?, updated_at = ?\n where project_id = ? and id = ?\n `).run(next.title, next.status, next.notes || null, next.active_at || null, timestamp, project, current.id);\n return {\n ok: true as const,\n message: `Updated lineage workspace ${next.title}`,\n workspace: workspaceById(database, project, current.id),\n };\n } finally {\n database.close();\n }\n}\n\nexport function activateLineageWorkspace(project: string, workspaceId: string, confirmWrite: boolean) {\n return updateLineageWorkspace(project, workspaceId, { activate: true, status: 'active', confirmWrite });\n}\n\nexport function archiveLineageWorkspace(project: string, workspaceId: string, confirmWrite: boolean) {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n const current = workspaceById(database, project, workspaceId) || workspaceByRoot(database, project, workspaceId);\n if (!current) throw new LineageWorkspaceError(`Unknown lineage workspace: ${workspaceId}`, 404);\n const timestamp = nowIso();\n const next: LineageWorkspace = {\n ...current,\n status: 'archived',\n active_at: undefined,\n updated_at: timestamp,\n };\n if (!confirmWrite) return { ok: true as const, dryRun: true as const, workspace: next };\n database.prepare(`\n update lineage_workspaces\n set status = 'archived', active_at = null, updated_at = ?\n where project_id = ? and id = ?\n `).run(timestamp, project, current.id);\n database.prepare('delete from asset_selections where project_id = ? and root_asset_id = ?').run(project, current.root_asset_id);\n return {\n ok: true as const,\n message: `Archived lineage workspace ${current.title}`,\n workspace: workspaceById(database, project, current.id),\n };\n } finally {\n database.close();\n }\n}\n\nexport function activeLineageWorkspaceRoot(project: string): string | undefined {\n const database = lineageDb();\n try {\n seedLegacyWorkspaces(database, project);\n return activeWorkspace(database, project)?.root_asset_id;\n } finally {\n database.close();\n }\n}\n", "import { AgentClaimError, listAgentClaims, validateAgentClaimForWrite } from './agentClaims';\nimport { lineageWorkspaceId } from './assetLineageWorkspaces';\n\nfunction channelOverlaps(left?: string, right?: string): boolean {\n return !left || !right || left === right;\n}\n\nfunction hasActiveLineageWorkspaceClaim(project: string, targetId: string, channel?: string): boolean {\n return listAgentClaims(project).claims.some(claim => {\n if (claim.project !== project || claim.status !== 'active' || claim.derived_state === 'expired') return false;\n if (claim.scope_type === 'lineage_workspace') return claim.target_id === targetId;\n return claim.scope_type === 'project_channel' && channelOverlaps(channel, claim.channel);\n });\n}\n\nexport function requireLineageWorkspaceClaimForWrite(fields: {\n channel?: string;\n claimToken?: string;\n confirmWrite: boolean;\n project: string;\n rootAssetId: string;\n writeKind: string;\n}): void {\n if (!fields.confirmWrite) return;\n const targetId = lineageWorkspaceId(fields.project, fields.rootAssetId);\n if (!fields.claimToken && !hasActiveLineageWorkspaceClaim(fields.project, targetId, fields.channel)) return;\n const validation = validateAgentClaimForWrite({\n channel: fields.channel,\n claimToken: fields.claimToken,\n confirmWrite: fields.confirmWrite,\n dangerLevel: 'enforce',\n project: fields.project,\n scopeType: 'lineage_workspace',\n targetId,\n writeKind: fields.writeKind,\n });\n if (!validation.ok) {\n const status = validation.code === 'claim_required' || validation.code === 'claim_token_invalid' ? 401 : 409;\n throw new AgentClaimError(validation.message, status, validation.code, validation.conflicts);\n }\n}\n", "import { join } from 'node:path';\nimport { defaultProject, listAssets, repoRoot } from './assetCore';\nimport { lineageDb as db, lineageDbPath, nowIso, type DatabaseSync } from './assetLineageDb';\nimport { LINEAGE_NEXT_VARIATION_LIMIT, normalizeSelectionInput, selectedRows, selectionId } from './assetLineageSelection';\nimport { activeLineageWorkspaceRoot } from './assetLineageWorkspaces';\nimport { requireLineageWorkspaceClaimForWrite } from './lineageClaimGuards';\nimport type {\n AssetReviewState,\n GrowthAsset,\n LineageEdge,\n LineageChildrenResponse,\n LineageIndexSummary,\n LineageLayoutFields,\n LineageLinkFields,\n LineageNode,\n LineageNextResponse,\n LineagePosition,\n LineageSnapshot,\n ReviewFields,\n SelectionFields,\n} from '../shared/types';\n\nexport class LineageError extends Error {\n constructor(message: string, public status = 400) {\n super(message);\n }\n}\n\nexport function isLineageError(error: unknown): error is LineageError {\n return error instanceof LineageError;\n}\n\nfunction collectAssets(project: string, source: 'catalog' | 'local'): GrowthAsset[] {\n const first = listAssets(project, { source, page: 1, pageSize: 100 });\n const assets = [...first.assets];\n for (let page = 2; page <= first.pagination.totalPages; page += 1) {\n assets.push(...listAssets(project, { source, page, pageSize: 100 }).assets);\n }\n return assets;\n}\n\nfunction upsertProject(database: DatabaseSync, project: string): void {\n const timestamp = nowIso();\n database.prepare(`\n insert into projects (id, product, catalog_path, created_at, updated_at)\n values (?, ?, ?, ?, ?)\n on conflict(id) do update set product = excluded.product, updated_at = excluded.updated_at\n `).run(project, project, join(repoRoot, project, 'assets', 'catalog.json'), timestamp, timestamp);\n}\n\nfunction upsertAsset(database: DatabaseSync, project: string, asset: GrowthAsset): void {\n const timestamp = nowIso();\n const source = asset.source === 'local' ? 'local' : 'catalog';\n database.prepare(`\n insert into assets (\n id, project_id, source, local_path, s3_key, checksum_sha256, media_type, title, status,\n channel, campaign, audience, size_bytes, content_type, created_at, updated_at, last_seen_at\n ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n on conflict(id) do update set\n source = excluded.source, local_path = excluded.local_path, s3_key = excluded.s3_key,\n checksum_sha256 = excluded.checksum_sha256, media_type = excluded.media_type,\n title = excluded.title, status = excluded.status, channel = excluded.channel,\n campaign = excluded.campaign, audience = excluded.audience, size_bytes = excluded.size_bytes,\n content_type = excluded.content_type, updated_at = excluded.updated_at, last_seen_at = excluded.last_seen_at\n `).run(\n asset.asset_id, project, source, asset.local?.relative_path || null, asset.s3?.key || null,\n asset.local?.checksum_sha256 || asset.s3?.checksum_sha256 || null, asset.content_type, asset.title,\n asset.status, asset.channel || null, asset.campaign || null, asset.audience || null,\n asset.local?.size_bytes || asset.s3?.size_bytes || null, asset.local?.content_type || asset.s3?.content_type || null,\n timestamp, timestamp, timestamp\n );\n database.prepare(`\n insert into asset_reviews (asset_id, review_state, updated_at)\n values (?, 'unreviewed', ?)\n on conflict(asset_id) do nothing\n `).run(asset.asset_id, timestamp);\n}\n\nexport function indexLineageAssets(project = defaultProject): LineageIndexSummary {\n const database = db();\n const catalog = collectAssets(project, 'catalog');\n const local = collectAssets(project, 'local');\n upsertProject(database, project);\n for (const asset of [...catalog, ...local]) upsertAsset(database, project, asset);\n database.close();\n return { catalog: catalog.length, local: local.length, total: catalog.length + local.length, database: lineageDbPath() };\n}\n\nfunction requireAsset(database: DatabaseSync, project: string, assetId: string): void {\n const row = database.prepare('select id from assets where project_id = ? and id = ?').get(project, assetId);\n if (!row) throw new LineageError(`Unknown indexed asset: ${assetId}`, 404);\n}\n\nfunction parentOf(database: DatabaseSync, project: string, assetId: string): string | undefined {\n const row = database.prepare('select parent_asset_id from asset_edges where project_id = ? and child_asset_id = ? order by created_at limit 1').get(project, assetId) as { parent_asset_id?: string } | undefined;\n return row?.parent_asset_id;\n}\n\nfunction rootFor(database: DatabaseSync, project: string, assetId: string): string {\n let root = assetId;\n const seen = new Set<string>();\n while (!seen.has(root)) {\n seen.add(root);\n const parent = parentOf(database, project, root);\n if (!parent) return root;\n root = parent;\n }\n return assetId;\n}\n\nfunction explicitWorkspaceRoot(database: DatabaseSync, project: string, assetId: string): string | undefined {\n const row = database.prepare(`\n select root_asset_id from lineage_workspaces\n where project_id = ? and root_asset_id = ? and status != 'archived'\n `).get(project, assetId) as { root_asset_id?: string } | undefined;\n return row?.root_asset_id;\n}\n\nfunction nearestWorkspaceRoot(database: DatabaseSync, project: string, assetId: string): string {\n let current = assetId;\n const seen = new Set<string>();\n while (!seen.has(current)) {\n seen.add(current);\n const explicit = explicitWorkspaceRoot(database, project, current);\n if (explicit) return explicit;\n const parent = parentOf(database, project, current);\n if (!parent) return current;\n current = parent;\n }\n return assetId;\n}\n\nfunction assetChannel(database: DatabaseSync, project: string, assetId: string): string | undefined {\n const row = database.prepare('select channel from assets where project_id = ? and id = ?').get(project, assetId) as { channel?: string } | undefined;\n return row?.channel;\n}\n\nfunction lineageWriteClaimContext(database: DatabaseSync, project: string, assetId: string): { channel?: string; rootAssetId: string } {\n return {\n channel: assetChannel(database, project, assetId),\n rootAssetId: nearestWorkspaceRoot(database, project, assetId),\n };\n}\n\nexport function getLineageWriteClaimContext(project: string, assetId: string): { channel?: string; rootAssetId: string } {\n const database = db();\n try {\n requireAsset(database, project, assetId);\n return lineageWriteClaimContext(database, project, assetId);\n } finally {\n database.close();\n }\n}\n\nfunction latestSelectedRoot(database: DatabaseSync, project: string): string | undefined {\n const row = database.prepare('select root_asset_id from asset_selections where project_id = ? order by selected_at desc limit 1').get(project) as { root_asset_id?: string } | undefined;\n return row?.root_asset_id;\n}\n\nfunction resolveRoot(database: DatabaseSync, project: string, rootAssetId?: string): string {\n if (rootAssetId) {\n requireAsset(database, project, rootAssetId);\n return rootAssetId;\n }\n const root = activeLineageWorkspaceRoot(project) || latestSelectedRoot(database, project);\n if (!root) throw new LineageError('Lineage command requires --root unless a project selection exists');\n requireAsset(database, project, root);\n return root;\n}\n\nfunction edgeId(project: string, parent: string, child: string): string {\n return `${project}:${parent}:derived_from:${child}`;\n}\n\nfunction canPreviewLocally(mediaType: string, localPath?: string): boolean {\n return Boolean(localPath && ['image', 'video', 'gif'].includes(mediaType));\n}\n\nfunction localPreviewUrl(project: string, localPath?: string): string | undefined {\n if (!localPath) return undefined;\n const params = new URLSearchParams({ project, path: localPath });\n return `/api/assets/local-preview?${params.toString()}`;\n}\n\nexport function linkLineageAssets(project: string, fields: LineageLinkFields) {\n const database = db();\n requireAsset(database, project, fields.parentAssetId);\n requireAsset(database, project, fields.childAssetId);\n if (fields.parentAssetId === fields.childAssetId) throw new LineageError('Lineage link cannot point to itself');\n const claimContext = lineageWriteClaimContext(database, project, fields.parentAssetId);\n try {\n requireLineageWorkspaceClaimForWrite({\n channel: claimContext.channel,\n claimToken: fields.claimToken,\n confirmWrite: fields.confirmWrite,\n project,\n rootAssetId: claimContext.rootAssetId,\n writeKind: 'lineage_link',\n });\n } catch (error) {\n database.close();\n throw error;\n }\n const edge = {\n id: edgeId(project, fields.parentAssetId, fields.childAssetId), parent_asset_id: fields.parentAssetId,\n child_asset_id: fields.childAssetId, relation_type: 'derived_from' as const, created_at: nowIso(),\n };\n if (!fields.confirmWrite) {\n database.close();\n return { ok: true as const, dryRun: true, edge };\n }\n database.prepare(`\n insert into asset_edges (id, project_id, parent_asset_id, child_asset_id, relation_type, created_at)\n values (?, ?, ?, ?, 'derived_from', ?)\n on conflict(project_id, parent_asset_id, child_asset_id, relation_type) do nothing\n `).run(edge.id, project, edge.parent_asset_id, edge.child_asset_id, edge.created_at);\n database.close();\n return { ok: true as const, message: `Linked ${edge.child_asset_id} from ${edge.parent_asset_id}`, edge };\n}\n\nfunction descendants(database: DatabaseSync, project: string, root: string): LineageEdge[] {\n const edges: LineageEdge[] = [];\n const queue = [root];\n const seen = new Set<string>();\n while (queue.length > 0) {\n const parent = queue.shift()!;\n if (seen.has(parent)) continue;\n seen.add(parent);\n const rows = database.prepare('select id, parent_asset_id, child_asset_id, relation_type, created_at from asset_edges where project_id = ? and parent_asset_id = ? order by created_at').all(project, parent) as unknown as LineageEdge[];\n edges.push(...rows);\n queue.push(...rows.map(row => row.child_asset_id));\n }\n return edges;\n}\n\nexport function getLineageSnapshot(project: string, assetId: string): LineageSnapshot {\n const database = db();\n requireAsset(database, project, assetId);\n const root = explicitWorkspaceRoot(database, project, assetId) || rootFor(database, project, assetId);\n const edges = descendants(database, project, root);\n const ids = [...new Set([root, ...edges.flatMap(edge => [edge.parent_asset_id, edge.child_asset_id])])];\n const placeholders = ids.map(() => '?').join(',');\n const rows = database.prepare(`\n select a.id asset_id, a.project_id project, a.source, a.title, a.media_type, a.status, a.channel, a.campaign,\n a.local_path, a.s3_key, a.checksum_sha256, coalesce(r.review_state, 'unreviewed') review_state,\n r.notes review_notes, l.x layout_x, l.y layout_y\n from assets a left join asset_reviews r on r.asset_id = a.id\n left join asset_layouts l on l.project_id = a.project_id and l.root_asset_id = ? and l.asset_id = a.id\n where a.project_id = ? and a.id in (${placeholders})\n `).all(root, project, ...ids) as Array<Omit<LineageNode, 'is_latest' | 'position' | 'preview_url' | 'selection_note' | 'user_selected'> & { layout_x?: number; layout_y?: number }>;\n const selected = selectedRows(database, project, root);\n const childIds = new Set(edges.map(edge => edge.parent_asset_id));\n const selectedIds = new Set(selected.map(row => row.asset_id));\n const selections = selected.map(row => ({\n asset_id: row.asset_id, notes: row.notes || undefined,\n position: Number(row.position || 0), selected_at: row.selected_at,\n }));\n const selection = selections[0] || null;\n const nodes = rows.map(row => {\n const position: LineagePosition | undefined = typeof row.layout_x === 'number' && typeof row.layout_y === 'number' ? { x: row.layout_x, y: row.layout_y } : undefined;\n const { layout_x: _layoutX, layout_y: _layoutY, ...node } = row;\n const nodeSelection = selections.find(item => item.asset_id === row.asset_id);\n return {\n ...node,\n is_latest: !childIds.has(row.asset_id),\n position,\n preview_url: canPreviewLocally(row.media_type, row.local_path) ? localPreviewUrl(project, row.local_path) : undefined,\n selection_note: nodeSelection?.notes,\n user_selected: selectedIds.has(row.asset_id),\n };\n });\n database.close();\n return {\n project,\n root_asset_id: root,\n active_asset_id: assetId,\n selected: selections.map(row => row.asset_id),\n selection,\n selections,\n latest: nodes.filter(node => node.is_latest).map(node => node.asset_id),\n nodes,\n edges,\n fetchedAt: nowIso(),\n };\n}\n\nexport function updateLineageLayout(project: string, fields: LineageLayoutFields) {\n if (fields.positions.length === 0) throw new LineageError('Lineage layout requires at least one position');\n const database = db();\n requireAsset(database, project, fields.rootAssetId);\n for (const position of fields.positions) requireAsset(database, project, position.assetId);\n try {\n requireLineageWorkspaceClaimForWrite({\n channel: assetChannel(database, project, fields.rootAssetId),\n claimToken: fields.claimToken,\n confirmWrite: fields.confirmWrite,\n project,\n rootAssetId: fields.rootAssetId,\n writeKind: 'lineage_layout',\n });\n } catch (error) {\n database.close();\n throw error;\n }\n if (!fields.confirmWrite) {\n database.close();\n return { ok: true as const, dryRun: true, root_asset_id: fields.rootAssetId, positions: fields.positions };\n }\n const timestamp = nowIso();\n const statement = database.prepare(`\n insert into asset_layouts (id, project_id, root_asset_id, asset_id, x, y, updated_at)\n values (?, ?, ?, ?, ?, ?, ?)\n on conflict(project_id, root_asset_id, asset_id) do update set\n x = excluded.x, y = excluded.y, updated_at = excluded.updated_at\n `);\n for (const position of fields.positions) {\n statement.run(`${project}:${fields.rootAssetId}:layout:${position.assetId}`, project, fields.rootAssetId, position.assetId, position.x, position.y, timestamp);\n }\n database.close();\n return { ok: true as const, message: `Saved ${fields.positions.length} lineage positions`, root_asset_id: fields.rootAssetId, positions: fields.positions };\n}\n\nexport function getLineageNextAsset(project: string, rootAssetId?: string): LineageNextResponse {\n const database = db();\n const root = resolveRoot(database, project, rootAssetId);\n database.close();\n const snapshot = getLineageSnapshot(project, root);\n const selectedNodes = snapshot.selected\n .map(assetId => snapshot.nodes.find(node => node.asset_id === assetId))\n .filter((node): node is LineageNode => Boolean(node));\n const latestNodes = snapshot.nodes.filter(node => snapshot.latest.includes(node.asset_id));\n const warnings: string[] = [];\n for (const selectedNode of selectedNodes) {\n if (selectedNode.is_latest) continue;\n warnings.push('Selected asset is not a latest leaf; agents should treat this as an intentional branch choice.');\n }\n if (selectedNodes.length > 0) {\n return {\n project,\n root_asset_id: snapshot.root_asset_id,\n strategy: 'selected',\n selection_mode: selectedNodes.length > 1 ? 'multiple' : 'single',\n recommended_action: 'evolve_variations',\n reason: 'user_selected',\n next_asset: selectedNodes[0],\n next_assets: selectedNodes,\n latest: snapshot.latest,\n selected: snapshot.selected,\n selection: snapshot.selection,\n selections: snapshot.selections,\n candidates: latestNodes,\n warnings,\n fetchedAt: nowIso(),\n };\n }\n if (latestNodes.length === 1) {\n return {\n project,\n root_asset_id: snapshot.root_asset_id,\n strategy: 'single_latest',\n selection_mode: 'fallback',\n recommended_action: 'evolve_variations',\n reason: 'single_latest_fallback',\n next_asset: latestNodes[0],\n next_assets: [latestNodes[0]],\n latest: snapshot.latest,\n selected: snapshot.selected,\n selection: snapshot.selection,\n selections: snapshot.selections,\n candidates: latestNodes,\n warnings,\n fetchedAt: nowIso(),\n };\n }\n return {\n project,\n root_asset_id: snapshot.root_asset_id,\n strategy: latestNodes.length > 1 ? 'ambiguous_latest' : 'empty',\n selection_mode: 'none',\n recommended_action: latestNodes.length > 1 ? 'choose_next_base' : 'none',\n reason: latestNodes.length > 1 ? 'multiple_latest_no_selection' : 'no_lineage_candidates',\n next_asset: null,\n next_assets: [],\n latest: snapshot.latest,\n selected: snapshot.selected,\n selection: snapshot.selection,\n selections: snapshot.selections,\n candidates: latestNodes,\n warnings,\n fetchedAt: nowIso(),\n };\n}\n\nexport function getLineageChildren(project: string, parentAssetId: string): LineageChildrenResponse {\n const snapshot = getLineageSnapshot(project, parentAssetId);\n const edges = snapshot.edges.filter(edge => edge.parent_asset_id === parentAssetId);\n const childIds = new Set(edges.map(edge => edge.child_asset_id));\n return {\n project, parent_asset_id: parentAssetId,\n children: snapshot.nodes.filter(node => childIds.has(node.asset_id)),\n edges, fetchedAt: nowIso(),\n };\n}\n\nexport function updateSelectedAsset(project: string, fields: SelectionFields) {\n const database = db();\n const inputAssetIds = normalizeSelectionInput(fields);\n const root = fields.rootAssetId || (inputAssetIds[0] ? rootFor(database, project, inputAssetIds[0]) : '');\n if (!root) throw new LineageError('Selection requires rootAssetId or assetId');\n requireAsset(database, project, root);\n for (const assetId of inputAssetIds) requireAsset(database, project, assetId);\n const mode = fields.mode || 'replace';\n const limit = fields.maxSelections || LINEAGE_NEXT_VARIATION_LIMIT;\n if (!fields.confirmWrite) {\n database.close();\n return { ok: true as const, dryRun: true, root_asset_id: root, asset_ids: inputAssetIds, mode, clear: Boolean(fields.clear), max_selections: limit };\n }\n const current = selectedRows(database, project, root);\n let nextIds = current.map(row => row.asset_id);\n if (fields.clear) {\n nextIds = [];\n } else if (mode === 'replace') {\n nextIds = inputAssetIds;\n } else if (mode === 'add') {\n nextIds = [...nextIds, ...inputAssetIds];\n } else if (mode === 'remove') {\n nextIds = nextIds.filter(assetId => !inputAssetIds.includes(assetId));\n } else if (mode === 'toggle') {\n for (const assetId of inputAssetIds) {\n nextIds = nextIds.includes(assetId) ? nextIds.filter(id => id !== assetId) : [...nextIds, assetId];\n }\n }\n nextIds = [...new Set(nextIds)];\n if (!fields.clear && inputAssetIds.length === 0) throw new LineageError('Selection set requires assetId or assetIds');\n if (nextIds.length > limit) throw new LineageError(`Select at most ${limit} assets for next variation`);\n database.prepare('delete from asset_selections where project_id = ? and root_asset_id = ?').run(project, root);\n const timestamp = nowIso();\n const insert = database.prepare(`\n insert into asset_selections (id, project_id, root_asset_id, asset_id, position, notes, selected_at)\n values (?, ?, ?, ?, ?, ?, ?)\n `);\n nextIds.forEach((assetId, position) => {\n const existing = current.find(row => row.asset_id === assetId);\n const notes = inputAssetIds.includes(assetId) ? fields.notes || existing?.notes : existing?.notes;\n insert.run(selectionId(project, root, assetId), project, root, assetId, position, notes || null, timestamp);\n });\n database.close();\n const message = nextIds.length === 0 ? `Cleared selected assets for ${root}` : `Selected ${nextIds.length} asset${nextIds.length === 1 ? '' : 's'} for ${root}`;\n return { ok: true as const, message, root_asset_id: root, asset_id: nextIds[0] || null, asset_ids: nextIds, mode };\n}\n\nexport function updateAssetReview(project: string, fields: ReviewFields) {\n const allowed = new Set<AssetReviewState>(['unreviewed', 'approved', 'needs_revision', 'rejected', 'ignored']);\n if (!allowed.has(fields.reviewState)) throw new LineageError(`Unsupported review state: ${fields.reviewState}`);\n const database = db();\n requireAsset(database, project, fields.assetId);\n if (!fields.confirmWrite) {\n database.close();\n return { ok: true as const, dryRun: true, asset_id: fields.assetId, review_state: fields.reviewState, notes: fields.notes };\n }\n const timestamp = nowIso();\n database.prepare(`\n insert into asset_reviews (asset_id, review_state, reviewed_at, ignored_at, notes, updated_at)\n values (?, ?, ?, ?, ?, ?)\n on conflict(asset_id) do update set\n review_state = excluded.review_state, reviewed_at = excluded.reviewed_at,\n ignored_at = excluded.ignored_at, notes = excluded.notes, updated_at = excluded.updated_at\n `).run(fields.assetId, fields.reviewState, timestamp, fields.reviewState === 'ignored' ? timestamp : null, fields.notes || null, timestamp);\n database.close();\n return { ok: true as const, message: `Marked ${fields.assetId} ${fields.reviewState}`, asset_id: fields.assetId, review_state: fields.reviewState };\n}\n", "import type { LineageBriefResponse, LineageSelectedChildFields } from '../shared/types';\nimport { AgentClaimError, validateAgentClaimForWrite } from './agentClaims';\nimport { getLineageNextAsset, getLineageWriteClaimContext, LineageError, linkLineageAssets } from './assetLineage';\nimport { lineageDbPath, nowIso } from './assetLineageDb';\nimport { lineageWorkspaceId } from './assetLineageWorkspaces';\n\nconst publicPackageCommand = 'npx @mean-weasel/lineage';\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nfunction lineageCommand(command: string, project: string, rootAssetId: string): string {\n return `${publicPackageCommand} ${command} --project ${shellQuote(project)} --root ${shellQuote(rootAssetId)} --db ${shellQuote(lineageDbPath())} --json`;\n}\n\nfunction linkChildCommand(project: string, rootAssetId: string): string {\n return `${publicPackageCommand} link-child --project ${shellQuote(project)} --root ${shellQuote(rootAssetId)} --child <asset-id> --confirm-write --db ${shellQuote(lineageDbPath())} --json`;\n}\n\nexport function getLineageBrief(project: string, rootAssetId?: string): LineageBriefResponse {\n const next = getLineageNextAsset(project, rootAssetId);\n const assets = next.next_assets;\n const asset = next.next_asset;\n const referenceAssetIds = assets.map(item => item.asset_id);\n const rationale = next.selections.map(selection => selection.notes).find(Boolean) || asset?.selection_note || next.selection?.notes;\n const channels = [...new Set(assets.map(item => item.channel || 'unknown'))];\n const campaigns = [...new Set(assets.map(item => item.campaign || 'unknown'))];\n const prompt = assets.length > 0\n ? [\n assets.length === 1\n ? `Create 3-4 variations from asset ${assets[0].asset_id} (${assets[0].title}).`\n : `Create 3-4 variations using these ${assets.length} selected references: ${referenceAssetIds.join(', ')}.`,\n rationale ? `Preserve this selection rationale: ${rationale}` : 'Preserve the strongest visible ideas while exploring distinct alternatives.',\n `Keep project=${project}, root=${next.root_asset_id}, channels=${channels.join(',')}, campaigns=${campaigns.join(',')}.`,\n 'After generation, index outputs and link chosen children with lineage link-child.',\n ].join(' ')\n : 'Select one to three latest lineage candidates before generating variations.';\n return {\n project,\n root_asset_id: next.root_asset_id,\n strategy: next.strategy,\n selection_mode: next.selection_mode,\n recommended_action: next.recommended_action,\n reason: next.reason,\n next_asset: asset,\n next_assets: assets,\n selection: next.selection,\n selections: next.selections,\n latest: next.latest,\n warnings: next.warnings,\n brief: {\n title: asset ? `Evolve ${assets.length > 1 ? `${assets.length} selected bases` : asset.title}` : 'Choose next lineage base',\n objective: asset ? 'Generate the next branch of visual variations from the selected lineage base or bases.' : 'Resolve the next base before generation.',\n prompt,\n reference_asset_id: asset?.asset_id,\n reference_asset_ids: referenceAssetIds,\n rationale,\n },\n handoff: {\n next_command: lineageCommand('next', project, next.root_asset_id),\n inspect_command: asset ? `${publicPackageCommand} inspect --project ${shellQuote(project)} --asset-id ${shellQuote(asset.asset_id)} --db ${shellQuote(lineageDbPath())} --json` : undefined,\n link_child_command: asset ? linkChildCommand(project, next.root_asset_id) : undefined,\n },\n fetchedAt: nowIso(),\n };\n}\n\nexport function linkSelectedLineageChild(project: string, fields: LineageSelectedChildFields) {\n const next = getLineageNextAsset(project, fields.rootAssetId);\n if (!next.next_asset) throw new LineageError('Cannot link child until a next base is selected or unambiguous');\n if (fields.confirmWrite) {\n const claimContext = getLineageWriteClaimContext(project, next.next_asset.asset_id);\n const validation = validateAgentClaimForWrite({\n channel: claimContext.channel,\n claimToken: fields.claimToken,\n confirmWrite: fields.confirmWrite,\n dangerLevel: 'enforce',\n project,\n scopeType: 'lineage_workspace',\n targetId: lineageWorkspaceId(project, claimContext.rootAssetId),\n writeKind: 'link_child',\n });\n if (!validation.ok) throw new AgentClaimError(validation.message, validation.code === 'claim_required' ? 401 : 403, validation.code, validation.conflicts);\n }\n const result = linkLineageAssets(project, {\n childAssetId: fields.childAssetId,\n confirmWrite: fields.confirmWrite,\n claimToken: fields.claimToken,\n parentAssetId: next.next_asset.asset_id,\n });\n return {\n ...result,\n root_asset_id: next.root_asset_id,\n parent_asset_id: next.next_asset.asset_id,\n child_asset_id: fields.childAssetId,\n reference_asset_ids: next.next_assets.map(asset => asset.asset_id),\n warning: next.next_assets.length > 1\n ? 'Linked child to the primary selected base; add explicit edges to other selected references if the child derives from them too.'\n : undefined,\n };\n}\n", "#!/usr/bin/env node\n\nimport { runLineageCli } from './lineageCli';\n\nrunLineageCli({ binName: 'lineage', channel: 'stable', defaultHost: 'lineage.localhost', defaultPort: 5197, displayName: 'Lineage' });\n"],
5
+ "mappings": ";;;AAAA,SAAS,cAAAA,aAAY,aAAAC,YAAW,gBAAAC,qBAAoB;AACpD,SAAS,SAAS,gBAAgB;AAClC,SAAS,WAAAC,UAAS,QAAAC,OAAM,WAAAC,gBAAe;AACvC,SAAS,aAAa;AACtB,SAAS,iBAAAC,sBAAqB;;;ACJ9B,SAAS,cAAAC,aAAY,aAAa,uBAAuB;;;ACAzD,SAAS,qBAAqB;AAE9B,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,QAAAC,aAAY;;;ACHrB,SAAS,cAAAC,aAAY,aAAAC,YAAW,eAAAC,cAAa,gBAAAC,eAAc,YAAY,qBAAqB;AAC5F,SAAS,WAAAC,UAAS,QAAAC,OAAM,WAAAC,gBAAe;AACvC,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB;;;ACH9B,SAAS,cAAc,cAAAC,aAAY,WAAW,YAAAC,iBAAgB;AAC9D,SAAS,YAAAC,WAAU,SAAS,QAAAC,aAAY;;;ACDxC,SAAS,kBAAkB;AAC3B,SAAS,YAAY,aAAa,cAAc,gBAAgB;AAChE,SAAS,UAAU,SAAS,MAAM,UAAU,eAAe;AAG3D,IAAM,YAAoC;AAAA,EACxC,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AACX;AACA,IAAM,kBAAkB,IAAI,IAAI,OAAO,KAAK,SAAS,CAAC;AAY/C,SAAS,eAAe,MAAsB;AACnD,SAAO,UAAU,QAAQ,IAAI,EAAE,YAAY,CAAC,KAAK;AACnD;AAEO,SAAS,WAAW,MAAsB;AAC/C,SAAO,WAAW,QAAQ,EAAE,OAAO,aAAa,IAAI,CAAC,EAAE,OAAO,KAAK;AACrE;;;AD3BO,SAAS,sBAAsB,KAAiC;AACrE,QAAM,SAAS;AACf,QAAM,QAAQ,IAAI,QAAQ,MAAM;AAChC,MAAI,UAAU,GAAI,QAAO;AACzB,SAAO,IAAI,MAAM,QAAQ,OAAO,MAAM,EAAE,MAAM,GAAG,EAAE,CAAC;AACtD;AAEA,SAAS,eAAe,OAAwF;AAC9G,QAAM,QAAQ,MAAM,SAAS,MAAM;AACnC,QAAM,QAAQ,GAAG,MAAM,WAAW,SAAS,MAAM,MAAM,UAAU,SAAS;AAC1E,QAAM,MAAM,0bAA0b,cAAc,MAAM,QAAQ,CAAC,6FAA6F,cAAc,KAAK,CAAC,6FAA6F,cAAc,KAAK,CAAC;AACrsB,SAAO,6BAA6B,OAAO,KAAK,GAAG,EAAE,SAAS,QAAQ,CAAC;AACzE;AAEA,SAAS,cAAc,OAAuB;AAC5C,SAAO,MACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ;AAC3B;AAEO,SAAS,uBAAuB,MAAkD;AACvF,SAAO;AAAA,IACL,oBAAoB,SAAS,SAAS,cAAgC;AACpE,YAAM,UAAU,QAAQ,IAAI,gCAAgC;AAC5D,UAAI,CAAC,SAAS;AACZ,cAAM,KAAK,YAAY,0FAA0F,GAAG;AAAA,MACtH;AACA,UAAI,iBAAiB,UAAU,OAAO,IAAI;AACxC,cAAM,KAAK,YAAY,kDAAkD,OAAO,EAAE;AAAA,MACpF;AACA,YAAM,UAAU,KAAK,YAAY,OAAO;AACxC,YAAM,QAAQ,KAAK,UAAU,SAAS,OAAO;AAC7C,UAAI,CAAC,MAAM,GAAI,OAAM,KAAK,YAAY,2BAA2B,OAAO,EAAE;AAC1E,WAAK,OAAO,CAAC,SAAS,iBAAiB,YAAY,MAAM,GAAG,QAAQ,SAAS,MAAM,GAAG,KAAK,YAAY,MAAM,GAAG,MAAM,CAAC;AACvH,YAAM,SAAS;AACf,WAAK,YAAY,SAAS,OAAO;AACjC,aAAO,EAAE,IAAI,MAAM,SAAS,0CAA0C,OAAO,IAAI,QAAQ;AAAA,IAC3F;AAAA,IAEA,cAAc;AACZ,UAAI;AACF,cAAM,SAAS,KAAK,OAAO,CAAC,OAAO,uBAAuB,WAAW,6BAA6B,YAAY,MAAM,CAAC;AACrH,cAAM,SAAS,KAAK,MAAM,OAAO,MAAM;AACvC,eAAO,EAAE,SAAS,OAAO,SAAS,KAAK,OAAO,IAAI;AAAA,MACpD,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,gBAAgB,SAAuC;AACrD,YAAM,SAAS,QAAQ;AACvB,YAAM,SAAS,QAAQ;AAEvB,YAAM,SAAS,YAAY,QAAQ,OAAO;AAC1C,YAAM,SAAS,KAAK,OAAO,CAAC,SAAS,mBAAmB,YAAY,QAAQ,YAAY,QAAQ,YAAY,QAAQ,YAAY,MAAM,CAAC;AACvI,YAAM,SAAS,KAAK,MAAM,OAAO,MAAM;AAGvC,YAAM,cAAc,IAAI,IAAI,QAAQ,OAAO,IAAI,WAAS,MAAM,IAAI,GAAG,EAAE,OAAO,OAAO,CAAC;AACtF,cAAQ,OAAO,YAAY,CAAC,GAAG,IAAI,WAAS;AAAA,QAC1C,KAAK,KAAK;AAAA,QACV,MAAM,KAAK;AAAA,QACX,cAAc,KAAK;AAAA,QACnB,cAAc,KAAK;AAAA,QACnB,WAAW,YAAY,IAAI,KAAK,GAAG;AAAA,QACnC,SAAS,sBAAsB,KAAK,GAAG;AAAA,MACzC,EAAE;AAAA,IACJ;AAAA,IAEA,aAAa,SAAS,SAAS,YAAY,KAAsB;AAC/D,YAAM,UAAU,KAAK,YAAY,OAAO;AACxC,YAAM,QAAQ,KAAK,UAAU,SAAS,OAAO;AAC7C,aAAO,EAAE,SAAS,WAAW,KAAK,eAAe,KAAK,EAAE;AAAA,IAC1D;AAAA,IAEA,aAAa,SAAS,SAAS,cAAgC;AAC7D,UAAI,CAAC,aAAc,OAAM,KAAK,YAAY,oCAAoC;AAC9E,YAAM,UAAU,KAAK,YAAY,OAAO;AACxC,YAAM,QAAQ,KAAK,UAAU,SAAS,OAAO;AAC7C,YAAM,SAAS;AACf,WAAK,YAAY,SAAS,OAAO;AACjC,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,SAAS,YAAY,OAAO;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,IAEA,UAAU,SAAS,SAAS,MAAM,kBAAoC;AACpE,YAAM,UAAU,KAAK,YAAY,OAAO;AACxC,YAAM,QAAQ,KAAK,UAAU,SAAS,OAAO;AAC7C,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,SAAS,YAAY,OAAO;AAAA,QAC5B,QAAQ;AAAA,UACN,SAAS,MAAM;AAAA,UACf;AAAA,UACA,SAAS,MAAM,QAAQ,UAAU,MAAM,KAAK,wBAAwB;AAAA,UACpE,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,IAEA,YAAY,MAAM,QAA0B;AAC1C,UAAI,CAAC,OAAO,aAAc,OAAM,KAAK,YAAY,mCAAmC;AACpF,UAAI,CAACC,YAAW,IAAI,EAAG,OAAM,KAAK,YAAY,wBAAwB,IAAI,IAAI,GAAG;AACjF,UAAI,CAAC,CAAC,WAAW,WAAW,EAAE,SAAS,OAAO,MAAM,EAAG,OAAM,KAAK,YAAY,4CAA4C;AAC1H,UAAI,CAAC,KAAK,sBAAsB,IAAI,OAAO,IAAI,EAAG,OAAM,KAAK,YAAY,2BAA2B,OAAO,IAAI,EAAE;AAEjH,YAAM,UAAU,KAAK,aAAa,OAAO,WAAW,OAAO,WAAW,KAAK,cAAc;AACzF,YAAM,UAAU,KAAK,YAAY,OAAO;AACxC,YAAM,eAAeC,MAAK,WAAW,SAAS,OAAO,SAASC,UAAS,IAAI,CAAC;AAC5E,YAAM,eAAeD,MAAK,KAAK,UAAU,kBAAkB,YAAY;AACvE,gBAAU,QAAQ,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;AACpD,mBAAa,MAAM,YAAY;AAC/B,YAAM,QAAQE,UAAS,YAAY;AACnC,YAAM,cAAc,eAAe,YAAY;AAC/C,YAAM,iBAAiB,WAAW,YAAY;AAC9C,YAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,YAAM,YAAY;AAAA,QAChB,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,QACjB,SAAS,OAAO;AAAA,QAChB,cAAc,OAAO;AAAA,QACrB,KAAK,OAAO;AAAA,QACZ,MAAM,OAAO;AAAA,QACb,GAAI,OAAO,SAAS,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,QACjD,OAAO;AAAA,UACL,eAAe;AAAA,UACf,iBAAiB;AAAA,UACjB,cAAc;AAAA,UACd,eAAe;AAAA,UACf,YAAY,MAAM;AAAA,UAClB,YAAY;AAAA,QACd;AAAA,QACA,GAAI,OAAO,gBAAgB,EAAE,gBAAgB,OAAO,cAAc,IAAI,CAAC;AAAA,QACvE,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,QAC9C,SAAS;AAAA,QACT;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ,OAAO;AAAA,QACf,OAAO,OAAO;AAAA,QACd,aAAa,OAAO;AAAA,MACtB;AACA,YAAM,WAAW,QAAQ,OAAO,UAAU,WAAS,MAAM,aAAa,OAAO,OAAO;AACpF,UAAI,YAAY,EAAG,SAAQ,OAAO,QAAQ,IAAI,EAAE,GAAG,QAAQ,OAAO,QAAQ,GAAG,GAAG,UAAU;AAAA,UACrF,SAAQ,OAAO,KAAK,SAAS;AAClC,WAAK,YAAY,SAAS,OAAO;AACjC,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,SAAS,YAAY,OAAO,OAAO;AAAA,QACnC,QAAQ;AAAA,UACN,MAAMD,UAAS,YAAY;AAAA,UAC3B;AAAA,UACA,WAAW,MAAM;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ADlJA,SAAS,cAAc,MAAuB;AAC5C,QAAM,cAAcE,MAAK,MAAM,cAAc;AAC7C,MAAI,CAACC,YAAW,WAAW,EAAG,QAAO;AACrC,MAAI;AACF,UAAM,cAAc,KAAK,MAAMC,cAAa,aAAa,MAAM,CAAC;AAChE,WAAO,YAAY,SAAS;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAA0B;AACjC,QAAM,YAAYC,SAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,QAAM,aAAa;AAAA,IACjB,QAAQ,IAAI;AAAA,IACZC,SAAQ,WAAW,IAAI;AAAA,IACvBA,SAAQ,WAAW,OAAO;AAAA,IAC1B,QAAQ,IAAI;AAAA,EACd,EAAE,OAAO,CAAC,cAAmC,QAAQ,SAAS,CAAC;AAC/D,QAAM,OAAO,WAAW,KAAK,aAAa;AAC1C,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,uCAAuC;AAClE,SAAO;AACT;AAEO,IAAM,WAAW,gBAAgB;AACjC,IAAM,iBAAiB;AACvB,IAAM,iBAAiB,QAAQ,IAAI,2BAA2B;AACrE,IAAM,uBAAuB;AAC7B,IAAM,uBAAuB;AAC7B,IAAM,eAAe,oBAAI,IAAsB,CAAC,SAAS,SAAS,OAAO,SAAS,OAAO,OAAO,CAAC;AAGjG,IAAM,qBAAqB;AAO3B,IAAM,oBAAN,cAAgC,MAAM;AAAA,EACpC,YAAY,SAAwB,SAAS,KAAK;AAChD,UAAM,OAAO;AADqB;AAAA,EAEpC;AAAA,EAFoC;AAGtC;AAMO,SAAS,aAAa,UAAU,gBAAwB;AAC7D,MAAI,CAAC,mBAAmB,KAAK,OAAO,GAAG;AACrC,UAAM,IAAI,kBAAkB,sCAAsC;AAAA,EACpE;AACA,SAAO;AACT;AAEO,SAAS,YAAY,UAAU,gBAAwB;AAC5D,SAAOC,MAAK,UAAU,aAAa,OAAO,GAAG,UAAU,cAAc;AACvE;AAEA,SAAS,mBAAmB,UAAU,gBAAwB;AAC5D,SAAOA,MAAK,UAAU,YAAY,aAAa,OAAO,GAAG,UAAU,cAAc;AACnF;AAUO,SAAS,iBAAiB,SAAgC,kBAAkB,gBAA8B;AAC/G,QAAM,UAAU,aAAa,QAAQ,WAAW,QAAQ,WAAW,eAAe;AAClF,QAAM,UAAU,QAAQ,WAAW;AACnC,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA,gBAAgB,QAAQ,kBAAkB;AAAA,IAC1C,gBAAgB,QAAQ,kBAAkB;AAAA,IAC1C,SAAS,QAAQ,UAAU,CAAC,GAAG,IAAI,YAAU;AAAA,MAC3C,GAAG;AAAA,MACH,QAAQ,MAAM,UAAU;AAAA,MACxB,SAAS,MAAM,WAAW,MAAM,WAAW;AAAA,MAC3C,SAAS,MAAM,WAAW,MAAM,WAAW;AAAA,IAC7C,EAAE;AAAA,EACJ;AACF;AAEA,SAAS,WAAW,SAAiB,SAAiB,SAAS,WAAW;AACxE,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,KAAK,YAAY,cAAc,2CAA2C,OAAO,gCAAgC,MAAM,uBAAuB,OAAO,IAAI,OAAO;AAAA,IAChK,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACF;AAEA,SAAS,cAAc,QAMP;AACd,SAAO;AAAA,IACL,UAAU,OAAO,YAAY;AAAA,IAC7B,UAAU,OAAO,YAAY;AAAA,IAC7B,cAAc;AAAA,IACd,KAAK,OAAO,OAAO;AAAA,IACnB,MAAM,OAAO,QAAQ;AAAA,IACrB,SAAS;AAAA,IACT,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa,OAAO,eAAe,OAAO,SAAS,QAAQ,MAAM,GAAG;AAAA,IACpE,GAAG;AAAA,EACL;AACF;AAEA,SAAS,yBAAuC;AAC9C,SAAO,iBAAiB;AAAA,IACtB,QAAQ;AAAA,MACN,cAAc;AAAA,QACZ,UAAU;AAAA,QACV,SAAS;AAAA,QACT,IAAI,WAAW,gDAAgD,MAAM;AAAA,QACrE,QAAQ;AAAA,QACR,OAAO;AAAA,MACT,CAAC;AAAA,MACD,cAAc;AAAA,QACZ,UAAU;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,QACN,IAAI,WAAW,uCAAuC,UAAU;AAAA,QAChE,QAAQ;AAAA,QACR,OAAO;AAAA,MACT,CAAC;AAAA,MACD,cAAc;AAAA,QACZ,UAAU;AAAA,QACV,SAAS;AAAA,QACT,YAAY,CAAC;AAAA,UACX,SAAS;AAAA,UACT,OAAO;AAAA,UACP,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,YAAY;AAAA,QACd,CAAC;AAAA,QACD,IAAI,WAAW,qDAAqD,YAAY,UAAU;AAAA,QAC1F,QAAQ;AAAA,QACR,OAAO;AAAA,MACT,CAAC;AAAA,MACD,cAAc;AAAA,QACZ,UAAU;AAAA,QACV,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,IAAI,WAAW,2CAA2C,QAAQ;AAAA,QAClE,QAAQ;AAAA,QACR,OAAO;AAAA,MACT,CAAC;AAAA,MACD,cAAc;AAAA,QACZ,UAAU;AAAA,QACV,SAAS;AAAA,QACT,YAAY,CAAC;AAAA,UACX,SAAS;AAAA,UACT,OAAO;AAAA,UACP,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,YAAY;AAAA,QACd,CAAC;AAAA,QACD,IAAI,WAAW,sCAAsC,WAAW,WAAW;AAAA,QAC3E,QAAQ;AAAA,QACR,OAAO;AAAA,MACT,CAAC;AAAA,MACD,cAAc;AAAA,QACZ,UAAU;AAAA,QACV,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,IAAI,WAAW,+CAA+C,WAAW;AAAA,QACzE,QAAQ;AAAA,QACR,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT,SAAS;AAAA,EACX,GAAG,cAAc;AACnB;AAoBO,SAAS,YAAY,UAAU,gBAA8B;AAClE,QAAM,OAAO,YAAY,OAAO;AAChC,MAAIC,YAAW,IAAI,GAAG;AACpB,QAAI;AACF,aAAO,iBAAiB,KAAK,MAAMC,cAAa,MAAM,MAAM,CAAC,GAA4B,OAAO;AAAA,IAClG,SAAS,OAAO;AACd,UAAI,SAAS,OAAO,UAAU,YAAY,UAAU,SAAS,MAAM,SAAS,UAAU;AACpF,cAAM,IAAI,kBAAkB,oBAAoB,IAAI,IAAI,GAAG;AAAA,MAC7D;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACA,QAAM,QAAQ,aAAa,OAAO;AAClC,MAAI,UAAU,gBAAgB;AAC5B,UAAM,cAAc,mBAAmB,KAAK;AAC5C,QAAID,YAAW,WAAW,GAAG;AAC3B,aAAO,iBAAiB,KAAK,MAAMC,cAAa,aAAa,MAAM,CAAC,GAA4B,OAAO;AAAA,IACzG;AACA,WAAO,uBAAuB;AAAA,EAChC;AACA,QAAM,IAAI,kBAAkB,oBAAoB,IAAI,IAAI,GAAG;AAC7D;AAEA,SAAS,YAAY,SAAiB,SAAqC;AACzE,QAAM,aAAa,iBAAiB,SAAS,OAAO;AACpD,EAAAC,WAAUC,SAAQ,YAAY,OAAO,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5D,gBAAc,YAAY,OAAO,GAAG,GAAG,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;AAAA,CAAI;AAC9E,SAAO;AACT;AAEA,SAAS,IAAI,SAAiB,MAA+B;AAC3D,QAAM,SAAS,UAAU,SAAS,MAAM;AAAA,IACtC,KAAK;AAAA,IACL,UAAU;AAAA,IACV,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,IAChC,KAAK;AAAA,MACH,GAAG,QAAQ;AAAA,MACX,YAAY,QAAQ,IAAI,cAAc;AAAA,MACtC,oBAAoB,QAAQ,IAAI,sBAAsB;AAAA,IACxD;AAAA,EACF,CAAC;AAED,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,SAAS,OAAO,OAAO,KAAK,KAAK,OAAO,OAAO,KAAK;AAC1D,UAAM,IAAI,kBAAkB,GAAG,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC,UAAU,SAAS,KAAK,MAAM,KAAK,EAAE,IAAI,GAAG;AAAA,EACtG;AAEA,SAAO,EAAE,QAAQ,OAAO,QAAQ,QAAQ,OAAO,OAAO;AACxD;AAEA,SAAS,OAAO,MAA+B;AAC7C,SAAO,IAAI,OAAO,IAAI;AACxB;AAuBA,SAAS,UAAU,SAAuB,SAA8B;AACtE,QAAM,QAAQ,QAAQ,OAAO,KAAK,UAAQ,KAAK,aAAa,OAAO;AACnE,MAAI,CAAC,MAAO,OAAM,IAAI,kBAAkB,kBAAkB,OAAO,IAAI,GAAG;AACxE,SAAO;AACT;AAEA,IAAM,iBAAiB,uBAAuB;AAAA,EAC5C;AAAA,EACA;AAAA,EACA,aAAa,CAAC,SAAS,WAAW,IAAI,kBAAkB,SAAS,MAAM;AAAA,EACvE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,uBAAuB;AACzB,CAAC;;;ADnUD,IAAMC,WAAU,cAAc,YAAY,GAAG;AAGtC,SAAS,SAAiB;AAC/B,UAAO,oBAAI,KAAK,GAAE,YAAY;AAChC;AAEO,SAAS,gBAAwB;AACtC,SAAO,QAAQ,IAAI,cAAcC,MAAK,UAAU,YAAY,sBAAsB;AACpF;AAEO,SAAS,YAA0B;AACxC,EAAAC,WAAUD,MAAK,cAAc,GAAG,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,QAAM,EAAE,aAAa,IAAID,SAAQ,aAAa;AAC9C,QAAM,WAAW,IAAI,aAAa,cAAc,CAAC;AACjD,WAAS,KAAK,0BAA0B;AAAG,WAAS,KAAK,4BAA4B;AACrF,WAAS,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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",
6
+ "names": ["existsSync", "mkdirSync", "readFileSync", "dirname", "join", "resolve", "fileURLToPath", "createHash", "mkdirSync", "join", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "dirname", "join", "resolve", "existsSync", "statSync", "basename", "join", "existsSync", "join", "basename", "statSync", "join", "existsSync", "readFileSync", "dirname", "resolve", "join", "existsSync", "readFileSync", "mkdirSync", "dirname", "require", "join", "mkdirSync", "createHash", "claim", "ensureProject", "ensureProject", "channelOverlaps", "resolve", "dirname", "fileURLToPath", "readFileSync", "join", "existsSync", "mkdirSync", "json", "message"]
7
7
  }