mirror of
https://github.com/stablyai/orca.git
synced 2026-10-02 00:02:05 +00:00
* oom(01): A1-shared-readers — reintroduce #10179 subset Files: 18 applied, 0 deleted (from6eb70d8370) Co-authored-by: Orca <help@stably.ai> * oom(02): A2-shared-image-media — reintroduce #10179 subset Files: 7 applied, 0 deleted (from6eb70d8370) Co-authored-by: Orca <help@stably.ai> * oom(03): A3-shared-fs-listing — reintroduce #10179 subset Files: 21 applied, 0 deleted (from6eb70d8370) Co-authored-by: Orca <help@stably.ai> * oom(04): A4-shared-remote-relay — reintroduce #10179 subset Files: 8 applied, 0 deleted (from6eb70d8370) Co-authored-by: Orca <help@stably.ai> * oom(05): A5-shared-misc — reintroduce #10179 subset Files: 28 applied, 0 deleted (from6eb70d8370) Co-authored-by: Orca <help@stably.ai> * oom(06): B-shared-wiring — reintroduce #10179 subset Files: 81 applied, 0 deleted (from6eb70d8370) Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai>
321 lines
9.5 KiB
TypeScript
321 lines
9.5 KiB
TypeScript
import { inspectCodexEnvironmentConfig } from './setup-script-import-codex-environment'
|
|
import { inspectPackageManagerSetupCandidate } from './setup-script-package-manager-suggestion'
|
|
import type { SetupScriptImportProvider } from './setup-script-import-providers'
|
|
import {
|
|
isSetupScriptImportFieldWithinLimit,
|
|
isSetupScriptImportTextWithinLimit,
|
|
SETUP_SCRIPT_IMPORT_MAX_CMUX_COMMANDS,
|
|
SETUP_SCRIPT_IMPORT_MAX_KEYWORDS,
|
|
SETUP_SCRIPT_IMPORT_MAX_UNSUPPORTED_FIELDS
|
|
} from './setup-script-import-limits'
|
|
import {
|
|
joinSetupScriptImportCommands,
|
|
normalizeSetupScriptImportCommand,
|
|
pushSetupScriptImportUnsupportedField
|
|
} from './setup-script-import-command-limits'
|
|
|
|
export type SetupScriptImportCandidate = {
|
|
provider: SetupScriptImportProvider
|
|
label: string
|
|
files: string[]
|
|
setup: string
|
|
archive?: string
|
|
unsupportedFields?: string[]
|
|
}
|
|
|
|
export type SetupScriptImportFileRead = (relativePath: string) => Promise<string | null>
|
|
export type SetupScriptImportFileExists = (relativePath: string) => Promise<boolean>
|
|
|
|
const SUPERSET_CONFIG_PATH = '.superset/config.json'
|
|
const SUPERSET_LOCAL_CONFIG_PATH = '.superset/config.local.json'
|
|
const CONDUCTOR_CONFIG_PATH = 'conductor.json'
|
|
const CMUX_CONFIG_PATHS = ['.cmux/cmux.json', 'cmux.json'] as const
|
|
|
|
export async function inspectSetupScriptImportCandidates(
|
|
readFile: SetupScriptImportFileRead,
|
|
options?: { fileExists?: SetupScriptImportFileExists }
|
|
): Promise<SetupScriptImportCandidate[]> {
|
|
const boundedReadFile: SetupScriptImportFileRead = async (relativePath) => {
|
|
const content = await readFile(relativePath)
|
|
return content !== null && isSetupScriptImportTextWithinLimit(content) ? content : null
|
|
}
|
|
const candidates = await Promise.all([
|
|
inspectSupersetConfig(boundedReadFile),
|
|
inspectConductorConfig(boundedReadFile),
|
|
inspectCodexEnvironmentConfig(boundedReadFile),
|
|
inspectCmuxConfig(boundedReadFile),
|
|
inspectPackageManagerSetupCandidate(boundedReadFile, options?.fileExists)
|
|
])
|
|
return candidates.filter(
|
|
(candidate): candidate is SetupScriptImportCandidate => candidate != null
|
|
)
|
|
}
|
|
|
|
async function inspectSupersetConfig(
|
|
readFile: SetupScriptImportFileRead
|
|
): Promise<SetupScriptImportCandidate | null> {
|
|
const config = parseJsonObject(await readFile(SUPERSET_CONFIG_PATH))
|
|
if (!config) {
|
|
return null
|
|
}
|
|
|
|
const localConfig = parseJsonObject(await readFile(SUPERSET_LOCAL_CONFIG_PATH))
|
|
const unsupportedFields = collectUnsupportedFields(config, ['run', 'cwd'])
|
|
const files = localConfig
|
|
? [SUPERSET_CONFIG_PATH, SUPERSET_LOCAL_CONFIG_PATH]
|
|
: [SUPERSET_CONFIG_PATH]
|
|
if (localConfig) {
|
|
unsupportedFields.push(
|
|
...collectUnsupportedFields(localConfig, ['run', 'cwd']).map(
|
|
(field) => `config.local.${field}`
|
|
)
|
|
)
|
|
}
|
|
|
|
const setup = resolveSupersetScriptValue(
|
|
config.setup,
|
|
localConfig?.setup,
|
|
'setup',
|
|
unsupportedFields
|
|
)
|
|
if (!setup) {
|
|
return null
|
|
}
|
|
|
|
collectUnsupportedScriptObjectFields(config.setup, 'setup', unsupportedFields)
|
|
collectUnsupportedScriptObjectFields(config.teardown, 'teardown', unsupportedFields)
|
|
|
|
return {
|
|
provider: 'superset',
|
|
label: 'Superset',
|
|
files,
|
|
setup,
|
|
archive:
|
|
resolveSupersetScriptValue(
|
|
config.teardown,
|
|
localConfig?.teardown,
|
|
'teardown',
|
|
unsupportedFields
|
|
) || undefined,
|
|
unsupportedFields
|
|
}
|
|
}
|
|
|
|
async function inspectConductorConfig(
|
|
readFile: SetupScriptImportFileRead
|
|
): Promise<SetupScriptImportCandidate | null> {
|
|
const config = parseJsonObject(await readFile(CONDUCTOR_CONFIG_PATH))
|
|
const scripts = asRecord(config?.scripts)
|
|
if (!config || !scripts) {
|
|
return null
|
|
}
|
|
|
|
const setup = normalizeSetupScriptImportCommand(scripts.setup)
|
|
if (!setup) {
|
|
return null
|
|
}
|
|
|
|
const unsupportedFields = collectUnsupportedFields(config, [
|
|
'enterpriseDataPrivacy',
|
|
'runScriptMode'
|
|
])
|
|
for (const field of ['run', 'teardown'] as const) {
|
|
if (normalizeSetupScriptImportCommand(scripts[field])) {
|
|
unsupportedFields.push(`scripts.${field}`)
|
|
}
|
|
}
|
|
|
|
return {
|
|
provider: 'conductor',
|
|
label: 'Conductor',
|
|
files: [CONDUCTOR_CONFIG_PATH],
|
|
setup,
|
|
archive: normalizeSetupScriptImportCommand(scripts.archive) || undefined,
|
|
unsupportedFields
|
|
}
|
|
}
|
|
|
|
async function inspectCmuxConfig(
|
|
readFile: SetupScriptImportFileRead
|
|
): Promise<SetupScriptImportCandidate | null> {
|
|
for (const configPath of CMUX_CONFIG_PATHS) {
|
|
const config = parseJsonObject(await readFile(configPath))
|
|
const candidate = config ? buildCmuxSetupCandidate(configPath, config) : null
|
|
if (candidate) {
|
|
return candidate
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
function parseJsonObject(content: string | null): Record<string, unknown> | null {
|
|
if (!content) {
|
|
return null
|
|
}
|
|
try {
|
|
return asRecord(JSON.parse(content))
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
function asRecord(value: unknown): Record<string, unknown> | null {
|
|
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
? (value as Record<string, unknown>)
|
|
: null
|
|
}
|
|
|
|
function resolveSupersetScriptValue(
|
|
baseValue: unknown,
|
|
localValue: unknown,
|
|
key: 'setup' | 'teardown',
|
|
unsupportedFields: string[]
|
|
): string {
|
|
const baseCommand = normalizeSetupScriptImportCommand(baseValue)
|
|
if (localValue === undefined) {
|
|
return baseCommand
|
|
}
|
|
if (typeof localValue === 'string' || Array.isArray(localValue)) {
|
|
return normalizeSetupScriptImportCommand(localValue)
|
|
}
|
|
|
|
const localRecord = asRecord(localValue)
|
|
if (!localRecord) {
|
|
pushSetupScriptImportUnsupportedField(unsupportedFields, `config.local.${key}`)
|
|
return baseCommand
|
|
}
|
|
|
|
for (const field in localRecord) {
|
|
if (!Object.prototype.hasOwnProperty.call(localRecord, field)) {
|
|
continue
|
|
}
|
|
if (field !== 'before' && field !== 'after') {
|
|
pushSetupScriptImportUnsupportedField(unsupportedFields, `config.local.${key}.${field}`)
|
|
if (unsupportedFields.length >= SETUP_SCRIPT_IMPORT_MAX_UNSUPPORTED_FIELDS) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
const beforeCommand = normalizeSetupScriptImportCommand(localRecord.before)
|
|
const afterCommand = normalizeSetupScriptImportCommand(localRecord.after)
|
|
return joinSetupScriptImportCommands([beforeCommand, baseCommand, afterCommand].filter(Boolean))
|
|
}
|
|
|
|
function buildCmuxSetupCandidate(
|
|
configPath: string,
|
|
config: Record<string, unknown>
|
|
): SetupScriptImportCandidate | null {
|
|
const commands = Array.isArray(config.commands) ? config.commands : []
|
|
if (commands.length > SETUP_SCRIPT_IMPORT_MAX_CMUX_COMMANDS) {
|
|
return null
|
|
}
|
|
for (let index = 0; index < commands.length; index++) {
|
|
const command = asRecord(commands[index])
|
|
if (!command || !isCmuxSetupCommand(command)) {
|
|
continue
|
|
}
|
|
|
|
const setup = normalizeSetupScriptImportCommand(command.command)
|
|
if (!setup) {
|
|
continue
|
|
}
|
|
|
|
return {
|
|
provider: 'cmux',
|
|
label: 'cmux',
|
|
files: [configPath],
|
|
setup,
|
|
unsupportedFields: collectUnsupportedCmuxCommandFields(command, index)
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
function isCmuxSetupCommand(command: Record<string, unknown>): boolean {
|
|
if (
|
|
typeof command.command !== 'string' ||
|
|
!isSetupScriptImportFieldWithinLimit(command.command) ||
|
|
!command.command.trim()
|
|
) {
|
|
return false
|
|
}
|
|
|
|
const name = normalizeMatchText(command.name)
|
|
const title = normalizeMatchText(command.title)
|
|
const labels = [name, title].filter(Boolean)
|
|
if (
|
|
labels.some((label) =>
|
|
['setup', 'project setup', 'workspace setup', 'repository setup'].includes(label)
|
|
)
|
|
) {
|
|
return true
|
|
}
|
|
|
|
const keywords = getStringArray(command.keywords).map(normalizeMatchText)
|
|
const hasSetupKeyword = keywords.some((keyword) =>
|
|
['setup', 'init', 'initialize', 'install'].includes(keyword)
|
|
)
|
|
if (!hasSetupKeyword) {
|
|
return false
|
|
}
|
|
|
|
const commandText = normalizeMatchText(command.command)
|
|
return labels.some((label) => label.includes('setup')) || /\bsetup\b/.test(commandText)
|
|
}
|
|
|
|
function normalizeMatchText(value: unknown): string {
|
|
return typeof value === 'string' && isSetupScriptImportFieldWithinLimit(value)
|
|
? value.trim().toLowerCase().replace(/\s+/g, ' ')
|
|
: ''
|
|
}
|
|
|
|
function getStringArray(value: unknown): string[] {
|
|
return Array.isArray(value) && value.length <= SETUP_SCRIPT_IMPORT_MAX_KEYWORDS
|
|
? value.filter((item): item is string => typeof item === 'string')
|
|
: []
|
|
}
|
|
|
|
function collectUnsupportedCmuxCommandFields(
|
|
command: Record<string, unknown>,
|
|
commandIndex: number
|
|
): string[] {
|
|
const supportedFields = new Set(['name', 'title', 'description', 'keywords', 'command'])
|
|
const unsupportedFields: string[] = []
|
|
for (const field in command) {
|
|
if (!Object.prototype.hasOwnProperty.call(command, field)) {
|
|
continue
|
|
}
|
|
if (!supportedFields.has(field)) {
|
|
pushSetupScriptImportUnsupportedField(unsupportedFields, `commands.${commandIndex}.${field}`)
|
|
if (unsupportedFields.length >= SETUP_SCRIPT_IMPORT_MAX_UNSUPPORTED_FIELDS) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return unsupportedFields
|
|
}
|
|
|
|
function collectUnsupportedFields(
|
|
source: Record<string, unknown>,
|
|
fieldNames: readonly string[]
|
|
): string[] {
|
|
return fieldNames.filter((field) => source[field] !== undefined)
|
|
}
|
|
|
|
function collectUnsupportedScriptObjectFields(
|
|
value: unknown,
|
|
prefix: string,
|
|
unsupportedFields: string[]
|
|
): void {
|
|
const record = asRecord(value)
|
|
if (!record) {
|
|
return
|
|
}
|
|
for (const field of ['before', 'after'] as const) {
|
|
if (record[field] !== undefined) {
|
|
pushSetupScriptImportUnsupportedField(unsupportedFields, `${prefix}.${field}`)
|
|
}
|
|
}
|
|
}
|