diff --git a/.github/scripts/check-search-locales.mjs b/.github/scripts/check-search-locales.mjs new file mode 100644 index 0000000..9f93f86 --- /dev/null +++ b/.github/scripts/check-search-locales.mjs @@ -0,0 +1,209 @@ +#!/usr/bin/env node +/** + * The search gate for objectos#296: the BUILT `/api/search` route answers in + * every locale `apps/docs/lib/i18n.ts` declares. + * + * `createFromSource` builds one Orama index per locale and picks each one's + * tokenizer from the locale code. Orama has no tokenizer for `zh-Hans`, + * `zh-Hant`, `ja` or `ko`, so those four indexes threw `LANGUAGE_NOT_SUPPORTED` + * and the route answered 500. Type-check, build and every other gate passed: + * the route is dynamic, so the build output records nothing about it, and the + * search dialog shows a 500 as an empty list. Only a request finds it. + * + * So this gate makes the requests. It loads the route handler out of + * `apps/docs/.next/` and calls its `GET` in-process, in each locale: + * + * - `threw`, `status`, `not-array`: the handler must resolve to a 200 with + * a JSON array. A handler that throws is what Next serves as a 500. + * - `no-results`: `permissions`, the query #296's audit used, must find + * something. + * - `own-title-missed`: every page that has a source file in the locale + * (`foo.ja.mdx`; for English, `foo.mdx`) must be found by its own title. + * That is what proves the locale's script is tokenized at all. English + * fallback pages make `permissions` match in every locale, and Orama's + * English tokenizer drops every CJK character, so a Chinese title would + * find nothing. + * - `negative-control-passed`: a query no page contains must find nothing. + * It runs against the same handler in the same run. If it finds + * something, `no-results` cannot fire, so the run fails. + * + * The locale list and the pages come from `i18n.ts` and `content/docs/`, read + * as text, and not from app code: the gate must be able to go red when app + * code is wrong. Run it after `pnpm turbo run build`, because a missing build + * fails it. `--self-test` runs every rule against fake handlers and needs no + * build. + */ +import { existsSync, readFileSync, readdirSync } from 'node:fs'; +import { createRequire } from 'node:module'; +import { dirname, join, relative, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../..'); +const ROUTE = 'apps/docs/.next/server/app/api/search/route.js'; +const QUERY = 'permissions'; +const NONCE = 'qzxvjwkq'; // in no page; prefix matching cannot reach a real word from it + +const RULES = ['threw', 'status', 'not-array', 'no-results', 'own-title-missed', 'negative-control-passed']; + +/** `languages` and `defaultLanguage` out of `i18n.ts`. Throws rather than guessing. */ +function readI18n(text) { + const list = /languages:\s*\[([^\]]+)\]/.exec(text)?.[1]; + const languages = list?.split(',').map((s) => s.trim().replace(/['"]/g, '')).filter(Boolean) ?? []; + const defaultLanguage = /defaultLanguage:\s*['"]([^'"]+)['"]/.exec(text)?.[1]; + if (!languages.length || !languages.includes(defaultLanguage)) { + throw new Error('could not read languages[] and defaultLanguage out of apps/docs/lib/i18n.ts'); + } + return { languages, defaultLanguage }; +} + +/** locale → the pages with a source file in that locale, as `{ file, title, url }`. */ +function readPages(root, { languages, defaultLanguage }) { + const docs = join(root, 'content/docs'); + const walk = (dir) => + readdirSync(dir, { withFileTypes: true }).flatMap((e) => + e.isDirectory() ? walk(join(dir, e.name)) : e.name.endsWith('.mdx') ? [join(dir, e.name)] : [], + ); + const pages = new Map(languages.map((l) => [l, []])); + for (const path of walk(docs).sort()) { + const file = relative(docs, path).split('\\').join('/'); + const locale = languages.find((l) => l !== defaultLanguage && file.endsWith(`.${l}.mdx`)) ?? defaultLanguage; + const segments = file.slice(0, -(locale === defaultLanguage ? '.mdx' : `.${locale}.mdx`).length).split('/'); + if (segments.at(-1) === 'index') segments.pop(); + const head = readFileSync(path, 'utf8').split(/\r?\n---/)[0]; + const title = /^title:\s*(.+)$/m.exec(head)?.[1].trim().replace(/^(['"])(.*)\1$/, '$2'); + const prefix = locale === defaultLanguage ? '' : `/${locale}`; + if (title) pages.get(locale).push({ file, title, url: [`${prefix}/docs`, ...segments].join('/') }); + } + return pages; +} + +/** One request. A rejection is recorded, because Next turns it into a 500. */ +async function ask(GET, locale, query) { + const url = `http://localhost/api/search?locale=${encodeURIComponent(locale)}&query=${encodeURIComponent(query)}`; + try { + const res = await GET(new Request(url)); + return { status: res.status, body: await res.json().catch(() => undefined) }; + } catch (err) { + return { threw: err?.code ?? String(err?.message ?? err).split('\n')[0] }; + } +} + +/** The rule a response breaks before its hits can be judged, or undefined. */ +function shape(r) { + if (r.threw) return ['threw', `the handler threw ${r.threw}, which Next serves as a 500`]; + if (r.status !== 200) return ['status', `HTTP ${r.status}`]; + if (!Array.isArray(r.body)) return ['not-array', 'the body is not a JSON array']; +} + +async function evaluate(GET, languages, pages) { + const findings = []; + const lines = []; + const add = (rule, locale, detail) => findings.push({ rule, locale, detail }); + for (const locale of languages) { + const probe = await ask(GET, locale, QUERY); + const bad = shape(probe); + if (bad) { + add(bad[0], locale, `?query=${QUERY}: ${bad[1]}`); + continue; + } + if (probe.body.length === 0) add('no-results', locale, `?query=${QUERY} found nothing`); + const own = pages.get(locale) ?? []; + let found = 0; + for (const page of own) { + const r = await ask(GET, locale, page.title); + const broke = shape(r); + if (broke) add(broke[0], locale, `?query=${JSON.stringify(page.title)}: ${broke[1]}`); + else if (r.body.some((hit) => hit.type === 'page' && hit.url === page.url)) found += 1; + else add('own-title-missed', locale, `${page.file}: its title ${JSON.stringify(page.title)} does not find ${page.url} (${r.body.length} hits)`); + } + const control = await ask(GET, locale, NONCE); + if (!shape(control) && control.body.length > 0) { + add('negative-control-passed', locale, `?query=${NONCE} matches no page yet found ${control.body.length} hits, so no-results cannot fire`); + } + lines.push(` ${locale}: 200, ${probe.body.length} hits for "${QUERY}", ${found}/${own.length} own pages found by title`); + } + return { findings, lines }; +} + +async function gate() { + const route = join(ROOT, ROUTE); + if (!existsSync(route)) { + console.error(`✗ search locales: ${ROUTE} does not exist. Run pnpm turbo run build first.`); + return 1; + } + const { languages, defaultLanguage } = readI18n(readFileSync(join(ROOT, 'apps/docs/lib/i18n.ts'), 'utf8')); + const pages = readPages(ROOT, { languages, defaultLanguage }); + const GET = (await createRequire(import.meta.url)(route))?.routeModule?.userland?.GET; + if (typeof GET !== 'function') { + console.error(`✗ search locales: ${ROUTE} exposes no routeModule.userland.GET, so nothing was measured.`); + return 1; + } + const { findings, lines } = await evaluate(GET, languages, pages); + for (const f of findings) console.error(` (${f.rule}) ${f.locale} ${f.detail}`); + if (findings.length) { + console.error(`\n✗ search locales: ${findings.length} finding(s). The rules are in this script's header.`); + return 1; + } + console.log(lines.join('\n')); + console.log(`✓ search locales: all ${languages.length} locales answer 200, find "${QUERY}", find every own page by its title, and find nothing for a nonce`); + return 0; +} + +/* Self-test: one clean fake handler, then one fake per rule that must break exactly that rule. */ +const LANGS = ['en', 'ja']; +const PAGES = new Map([ + ['en', [{ file: 'a.mdx', title: 'Alpha', url: '/docs/a' }]], + ['ja', [{ file: 'a.ja.mdx', title: '権限', url: '/ja/docs/a' }]], +]); +const json = (body, status = 200) => Response.json(body, { status }); +/** A handler that finds a page by its exact title, and finds `permissions` everywhere. */ +const good = (override = () => undefined) => async (req) => { + const p = new URL(req.url).searchParams; + const [locale, q] = [p.get('locale'), p.get('query')]; + const changed = await override(locale, q); + if (changed !== undefined) return changed; + if (q === QUERY) return json([{ type: 'page', url: '/docs/anything' }]); + const page = PAGES.get(locale)?.find((x) => x.title === q); + return json(page ? [{ type: 'page', url: page.url }] : []); +}; +const CASES = [ + ['clean', good(), []], + ['ja throws, as an unsupported language does', good((l) => { if (l === 'ja') throw Object.assign(new Error('x'), { code: 'LANGUAGE_NOT_SUPPORTED' }); }), ['threw']], + ['ja answers 500', good((l) => (l === 'ja' ? json({}, 500) : undefined)), ['status']], + ['ja answers an object', good((l) => (l === 'ja' ? json({ hits: [] }) : undefined)), ['not-array']], + ['nothing finds permissions', good((l, q) => (q === QUERY ? json([]) : undefined)), ['no-results', 'no-results']], + ['ja titles find nothing, as an English tokenizer would', good((l, q) => (l === 'ja' && q !== QUERY ? json([]) : undefined)), ['own-title-missed']], + ['a hit under a heading is not the page', good((l, q) => (l === 'en' && q === 'Alpha' ? json([{ type: 'heading', url: '/docs/a' }]) : undefined)), ['own-title-missed']], + ['every query matches', good(() => json([{ type: 'page', url: '/docs/a' }, { type: 'page', url: '/ja/docs/a' }])), ['negative-control-passed', 'negative-control-passed']], +]; + +async function selfTest() { + let failed = 0; + const fired = new Set(); + for (const [name, GET, want] of CASES) { + const got = (await evaluate(GET, LANGS, PAGES)).findings.map((f) => f.rule).sort(); + got.forEach((r) => fired.add(r)); + const ok = JSON.stringify(got) === JSON.stringify([...want].sort()); + if (!ok) failed += 1; + console.log(`${ok ? '✓' : '✗'} ${name}: ${got.length ? got.join(', ') : 'no findings'}`); + } + const silent = RULES.filter((r) => !fired.has(r)); + if (silent.length) { + failed += 1; + console.log(`✗ rules no fixture makes fire: ${silent.join(', ')}`); + } + const i18n = readI18n("defineI18n({ defaultLanguage: 'en', languages: ['en', 'zh-Hans'] })"); + const i18nOk = i18n.defaultLanguage === 'en' && i18n.languages.join() === 'en,zh-Hans'; + let unreadable = false; + try { + readI18n('defineI18n({})'); + } catch { + unreadable = true; + } + if (!i18nOk || !unreadable) failed += 1; + console.log(`${i18nOk ? '✓' : '✗'} i18n.ts is read; ${unreadable ? '✓' : '✗'} an unreadable one is rejected`); + console.log(failed ? `\n✗ search locales self-test: ${failed} failure(s)` : `\n✓ search locales self-test: ${CASES.length} cases, all ${RULES.length} rules can fire`); + return failed ? 1 : 0; +} + +process.exitCode = process.argv.includes('--self-test') ? await selfTest() : await gate(); diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e00f0c1..1858d86 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -160,6 +160,20 @@ jobs: shell: bash run: node .github/scripts/check-positioning.mjs | tee -a "$GITHUB_STEP_SUMMARY" + # #296: `/api/search` answered 500 in `zh-Hans`, `zh-Hant`, `ja` and `ko` + # while every step above was green. The route is dynamic, so the build + # output records nothing about it, and only a request finds the defect. + # This step loads the BUILT handler out of `apps/docs/.next/` and asks it + # in every locale `lib/i18n.ts` declares: 200, hits for `permissions`, + # every page that locale has a source file for found by its own title, + # and nothing for a nonce. It is on the same footing as the two steps + # above: after `build`, not a turbo task, its `--self-test` under + # `pnpm turbo run test` below, and `shell: bash` for the same pipefail + # reason. + - name: Search answers every locale + shell: bash + run: node .github/scripts/check-search-locales.mjs | tee -a "$GITHUB_STEP_SUMMARY" + - run: pnpm turbo run test # Defect 2 of #269: the deploy used to run its own `pnpm install` and its diff --git a/apps/docs/app/api/search/route.ts b/apps/docs/app/api/search/route.ts index b02d7cd..fc6bc92 100644 --- a/apps/docs/app/api/search/route.ts +++ b/apps/docs/app/api/search/route.ts @@ -1,6 +1,69 @@ import { source } from '@/lib/source'; +import type { i18n } from '@/lib/i18n'; import { createFromSource } from 'fumadocs-core/search/server'; -export const { GET } = createFromSource(source, { - language: 'english', -}); +type Locale = (typeof i18n.languages)[number]; + +/** + * A word tokenizer for Chinese, Japanese and Korean, built on `Intl.Segmenter`. + * + * Orama, the index behind `createFromSource`, ships tokenizers for about thirty + * languages, and Chinese, Japanese and Korean are not among them. A locale it + * does not know fails index creation with `LANGUAGE_NOT_SUPPORTED`, which made + * `/api/search` answer 500 for `zh-Hans`, `zh-Hant`, `ja` and `ko` (#296). Its + * English tokenizer is no fallback for these scripts. It splits on every + * non-Latin character, so a Chinese query tokenizes to nothing and finds + * nothing. + * + * `Intl.Segmenter` does dictionary-based word segmentation for all four. It is + * built into V8, so it costs no dependency, and it is present in both places + * this route runs: Node (`next start`) and workerd (the Cloudflare Worker). + * It is created on first use, not at module load, so Worker startup does not + * pay for it. fumadocs builds every locale's index on the first search in any + * locale, so that first search does. + * + * Tokens are lowercased and de-duplicated, as Orama's own tokenizer does. + */ +function segmented(locale: Locale) { + let segmenter: Intl.Segmenter | undefined; + return { + tokenizer: { + language: locale, + normalizationCache: new Map(), + tokenize(raw: string): string[] { + segmenter ??= new Intl.Segmenter(locale, { granularity: 'word' }); + const tokens = new Set(); + for (const { segment, isWordLike } of segmenter.segment(raw.toLowerCase())) { + if (isWordLike) tokens.add(segment); + } + return [...tokens]; + }, + }, + // A CJK query segments into several short words. Orama's default + // threshold (1) returns any page that matches one of them, so 0 requires + // every word to match. fumadocs already searches with tolerance 0, and it + // is spelled out here so it stays that way: an edit distance of 1 on a + // two-character word matches every word that shares one character with it. + search: { threshold: 0, tolerance: 0 }, + }; +} + +/** + * One entry per locale in `lib/i18n.ts`. The `satisfies` makes a missing entry + * a type error, because a locale without one falls back to a language Orama + * may not support, and that is how the four 500s above happened. + * `.github/scripts/check-search-locales.mjs` asks the built route for every + * locale after each build. + */ +const localeMap = { + en: 'english', + de: 'german', + es: 'spanish', + fr: 'french', + 'zh-Hans': segmented('zh-Hans'), + 'zh-Hant': segmented('zh-Hant'), + ja: segmented('ja'), + ko: segmented('ko'), +} as const satisfies Record; + +export const { GET } = createFromSource(source, { localeMap }); diff --git a/content/docs/quickstart.mdx b/content/docs/quickstart.mdx index d88784a..8ffdf45 100644 --- a/content/docs/quickstart.mdx +++ b/content/docs/quickstart.mdx @@ -17,7 +17,7 @@ doing. | You are … | Start here | |---|---| -| Trying the open runtime for the first time, or running it in production | [Path A — `os start`](#path-a--os-start-operator-first-time-evaluator) | +| Trying the open runtime for the first time, or running it in production | [Path A — `os start`](#path-a--os-start-operator--first-time-evaluator) | | Building or customizing an app in code | [Path B — `os init`](#path-b--os-init-developer) | Both produce a running server with the UI — account sign-in, registration diff --git a/content/docs/resources/license.de.mdx b/content/docs/resources/license.de.mdx deleted file mode 100644 index e022c14..0000000 --- a/content/docs/resources/license.de.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Lizenz -description: ObjectOS-Lizenzierung — Apache-2.0, kommerzielle Optionen und FAQ. -translation: - source_sha: 8d07bca969951145c9a815947a36fda483adc751b3385972b26542ab2e7a8863 - guide_rev: 1 - mode: auto ---- - -## ObjectOS-Runtime — Apache-2.0 - -Die ObjectOS-Runtime und alle Open-Source-Pakete `@objectstack/*` sind -unter der [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) lizenziert. - -In einfachen Worten: - -| Sie dürfen | Sie müssen | -|---|---| -| Es in kommerziellen Produkten verwenden | Die Dateien LICENSE und NOTICE bei der Weiterverteilung beilegen | -| Es ändern, ohne die Änderungen zu teilen | Geänderte Dateien als geändert kennzeichnen | -| Es in proprietäre Software einbetten | ObjectStack-Marken nicht ohne Erlaubnis verwenden | -| Es zu jedem Zweck und überall ausführen | — | -| Es als Teil eines größeren Werks unterlizenzieren | — | - -Es gibt **kein Copyleft**. Änderungen, die Sie für den internen Gebrauch -vornehmen oder die Sie in einem Closed-Source-Produkt ausliefern, müssen -**nicht** zurückgegeben werden. Die Apache-2.0-Lizenz enthält außerdem -eine **ausdrückliche Patentlizenz** von den Mitwirkenden — wichtig für -die rechtliche Prüfung in Unternehmen. - -Volltext: [LICENSE](https://github.com/objectstack-ai/objectstack/blob/main/LICENSE) - -## Was unter Apache-2.0 enthalten ist - -| | Lizenz | -|---|---| -| ObjectOS-Runtime-Image | Apache-2.0 | -| Alle npm-Pakete `@objectstack/*` (Runtime, Plugins, Services, Treiber, Adapter, CLI, Client-SDKs) | Apache-2.0 | -| Templates-Repository (`objectstack-ai/templates`) | Apache-2.0 | -| Console- und Account-UIs | Apache-2.0 | -| Dokumentation | CC-BY-4.0 | - -## Wann eine kommerzielle Vereinbarung sinnvoll sein kann - -Apache-2.0 deckt die meisten Anwendungsfälle ab. Eine kommerzielle -Vereinbarung kann dennoch sinnvoll sein, wenn: - -| Szenario | Was wir anbieten | -|---|---| -| Sie **Support mit SLAs** benötigen | Kommerzieller Support | -| Sie möchten, dass wir es **für Sie hosten** | Managed Cloud (ObjectStack Cloud) | -| Sie **OEM-Rechte** wünschen (ObjectStack-Marken verwenden, es als Ihr eigenes Produkt kennzeichnen) | OEM-Vereinbarung | -| Sie eine **Gewährleistung / Freistellung** wünschen | Kommerzielle Vereinbarung (Apache-2.0 schließt Gewährleistung aus) | -| Sie **regulatorische Nachweise** benötigen (SOC-2-Bericht, ISO-Zertifikat des Runtime-Images) | Enterprise-Tier | - -Kontaktieren Sie **sales@objectstack.ai**, um darüber zu sprechen. - -## Preise für die Open-Source-Runtime - -**Kostenlos.** Für immer. Keine Plätze, keine Nutzungsstufe, kein Lizenzserver, kein Schlüssel. - -Führen Sie es aus auf: -- Ihrem Laptop -- Ihren Servern -- Den Servern Ihrer Kunden -- Einem Raspberry Pi -- Einem Kubernetes-Cluster mit 1000 Pods - -Die Lizenz ist in jedem Fall dieselbe. - -## Komponenten von Drittanbietern - -ObjectOS hängt von mehreren vorgelagerten Open-Source-Projekten ab (Node.js, -Hono, Zod, Better Auth, AI SDK, …). Jedes wird mit seiner eigenen Lizenz -ausgeliefert — allesamt entweder Apache-2.0, MIT oder permissive Lizenzen -im BSD-Stil, die mit kommerzieller Nutzung kompatibel sind. Die vollständige -Inventarliste finden Sie in der SBOM, die mit jedem Release veröffentlicht wird. - -## FAQ - -**F: Kann ich ObjectOS in einer Closed-Source-SaaS verwenden, die ich an meine Kunden verkaufe?** -A: Ja. Apache-2.0 hat kein Copyleft. Sie müssen Ihren Code nicht teilen. - -**F: Kann ich ObjectOS ändern und meine Änderungen nicht teilen?** -A: Ja. Apache-2.0 verlangt nicht, dass Sie Änderungen teilen. - -**F: Kann ich Console als Teil meines Produkts umbenennen (Rebranding)?** -A: Die UI selbst, ja. Die Verwendung des Namens oder Logos „ObjectStack", -um Ihr Produkt zu bewerben, erfordert eine OEM-Vereinbarung — kontaktieren Sie den Vertrieb. - -**F: Schulde ich Ihnen etwas, wenn mein Produkt Geld einbringt?** -A: Nein. Es gibt keine Lizenzgebühren oder Umsatzbeteiligung. - -**F: Sendet ObjectOS Nutzungsdaten nach Hause („phone home")?** -A: Nein. Es gibt keine Telemetrie, keine Lizenzprüfung, keinen Update-Ping. -Siehe [Security & Compliance](/docs/reference/security#data-residency). - -**F: Was, wenn ich eine vertragliche Gewährleistung möchte?** -A: Apache-2.0 schließt Gewährleistung aus. Erwerben Sie eine kommerzielle -Vereinbarung, und wir stellen eine bereit. - -**F: Wird die Open-Source-Version immer kostenlos sein?** -A: Ja. Apache-2.0-Lizenzen sind unwiderruflich. diff --git a/content/docs/resources/license.es.mdx b/content/docs/resources/license.es.mdx deleted file mode 100644 index 81d1372..0000000 --- a/content/docs/resources/license.es.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Licencia -description: Licencias de ObjectOS — Apache-2.0, opciones comerciales y preguntas frecuentes. -translation: - source_sha: 8d07bca969951145c9a815947a36fda483adc751b3385972b26542ab2e7a8863 - guide_rev: 1 - mode: auto ---- - -## Runtime de ObjectOS — Apache-2.0 - -El runtime de ObjectOS y todos los paquetes de código abierto `@objectstack/*` están -licenciados bajo la [Licencia Apache, Versión 2.0](https://www.apache.org/licenses/LICENSE-2.0). - -En lenguaje sencillo: - -| Puedes | Debes | -|---|---| -| Usarlo en productos comerciales | Incluir los archivos LICENSE y NOTICE cuando lo redistribuyas | -| Modificarlo sin compartir los cambios | Marcar los archivos modificados como modificados | -| Integrarlo en software propietario | No usar las marcas registradas de ObjectStack sin permiso | -| Ejecutarlo para cualquier propósito, en cualquier lugar | — | -| Sublicenciarlo como parte de una obra mayor | — | - -No hay **copyleft**. Las modificaciones que hagas para uso interno, o -que distribuyas en un producto de código cerrado, **no** tienen que ser -aportadas de vuelta. La licencia Apache-2.0 también incluye una **concesión -expresa de patentes** por parte de los contribuyentes — algo importante para la -revisión legal empresarial. - -Texto completo: [LICENSE](https://github.com/objectstack-ai/objectstack/blob/main/LICENSE) - -## Qué está incluido bajo Apache-2.0 - -| | Licencia | -|---|---| -| Imagen del runtime de ObjectOS | Apache-2.0 | -| Todos los paquetes npm `@objectstack/*` (runtime, plugins, servicios, drivers, adaptadores, CLI, SDKs de cliente) | Apache-2.0 | -| Repositorio de plantillas (`objectstack-ai/templates`) | Apache-2.0 | -| Interfaces de Console y Account | Apache-2.0 | -| Documentación | CC-BY-4.0 | - -## Cuándo podrías querer un acuerdo comercial - -Apache-2.0 cubre la mayoría de los casos de uso. Aun así podrías querer un acuerdo -comercial cuando: - -| Escenario | Lo que ofrecemos | -|---|---| -| Necesitas **soporte con SLAs** | Soporte comercial | -| Quieres que lo **alojemos por ti** | Nube gestionada (ObjectStack Cloud) | -| Quieres **derechos OEM** (usar las marcas de ObjectStack, presentarlo como propio) | Acuerdo OEM | -| Quieres una **garantía / indemnización** | Acuerdo comercial (Apache-2.0 renuncia a la garantía) | -| Necesitas **certificaciones regulatorias** (informe SOC 2, certificado ISO de la imagen del runtime) | Nivel Enterprise | - -Contacta con **sales@objectstack.ai** para hablarlo. - -## Precio del runtime de código abierto - -**Gratis.** Para siempre. Sin asientos, sin niveles de uso, sin servidor de licencias, sin clave. - -Ejecútalo en: -- Tu portátil -- Tus servidores -- Los servidores de tus clientes -- Una Raspberry Pi -- Un clúster de Kubernetes de 1000 pods - -La licencia es la misma en todos los casos. - -## Componentes de terceros - -ObjectOS depende de varios proyectos de código abierto upstream (Node.js, -Hono, Zod, Better Auth, AI SDK, …). Cada uno se distribuye con su propia licencia — -todas las cuales son Apache-2.0, MIT o licencias permisivas de estilo BSD -compatibles con el uso comercial. Consulta el SBOM publicado con -cada versión para ver el inventario completo. - -## Preguntas frecuentes - -**P: ¿Puedo usar ObjectOS en un SaaS de código cerrado que vendo a mis clientes?** -R: Sí. Apache-2.0 no tiene copyleft. No necesitas compartir tu código. - -**P: ¿Puedo modificar ObjectOS y no compartir mis cambios?** -R: Sí. Apache-2.0 no te obliga a compartir las modificaciones. - -**P: ¿Puedo cambiar la marca de Console como parte de mi producto?** -R: La interfaz en sí, sí. Usar el nombre o el logo de "ObjectStack" para promocionar -tu producto requiere un acuerdo OEM — contacta con ventas. - -**P: ¿Te debo algo si mi producto genera dinero?** -R: No. No hay regalías ni reparto de ingresos. - -**P: ¿ObjectOS envía datos de uso a casa (phone home)?** -R: No. No hay telemetría, ni comprobación de licencia, ni ping de actualización. -Consulta [Security & Compliance](/docs/reference/security#data-residency). - -**P: ¿Y si quiero una garantía contractual?** -R: Apache-2.0 renuncia a la garantía. Compra un acuerdo comercial y te -proporcionamos una. - -**P: ¿La versión de código abierto será siempre gratuita?** -R: Sí. Las concesiones de Apache-2.0 son irrevocables. diff --git a/content/docs/resources/license.fr.mdx b/content/docs/resources/license.fr.mdx deleted file mode 100644 index 7999ffd..0000000 --- a/content/docs/resources/license.fr.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Licence -description: Licence ObjectOS — Apache-2.0, options commerciales et FAQ. -translation: - source_sha: 8d07bca969951145c9a815947a36fda483adc751b3385972b26542ab2e7a8863 - guide_rev: 1 - mode: auto ---- - -## Runtime ObjectOS — Apache-2.0 - -Le runtime ObjectOS et tous les paquets open source `@objectstack/*` sont -distribués sous la [licence Apache, version 2.0](https://www.apache.org/licenses/LICENSE-2.0). - -En termes simples : - -| Vous pouvez | Vous devez | -|---|---| -| L'utiliser dans des produits commerciaux | Inclure les fichiers LICENSE et NOTICE lorsque vous le redistribuez | -| Le modifier sans partager vos modifications | Indiquer les fichiers modifiés comme tels | -| L'intégrer dans un logiciel propriétaire | Ne pas utiliser les marques ObjectStack sans autorisation | -| L'exécuter à n'importe quelle fin, n'importe où | — | -| Le sous-licencier dans le cadre d'une œuvre plus large | — | - -Il n'y a **aucun copyleft**. Les modifications que vous apportez pour un -usage interne, ou que vous livrez dans un produit à code source fermé, -n'ont **pas** à être reversées. La licence Apache-2.0 inclut également une -**concession expresse de brevet** de la part des contributeurs — un point -important pour les revues juridiques en entreprise. - -Texte intégral : [LICENSE](https://github.com/objectstack-ai/objectstack/blob/main/LICENSE) - -## Ce qui est couvert par Apache-2.0 - -| | Licence | -|---|---| -| Image du runtime ObjectOS | Apache-2.0 | -| Tous les paquets npm `@objectstack/*` (runtime, plugins, services, drivers, adaptateurs, CLI, SDK clients) | Apache-2.0 | -| Dépôt de templates (`objectstack-ai/templates`) | Apache-2.0 | -| Interfaces Console et Account | Apache-2.0 | -| Documentation | CC-BY-4.0 | - -## Quand un accord commercial peut être souhaitable - -Apache-2.0 couvre la plupart des cas d'usage. Vous pouvez néanmoins -souhaiter un accord commercial lorsque : - -| Scénario | Ce que nous proposons | -|---|---| -| Vous avez besoin d'un **support avec SLA** | Support commercial | -| Vous voulez que nous l'**hébergions pour vous** | Cloud managé (ObjectStack Cloud) | -| Vous voulez des **droits OEM** (utiliser les marques ObjectStack, le commercialiser sous votre propre nom) | Accord OEM | -| Vous voulez une **garantie / indemnisation** | Accord commercial (Apache-2.0 exclut toute garantie) | -| Vous avez besoin d'**attestations réglementaires** (rapport SOC 2, certificat ISO de l'image du runtime) | Offre Enterprise | - -Contactez **sales@objectstack.ai** pour en discuter. - -## Tarification du runtime open source - -**Gratuit.** Pour toujours. Pas de sièges, pas de palier d'utilisation, -pas de serveur de licences, pas de clé. - -Exécutez-le sur : -- Votre ordinateur portable -- Vos serveurs -- Les serveurs de vos clients -- Un Raspberry Pi -- Un cluster Kubernetes de 1000 pods - -La licence est la même dans tous les cas. - -## Composants tiers - -ObjectOS dépend de plusieurs projets open source en amont (Node.js, -Hono, Zod, Better Auth, AI SDK, …). Chacun est fourni avec sa propre -licence — toutes étant des licences permissives de type Apache-2.0, MIT -ou BSD, compatibles avec un usage commercial. Consultez le SBOM publié -avec chaque version pour l'inventaire complet. - -## FAQ - -**Q : Puis-je utiliser ObjectOS dans un SaaS à code source fermé que je vends à mes clients ?** -R : Oui. Apache-2.0 n'a aucun copyleft. Vous n'avez pas besoin de partager votre code. - -**Q : Puis-je modifier ObjectOS sans partager mes modifications ?** -R : Oui. Apache-2.0 ne vous oblige pas à partager vos modifications. - -**Q : Puis-je rebrander Console dans le cadre de mon produit ?** -R : L'interface elle-même, oui. Utiliser le nom ou le logo « ObjectStack » -pour promouvoir votre produit nécessite un accord OEM — contactez le service commercial. - -**Q : Vous dois-je quelque chose si mon produit génère des revenus ?** -R : Non. Il n'y a aucune redevance ni partage de revenus. - -**Q : ObjectOS envoie-t-il des données d'utilisation à distance ?** -R : Non. Il n'y a aucune télémétrie, aucune vérification de licence, aucun ping de mise à jour. -Voir [Sécurité et conformité](/docs/reference/security#data-residency). - -**Q : Et si je veux une garantie contractuelle ?** -R : Apache-2.0 exclut toute garantie. Souscrivez un accord commercial et nous vous en fournissons une. - -**Q : La version open source restera-t-elle toujours gratuite ?** -R : Oui. Les concessions Apache-2.0 sont irrévocables. diff --git a/content/docs/resources/license.ja.mdx b/content/docs/resources/license.ja.mdx deleted file mode 100644 index 61dd1bd..0000000 --- a/content/docs/resources/license.ja.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: ライセンス -description: ObjectOS のライセンス — Apache-2.0、商用オプション、FAQ。 -translation: - source_sha: 8d07bca969951145c9a815947a36fda483adc751b3385972b26542ab2e7a8863 - guide_rev: 1 - mode: auto ---- - -## ObjectOS ランタイム — Apache-2.0 - -ObjectOS ランタイムおよびすべての `@objectstack/*` オープンソースパッケージは、 -[Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) の下でライセンスされています。 - -平易に言うと: - -| できること | しなければならないこと | -|---|---| -| 商用製品で利用する | 再配布する際に LICENSE ファイルと NOTICE ファイルを含める | -| 変更内容を共有せずに改変する | 改変したファイルに変更済みである旨を明記する | -| プロプライエタリなソフトウェアに組み込む | 許可なく ObjectStack の商標を使用しない | -| 目的を問わず、どこででも実行する | — | -| より大きな成果物の一部としてサブライセンスする | — | - -**コピーレフトはありません**。社内利用のために加えた変更や、クローズドソース製品に -組み込んで出荷する変更を、貢献として還元する必要は **ありません**。Apache-2.0 -ライセンスには、コントリビューターからの **明示的な特許許諾** も含まれており、 -これはエンタープライズの法務レビューにおいて重要です。 - -全文: [LICENSE](https://github.com/objectstack-ai/objectstack/blob/main/LICENSE) - -## Apache-2.0 に含まれるもの - -| | ライセンス | -|---|---| -| ObjectOS ランタイムイメージ | Apache-2.0 | -| すべての `@objectstack/*` npm パッケージ(ランタイム、プラグイン、サービス、ドライバー、アダプター、CLI、クライアント SDK) | Apache-2.0 | -| テンプレートリポジトリ(`objectstack-ai/templates`) | Apache-2.0 | -| Console と Account の UI | Apache-2.0 | -| ドキュメント | CC-BY-4.0 | - -## 商用契約を検討したくなる場合 - -Apache-2.0 はほとんどのユースケースをカバーします。それでも、以下の場合には -商用契約をご検討いただくとよいでしょう: - -| シナリオ | 当社が提供するもの | -|---|---| -| **SLA 付きのサポート** が必要 | 商用サポート | -| **当社によるホスティング** を希望する | マネージドクラウド(ObjectStack Cloud) | -| **OEM 権利**(ObjectStack の商標を使用し、自社製品としてブランディングする)を希望する | OEM 契約 | -| **保証 / 補償** を希望する | 商用契約(Apache-2.0 は保証を否認しています) | -| **規制上の証明**(SOC 2 レポート、ランタイムイメージの ISO 認証)が必要 | エンタープライズプラン | - -ご相談は **sales@objectstack.ai** までご連絡ください。 - -## オープンソースランタイムの価格 - -**無料。** 永久に。シート課金なし、使用量ティアなし、ライセンスサーバーなし、キーなし。 - -実行できる環境: -- お使いのノートパソコン -- 自社のサーバー -- 顧客のサーバー -- Raspberry Pi -- 1000 ポッドの Kubernetes クラスター - -どの場合でもライセンスは同じです。 - -## サードパーティコンポーネント - -ObjectOS は、いくつかのアップストリームのオープンソースプロジェクト(Node.js、 -Hono、Zod、Better Auth、AI SDK、…)に依存しています。それぞれが独自のライセンスを -伴って提供されており、いずれも Apache-2.0、MIT、または BSD 系の寛容な -ライセンスで、商用利用と互換性があります。完全な一覧については、各リリースとともに -公開される SBOM をご覧ください。 - -## FAQ - -**Q: 顧客に販売するクローズドソースの SaaS で ObjectOS を使えますか?** -A: はい。Apache-2.0 にはコピーレフトがありません。コードを共有する必要はありません。 - -**Q: ObjectOS を改変して、その変更を共有しないことはできますか?** -A: はい。Apache-2.0 は改変内容の共有を求めていません。 - -**Q: 自社製品の一部として Console をリブランドできますか?** -A: UI 自体はできます。自社製品の宣伝のために「ObjectStack」の名称やロゴを -使用する場合は OEM 契約が必要です — sales までご連絡ください。 - -**Q: 製品で利益が出た場合、何か支払う義務はありますか?** -A: いいえ。ロイヤルティや収益分配はありません。 - -**Q: ObjectOS は使用状況データを外部に送信(phone home)しますか?** -A: いいえ。テレメトリも、ライセンスチェックも、アップデートの ping もありません。 -[セキュリティとコンプライアンス](/docs/reference/security#data-residency) をご覧ください。 - -**Q: 契約上の保証が欲しい場合はどうすればよいですか?** -A: Apache-2.0 は保証を否認しています。商用契約をご購入いただければ、当社が保証を提供します。 - -**Q: オープンソース版は常に無料ですか?** -A: はい。Apache-2.0 の許諾は撤回不能です。 diff --git a/content/docs/resources/license.ko.mdx b/content/docs/resources/license.ko.mdx deleted file mode 100644 index 56a1649..0000000 --- a/content/docs/resources/license.ko.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: 라이선스 -description: ObjectOS 라이선스 — Apache-2.0, 상용 옵션 및 FAQ. -translation: - source_sha: 8d07bca969951145c9a815947a36fda483adc751b3385972b26542ab2e7a8863 - guide_rev: 1 - mode: auto ---- - -## ObjectOS 런타임 — Apache-2.0 - -ObjectOS 런타임과 모든 `@objectstack/*` 오픈소스 패키지는 -[Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0)에 따라 라이선스가 부여됩니다. - -쉽게 말하면 다음과 같습니다. - -| 할 수 있는 것 | 해야 하는 것 | -|---|---| -| 상용 제품에 사용 | 재배포 시 LICENSE 및 NOTICE 파일 포함 | -| 변경 사항을 공유하지 않고 수정 | 수정된 파일을 수정됨으로 표시 | -| 독점 소프트웨어에 임베드 | 허가 없이 ObjectStack 상표를 사용하지 않음 | -| 어떤 목적으로든, 어디서든 실행 | — | -| 더 큰 저작물의 일부로 서브라이선스 | — | - -**카피레프트는 없습니다.** 내부용으로 수행한 수정이나 -폐쇄형 소스 제품에 포함하여 출시한 수정 사항은 다시 기여할 -필요가 **없습니다**. Apache-2.0 라이선스에는 기여자로부터의 -**명시적 특허 권리 부여**도 포함되어 있어 엔터프라이즈 법무 검토에 -중요합니다. - -전문: [LICENSE](https://github.com/objectstack-ai/objectstack/blob/main/LICENSE) - -## Apache-2.0에 포함되는 항목 - -| | 라이선스 | -|---|---| -| ObjectOS 런타임 이미지 | Apache-2.0 | -| 모든 `@objectstack/*` npm 패키지 (런타임, 플러그인, 서비스, 드라이버, 어댑터, CLI, 클라이언트 SDK) | Apache-2.0 | -| 템플릿 저장소 (`objectstack-ai/templates`) | Apache-2.0 | -| Console 및 Account UI | Apache-2.0 | -| 문서 | CC-BY-4.0 | - -## 상용 계약이 필요할 수 있는 경우 - -Apache-2.0은 대부분의 사용 사례를 다룹니다. 다음과 같은 경우에는 -상용 계약이 필요할 수 있습니다. - -| 시나리오 | 제공 항목 | -|---|---| -| **SLA가 포함된 지원**이 필요한 경우 | 상용 지원 | -| 우리가 **대신 호스팅**해 주기를 원하는 경우 | 관리형 클라우드 (ObjectStack Cloud) | -| **OEM 권리**(ObjectStack 상표 사용, 자체 제품으로 배지 표시)를 원하는 경우 | OEM 계약 | -| **보증 / 면책**을 원하는 경우 | 상용 계약 (Apache-2.0은 보증을 부인함) | -| **규제 증명**(SOC 2 보고서, 런타임 이미지의 ISO 인증서)이 필요한 경우 | 엔터프라이즈 등급 | - -논의를 원하시면 **sales@objectstack.ai**로 문의하세요. - -## 오픈소스 런타임의 가격 - -**무료입니다.** 영원히. 좌석도, 사용량 등급도, 라이선스 서버도, 키도 없습니다. - -다음에서 실행하세요. -- 노트북 -- 서버 -- 고객의 서버 -- Raspberry Pi -- 파드 1000개 규모의 Kubernetes 클러스터 - -라이선스는 모든 경우에 동일합니다. - -## 서드파티 구성 요소 - -ObjectOS는 여러 업스트림 오픈소스 프로젝트(Node.js, -Hono, Zod, Better Auth, AI SDK, …)에 의존합니다. 각 프로젝트는 -자체 라이선스와 함께 배포되며, 모두 Apache-2.0, MIT 또는 BSD 스타일의 -허용적 라이선스로 상용 사용과 호환됩니다. 전체 목록은 각 릴리스와 함께 -게시되는 SBOM을 참조하세요. - -## FAQ - -**Q: 고객에게 판매하는 폐쇄형 소스 SaaS에서 ObjectOS를 사용할 수 있나요?** -A: 네. Apache-2.0에는 카피레프트가 없습니다. 코드를 공유할 필요가 없습니다. - -**Q: ObjectOS를 수정하고 변경 사항을 공유하지 않아도 되나요?** -A: 네. Apache-2.0은 수정 사항 공유를 요구하지 않습니다. - -**Q: 제 제품의 일부로 Console을 리브랜딩할 수 있나요?** -A: UI 자체는 가능합니다. 제품을 홍보하기 위해 "ObjectStack" 이름이나 -로고를 사용하려면 OEM 계약이 필요합니다 — 영업팀에 문의하세요. - -**Q: 제 제품이 수익을 내면 비용을 지불해야 하나요?** -A: 아니요. 로열티나 수익 분배가 없습니다. - -**Q: ObjectOS가 사용 데이터를 본사로 전송하나요?** -A: 아니요. 텔레메트리, 라이선스 검사, 업데이트 핑이 없습니다. -[Security & Compliance](/docs/reference/security#data-residency)를 참조하세요. - -**Q: 계약상의 보증을 원하면 어떻게 하나요?** -A: Apache-2.0은 보증을 부인합니다. 상용 계약을 구매하면 보증을 -제공해 드립니다. - -**Q: 오픈소스 버전은 항상 무료인가요?** -A: 네. Apache-2.0 권리 부여는 철회할 수 없습니다. diff --git a/content/docs/resources/support.de.mdx b/content/docs/resources/support.de.mdx deleted file mode 100644 index f991f75..0000000 --- a/content/docs/resources/support.de.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Support -description: Wo Sie Hilfe erhalten, wie Sie Fehler melden, welche Reaktionszeiten zu erwarten sind. -translation: - source_sha: f6f76ab1e3037f16decdccd28977c380bb353dc9ad8d086e666f9c117b3981fa - guide_rev: 1 - mode: auto ---- - -## Wohin für welches Anliegen - -| Wenn Sie … | Gehen Sie zu | -|---|---| -| Eine „Wie mache ich …"-Frage haben | [GitHub Discussions](https://github.com/objectstack-ai/objectos/discussions) — Community + Maintainer | -| Einen Fehler gefunden haben | [GitHub Issues](https://github.com/objectstack-ai/objectos/issues) — bitte Version, Reproduktion sowie erwartetes vs. tatsächliches Verhalten angeben | -| Eine Sicherheitslücke gefunden haben | **security@objectstack.ai** — **kein** öffentliches Issue eröffnen | -| Kommerziellen Support / ein SLA benötigen | **sales@objectstack.ai** | -| Mit Nutzern + Maintainern chatten möchten | [Discord](https://discord.gg/objectstack) (von der Community betrieben) | -| Releases verfolgen möchten | [github.com/objectstack-ai/objectos](https://github.com/objectstack-ai/objectos) beobachten → Releases | -| Ein kostenpflichtiges Feature umgesetzt haben möchten | Eine Discussion eröffnen → mit `funding` taggen | - -## Einen guten Fehlerbericht erstellen - -Die 30-Sekunden-Variante: - -```text -ObjectOS version: 10.2.0 (or sha-abc123) -Node version: 22.4.0 -Install method: docker / npm -g / source -Database: postgres 16 / sqlite / turso / mongo -Repro steps: 1. ... 2. ... 3. ... -Expected: ... -Actual: ... -Logs: (sanitized, last 30 lines) -``` - -Bei Konfigurationsproblemen fügen Sie die Ausgabe von `os doctor` bei — es -diagnostiziert 80 % der Fehlkonfigurationen ganz von allein. - -## Reaktionszeiten - -| Kanal | Reaktionszeit nach bestem Bemühen | -|---|---| -| Security-E-Mail | 1 Werktag | -| GitHub Issues — Fehler, mit Reproduktion | 3 Werktage für die Triage, Fix mit dem nächsten Release-Zug | -| GitHub Issues — Feature-Anfrage | 7 Werktage für die Triage | -| GitHub Discussions | Community-getrieben; Maintainer melden sich regelmäßig zu Wort | -| Kommerzieller Support | Gemäß Ihrem Supportvertrag | - -Dies erfolgt nach bestem Bemühen und stellt keine SLAs dar. Verträge für -kommerziellen Support enthalten formale SLAs. - -## Kommerzieller Support & Dienstleistungen - -Verfügbar vom ObjectStack-Team: - -- **Kommerzieller Support** mit Reaktionszeit-SLAs. -- **Managed Hosting** — wir betreiben es für Sie. -- **Architektur-Review** — Plausibilitätsprüfung vor dem Deployment. -- **Individuelle Plugins / Funktionen**, gebaut nach Ihren Vorgaben. -- **OEM-Weiterverbreitung** — betten Sie ObjectOS in Ihr Produkt ein. - -Kontakt: **sales@objectstack.ai**. - -## Zurückgeben - -ObjectOS steht unter Apache-2.0 und nimmt Beiträge an: - -- [CONTRIBUTING.md](https://github.com/objectstack-ai/objectstack/blob/main/CONTRIBUTING.md) -- [Code of Conduct](https://github.com/objectstack-ai/objectstack/blob/main/CODE_OF_CONDUCT.md) -- Eröffnen Sie früh einen Draft-PR — wir prüfen lieber einen Entwurf, als dass - doppelte Arbeit entsteht. - -## Status & Vorfälle - -Gehostete Dienste (ObjectStack Cloud, Package-Registry): -[status.objectstack.ai](https://status.objectstack.ai). - -Für Ihr selbst gehostetes ObjectOS-Deployment liegt der Status in Ihrer -Verantwortung — binden Sie ihn an Ihr übliches Monitoring an (siehe [Observability](/docs/operate/observability)). diff --git a/content/docs/resources/support.es.mdx b/content/docs/resources/support.es.mdx deleted file mode 100644 index 26fc7bb..0000000 --- a/content/docs/resources/support.es.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Soporte -description: Dónde obtener ayuda, cómo reportar errores y qué esperar en cuanto a respuestas. -translation: - source_sha: f6f76ab1e3037f16decdccd28977c380bb353dc9ad8d086e666f9c117b3981fa - guide_rev: 1 - mode: auto ---- - -## A dónde acudir según el caso - -| Si tú … | Acude a | -|---|---| -| Tienes una pregunta del tipo "¿cómo hago…?" | [GitHub Discussions](https://github.com/objectstack-ai/objectos/discussions) — comunidad + mantenedores | -| Encontraste un error | [GitHub Issues](https://github.com/objectstack-ai/objectos/issues) — por favor incluye la versión, los pasos para reproducirlo y lo esperado frente a lo real | -| Encontraste una vulnerabilidad de seguridad | **security@objectstack.ai** — **no** abras un issue público | -| Necesitas soporte comercial / SLA | **sales@objectstack.ai** | -| Quieres charlar con usuarios y mantenedores | [Discord](https://discord.gg/objectstack) (gestionado por la comunidad) | -| Quieres seguir los lanzamientos | Observa [github.com/objectstack-ai/objectos](https://github.com/objectstack-ai/objectos) → Releases | -| Quieres que se implemente una función de pago | Abre una Discussion → etiquétala con `funding` | - -## Cómo redactar un buen reporte de error - -La versión de 30 segundos: - -```text -ObjectOS version: 10.2.0 (or sha-abc123) -Node version: 22.4.0 -Install method: docker / npm -g / source -Database: postgres 16 / sqlite / turso / mongo -Repro steps: 1. ... 2. ... 3. ... -Expected: ... -Actual: ... -Logs: (sanitized, last 30 lines) -``` - -Para problemas de configuración, adjunta la salida de `os doctor` — esto -diagnostica por sí solo el 80 % de las configuraciones incorrectas. - -## Qué esperar en cuanto a respuestas - -| Canal | Tiempo de respuesta estimado (best-effort) | -|---|---| -| Correo de seguridad | 1 día hábil | -| GitHub Issues — error, con pasos para reproducir | 3 días hábiles para la clasificación, corrección en el siguiente tren de lanzamientos | -| GitHub Issues — solicitud de función | 7 días hábiles para la clasificación | -| GitHub Discussions | Impulsado por la comunidad; los mantenedores participan con regularidad | -| Soporte comercial | Según tu contrato de soporte | - -Son tiempos de mejor esfuerzo (best-effort), no SLAs. Los contratos de soporte -comercial incluyen SLAs formales. - -## Soporte y servicios comerciales - -Disponibles a través del equipo de ObjectStack: - -- **Soporte comercial** con SLAs de tiempo de respuesta. -- **Hospedaje gestionado** — lo ejecutamos por ti. -- **Revisión de arquitectura** — verificación de viabilidad previa al despliegue. -- **Plugins / capacidades personalizadas** construidos según tus especificaciones. -- **Redistribución OEM** — integra ObjectOS en tu producto. - -Contacta a **sales@objectstack.ai**. - -## Contribuir de vuelta - -ObjectOS usa la licencia Apache-2.0 y acepta contribuciones: - -- [CONTRIBUTING.md](https://github.com/objectstack-ai/objectstack/blob/main/CONTRIBUTING.md) -- [Code of Conduct](https://github.com/objectstack-ai/objectstack/blob/main/CODE_OF_CONDUCT.md) -- Abre un borrador de PR pronto — preferimos revisar un esbozo a que haya - esfuerzo duplicado. - -## Estado e incidentes - -Servicios alojados (ObjectStack Cloud, registro de paquetes): -[status.objectstack.ai](https://status.objectstack.ai). - -Para tu despliegue autoalojado de ObjectOS, el estado es tu responsabilidad — -conéctalo a tu monitoreo habitual (consulta [Observability](/docs/operate/observability)). diff --git a/content/docs/resources/support.fr.mdx b/content/docs/resources/support.fr.mdx deleted file mode 100644 index de5a41a..0000000 --- a/content/docs/resources/support.fr.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Support -description: Où obtenir de l'aide, comment signaler des bugs, attentes en matière de délais de réponse. -translation: - source_sha: f6f76ab1e3037f16decdccd28977c380bb353dc9ad8d086e666f9c117b3981fa - guide_rev: 1 - mode: auto ---- - -## Où aller pour quoi - -| Si vous … | Rendez-vous sur | -|---|---| -| Avez une question « comment faire » | [GitHub Discussions](https://github.com/objectstack-ai/objectos/discussions) — communauté + mainteneurs | -| Avez trouvé un bug | [GitHub Issues](https://github.com/objectstack-ai/objectos/issues) — merci d'indiquer la version, la reproduction, le comportement attendu vs réel | -| Avez trouvé une faille de sécurité | **security@objectstack.ai** — n'ouvrez **pas** une issue publique | -| Avez besoin d'un support commercial / SLA | **sales@objectstack.ai** | -| Souhaitez échanger avec les utilisateurs + mainteneurs | [Discord](https://discord.gg/objectstack) (géré par la communauté) | -| Souhaitez suivre les versions | Surveillez [github.com/objectstack-ai/objectos](https://github.com/objectstack-ai/objectos) → Releases | -| Souhaitez le développement d'une fonctionnalité payante | Ouvrez une Discussion → taguez avec `funding` | - -## Rédiger un bon rapport de bug - -La version en 30 secondes : - -```text -ObjectOS version: 10.2.0 (or sha-abc123) -Node version: 22.4.0 -Install method: docker / npm -g / source -Database: postgres 16 / sqlite / turso / mongo -Repro steps: 1. ... 2. ... 3. ... -Expected: ... -Actual: ... -Logs: (sanitized, last 30 lines) -``` - -Pour les problèmes de configuration, joignez la sortie de `os doctor` — elle -diagnostique à elle seule 80 % des erreurs de configuration. - -## Attentes en matière de réponse - -| Canal | Délai de réponse au mieux | -|---|---| -| E-mail de sécurité | 1 jour ouvré | -| GitHub Issues — bug, avec reproduction | 3 jours ouvrés pour le tri, correction lors de la prochaine vague de versions | -| GitHub Issues — demande de fonctionnalité | 7 jours ouvrés pour le tri | -| GitHub Discussions | Piloté par la communauté ; les mainteneurs interviennent régulièrement | -| Support commercial | Selon votre contrat de support | - -Il s'agit d'engagements au mieux, et non de SLA. Les contrats de support -commercial comportent des SLA formels. - -## Support commercial & services - -Disponibles auprès de l'équipe ObjectStack : - -- **Support commercial** avec des SLA sur les délais de réponse. -- **Hébergement managé** — nous l'exploitons pour vous. -- **Revue d'architecture** — vérification de bon sens avant déploiement. -- **Plugins / capacités sur mesure** développés selon vos spécifications. -- **Redistribution OEM** — intégrez ObjectOS dans votre produit. - -Contactez **sales@objectstack.ai**. - -## Contribuer en retour - -ObjectOS est sous licence Apache-2.0 et accepte les contributions : - -- [CONTRIBUTING.md](https://github.com/objectstack-ai/objectstack/blob/main/CONTRIBUTING.md) -- [Code of Conduct](https://github.com/objectstack-ai/objectstack/blob/main/CODE_OF_CONDUCT.md) -- Ouvrez une PR en brouillon tôt — nous préférons relire une ébauche plutôt - que de voir des efforts dupliqués. - -## Statut & incidents - -Services hébergés (ObjectStack Cloud, registre de paquets) : -[status.objectstack.ai](https://status.objectstack.ai). - -Pour votre déploiement ObjectOS auto-hébergé, le statut est de votre ressort — -reliez-le à votre supervision habituelle (voir [Observability](/docs/operate/observability)). diff --git a/content/docs/resources/support.ja.mdx b/content/docs/resources/support.ja.mdx deleted file mode 100644 index 7849aae..0000000 --- a/content/docs/resources/support.ja.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: サポート -description: ヘルプの入手先、バグの報告方法、応答時間の目安。 -translation: - source_sha: f6f76ab1e3037f16decdccd28977c380bb353dc9ad8d086e666f9c117b3981fa - guide_rev: 1 - mode: auto ---- - -## 目的別の問い合わせ先 - -| 状況 | 問い合わせ先 | -|---|---| -| 「どうやって~する」という質問がある | [GitHub Discussions](https://github.com/objectstack-ai/objectos/discussions) — コミュニティ + メンテナー | -| バグを見つけた | [GitHub Issues](https://github.com/objectstack-ai/objectos/issues) — バージョン、再現手順、期待される動作と実際の動作を記載してください | -| セキュリティ脆弱性を見つけた | **security@objectstack.ai** — 公開 issue は**作成しない**でください | -| 商用サポート / SLA が必要 | **sales@objectstack.ai** | -| ユーザーやメンテナーと交流したい | [Discord](https://discord.gg/objectstack)(コミュニティ運営) | -| リリースを追いたい | [github.com/objectstack-ai/objectos](https://github.com/objectstack-ai/objectos) → Releases をウォッチ | -| 有償で機能を実装してほしい | Discussion を作成 → `funding` でタグ付け | - -## 良いバグレポートの書き方 - -30 秒で済むテンプレート: - -```text -ObjectOS version: 10.2.0 (or sha-abc123) -Node version: 22.4.0 -Install method: docker / npm -g / source -Database: postgres 16 / sqlite / turso / mongo -Repro steps: 1. ... 2. ... 3. ... -Expected: ... -Actual: ... -Logs: (sanitized, last 30 lines) -``` - -設定に関する問題の場合は、`os doctor` の出力を添付してください。 -これだけで設定ミスの 80% を診断できます。 - -## 応答時間の目安 - -| チャネル | ベストエフォートの応答時間 | -|---|---| -| セキュリティメール | 1 営業日 | -| GitHub Issues — バグ(再現手順あり) | トリアージまで 3 営業日、次回リリース時に修正 | -| GitHub Issues — 機能リクエスト | トリアージまで 7 営業日 | -| GitHub Discussions | コミュニティ主導。メンテナーも定期的に参加します | -| 商用サポート | サポート契約に準じます | - -これらはベストエフォートであり、SLA ではありません。商用サポート契約には -正式な SLA が付帯します。 - -## 商用サポート & サービス - -ObjectStack チームが提供します: - -- 応答時間 SLA 付きの**商用サポート**。 -- **マネージドホスティング** — 当社が運用を代行します。 -- **アーキテクチャレビュー** — デプロイ前の健全性チェック。 -- ご要望の仕様に合わせて構築する**カスタムプラグイン / 機能**。 -- **OEM 再配布** — ObjectOS を自社製品に組み込めます。 - -お問い合わせは **sales@objectstack.ai** まで。 - -## コントリビューション - -ObjectOS は Apache-2.0 ライセンスであり、コントリビューションを受け付けています: - -- [CONTRIBUTING.md](https://github.com/objectstack-ai/objectstack/blob/main/CONTRIBUTING.md) -- [Code of Conduct](https://github.com/objectstack-ai/objectstack/blob/main/CODE_OF_CONDUCT.md) -- 早めにドラフト PR を作成してください。重複した作業をするよりも、 - 下書きをレビューするほうが望ましいです。 - -## ステータス & インシデント - -ホスティングサービス(ObjectStack Cloud、パッケージレジストリ): -[status.objectstack.ai](https://status.objectstack.ai)。 - -セルフホストの ObjectOS デプロイのステータスはご自身で管理してください。 -通常の監視に組み込んでください([Observability](/docs/operate/observability) を参照)。 diff --git a/content/docs/resources/support.ko.mdx b/content/docs/resources/support.ko.mdx deleted file mode 100644 index aeb1ae0..0000000 --- a/content/docs/resources/support.ko.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: 지원 -description: 도움을 받을 수 있는 곳, 버그 신고 방법, 응답 기대치. -translation: - source_sha: f6f76ab1e3037f16decdccd28977c380bb353dc9ad8d086e666f9c117b3981fa - guide_rev: 1 - mode: auto ---- - -## 상황별 안내 - -| 다음과 같은 경우 … | 이동할 곳 | -|---|---| -| "어떻게 하나요" 질문이 있는 경우 | [GitHub Discussions](https://github.com/objectstack-ai/objectos/discussions) — 커뮤니티 + 메인테이너 | -| 버그를 발견한 경우 | [GitHub Issues](https://github.com/objectstack-ai/objectos/issues) — 버전, 재현 방법, 예상 동작 대 실제 동작을 포함해 주세요 | -| 보안 취약점을 발견한 경우 | **security@objectstack.ai** — 공개 이슈를 **열지** 마세요 | -| 상용 지원 / SLA가 필요한 경우 | **sales@objectstack.ai** | -| 사용자 + 메인테이너와 대화하고 싶은 경우 | [Discord](https://discord.gg/objectstack) (커뮤니티 운영) | -| 릴리스를 팔로우하고 싶은 경우 | [github.com/objectstack-ai/objectos](https://github.com/objectstack-ai/objectos) → Releases를 Watch | -| 유료로 기능 구현을 원하는 경우 | Discussion을 열고 → `funding` 태그를 추가 | - -## 좋은 버그 리포트 작성하기 - -30초 버전: - -```text -ObjectOS version: 10.2.0 (or sha-abc123) -Node version: 22.4.0 -Install method: docker / npm -g / source -Database: postgres 16 / sqlite / turso / mongo -Repro steps: 1. ... 2. ... 3. ... -Expected: ... -Actual: ... -Logs: (sanitized, last 30 lines) -``` - -구성 관련 문제의 경우 `os doctor`의 출력을 첨부하세요. 이 명령은 -잘못된 구성의 80%를 자체적으로 진단합니다. - -## 응답 기대치 - -| 채널 | 최선의 노력 기준 응답 시간 | -|---|---| -| 보안 이메일 | 영업일 기준 1일 | -| GitHub Issues — 버그, 재현 방법 포함 | 분류까지 영업일 기준 3일, 다음 릴리스 주기에 수정 | -| GitHub Issues — 기능 요청 | 분류까지 영업일 기준 7일 | -| GitHub Discussions | 커뮤니티 주도; 메인테이너가 정기적으로 참여 | -| 상용 지원 | 지원 계약에 따름 | - -이는 최선의 노력 기준이며 SLA가 아닙니다. 상용 지원 계약에는 -공식 SLA가 포함됩니다. - -## 상용 지원 및 서비스 - -ObjectStack 팀에서 제공: - -- 응답 시간 SLA가 포함된 **상용 지원**. -- **매니지드 호스팅** — 저희가 운영해 드립니다. -- **아키텍처 검토** — 배포 전 점검. -- 사양에 맞춰 제작된 **맞춤형 플러그인 / 기능**. -- **OEM 재배포** — ObjectOS를 제품에 임베드. - -**sales@objectstack.ai**로 문의하세요. - -## 기여하기 - -ObjectOS는 Apache-2.0이며 기여를 받습니다: - -- [CONTRIBUTING.md](https://github.com/objectstack-ai/objectstack/blob/main/CONTRIBUTING.md) -- [Code of Conduct](https://github.com/objectstack-ai/objectstack/blob/main/CODE_OF_CONDUCT.md) -- 초안 PR을 일찍 여세요 — 중복 작업이 발생하는 것보다 스케치를 - 검토하는 편이 낫습니다. - -## 상태 및 장애 - -호스팅 서비스(ObjectStack Cloud, 패키지 레지스트리): -[status.objectstack.ai](https://status.objectstack.ai). - -자체 호스팅된 ObjectOS 배포의 경우 상태는 사용자의 책임입니다 — -평소 사용하는 모니터링에 연결하세요(자세한 내용은 [Observability](/docs/operate/observability) 참조). diff --git a/content/docs/resources/support.zh-Hans.mdx b/content/docs/resources/support.zh-Hans.mdx deleted file mode 100644 index c2a8f21..0000000 --- a/content/docs/resources/support.zh-Hans.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: 支持 -description: 到哪里寻求帮助、如何上报 bug、响应预期。 -translation: - source_sha: f6f76ab1e3037f16decdccd28977c380bb353dc9ad8d086e666f9c117b3981fa - guide_rev: 1 - mode: auto ---- - -## 不同事情去哪里 - -| 如果你…… | 前往 | -|---|---| -| 有 "怎么做" 的问题 | [GitHub Discussions](https://github.com/objectstack-ai/objectos/discussions) —— 社区 + 维护者 | -| 发现了 bug | [GitHub Issues](https://github.com/objectstack-ai/objectos/issues) —— 请附版本、复现步骤、期望 vs 实际 | -| 发现了安全漏洞 | **security@objectstack.ai** —— **不要**开公开 issue | -| 需要商业支持 / SLA | **sales@objectstack.ai** | -| 想和用户与维护者聊聊 | [Discord](https://discord.gg/objectstack)(社区运营) | -| 想关注发版 | Watch [github.com/objectstack-ai/objectos](https://github.com/objectstack-ai/objectos) → Releases | -| 想付费实现某个特性 | 开一个 Discussion → 加上 `funding` 标签 | - -## 写一份好的 bug 报告 - -30 秒版本: - -```text -ObjectOS version: 14.7.0 (or sha-abc123) -Node version: 22.4.0 -Install method: docker / npm -g / source -Database: postgres 16 / sqlite / turso / mongo -Repro steps: 1. ... 2. ... 3. ... -Expected: ... -Actual: ... -Logs: (sanitized, last 30 lines) -``` - -对配置类问题,请附上 `os doctor` 的输出 —— 它能独立诊断 80% 的 -错误配置。 - -## 响应预期 - -| 渠道 | 尽力而为的响应时间 | -|---|---| -| 安全邮件 | 1 个工作日 | -| GitHub Issues —— 带复现的 bug | 3 个工作日内分流,下一趟发布列车修复 | -| GitHub Issues —— 特性请求 | 7 个工作日内分流 | -| GitHub Discussions | 社区驱动;维护者会定期参与 | -| 商业支持 | 按你的支持合同 | - -以上为尽力而为,并非 SLA。商业支持合同会带正式 SLA。 - -## 商业支持与服务 - -ObjectStack 团队可提供: - -- 带响应时间 SLA 的**商业支持**。 -- **托管服务** —— 我们替你运维。 -- **架构评审** —— 部署前的合理性检查。 -- 按你需求**定制插件 / 能力**。 -- **OEM 再分发** —— 把 ObjectOS 嵌入你的产品。 - -请联系 **sales@objectstack.ai**。 - -## 回馈贡献 - -ObjectOS 是 Apache-2.0,接受贡献: - -- [CONTRIBUTING.md](https://github.com/objectstack-ai/objectstack/blob/main/CONTRIBUTING.md) -- [Code of Conduct](https://github.com/objectstack-ai/objectstack/blob/main/CODE_OF_CONDUCT.md) -- 尽早开 draft PR —— 我们更愿意评审一份草图,而不是出现重复劳动。 - -## 状态与事件 - -托管服务(ObjectStack Cloud、包注册中心): -[status.objectstack.ai](https://status.objectstack.ai)。 - -自托管的 ObjectOS 部署的状态由你自己负责 —— 接到你常用的监控上 -(见 [可观测性](/docs/operate/observability))。 diff --git a/content/docs/resources/support.zh-Hant.mdx b/content/docs/resources/support.zh-Hant.mdx deleted file mode 100644 index 3d65a19..0000000 --- a/content/docs/resources/support.zh-Hant.mdx +++ /dev/null @@ -1,79 +0,0 @@ ---- -# @generated zh-Hant from zh-Hans -- do not edit. Edit the English source, then regenerate: pnpm --filter @objectos/docs gen:zh-hant -title: 支援 -description: 到哪裡尋求幫助、如何上報 bug、響應預期。 -translation: - source_sha: f6f76ab1e3037f16decdccd28977c380bb353dc9ad8d086e666f9c117b3981fa - guide_rev: 1 - mode: auto ---- - -## 不同事情去哪裡 - -| 如果你…… | 前往 | -|---|---| -| 有 "怎麼做" 的問題 | [GitHub Discussions](https://github.com/objectstack-ai/objectos/discussions) —— 社群 + 維護者 | -| 發現了 bug | [GitHub Issues](https://github.com/objectstack-ai/objectos/issues) —— 請附版本、復現步驟、期望 vs 實際 | -| 發現了安全漏洞 | **security@objectstack.ai** —— **不要**開公開 issue | -| 需要商業支援 / SLA | **sales@objectstack.ai** | -| 想和使用者與維護者聊聊 | [Discord](https://discord.gg/objectstack)(社群運營) | -| 想關注發版 | Watch [github.com/objectstack-ai/objectos](https://github.com/objectstack-ai/objectos) → Releases | -| 想付費實現某個特性 | 開一個 Discussion → 加上 `funding` 標籤 | - -## 寫一份好的 bug 報告 - -30 秒版本: - -```text -ObjectOS version: 14.7.0 (or sha-abc123) -Node version: 22.4.0 -Install method: docker / npm -g / source -Database: postgres 16 / sqlite / turso / mongo -Repro steps: 1. ... 2. ... 3. ... -Expected: ... -Actual: ... -Logs: (sanitized, last 30 lines) -``` - -對配置類問題,請附上 `os doctor` 的輸出 —— 它能獨立診斷 80% 的 -錯誤配置。 - -## 響應預期 - -| 渠道 | 盡力而為的響應時間 | -|---|---| -| 安全郵件 | 1 個工作日 | -| GitHub Issues —— 帶復現的 bug | 3 個工作日內分流,下一趟釋出列車修復 | -| GitHub Issues —— 特性請求 | 7 個工作日內分流 | -| GitHub Discussions | 社群驅動;維護者會定期參與 | -| 商業支援 | 按你的支援合同 | - -以上為盡力而為,並非 SLA。商業支援合同會帶正式 SLA。 - -## 商業支援與服務 - -ObjectStack 團隊可提供: - -- 帶響應時間 SLA 的**商業支援**。 -- **託管服務** —— 我們替你運維。 -- **架構評審** —— 部署前的合理性檢查。 -- 按你需求**定製外掛 / 能力**。 -- **OEM 再分發** —— 把 ObjectOS 嵌入你的產品。 - -請聯絡 **sales@objectstack.ai**。 - -## 回饋貢獻 - -ObjectOS 是 Apache-2.0,接受貢獻: - -- [CONTRIBUTING.md](https://github.com/objectstack-ai/objectstack/blob/main/CONTRIBUTING.md) -- [Code of Conduct](https://github.com/objectstack-ai/objectstack/blob/main/CODE_OF_CONDUCT.md) -- 儘早開 draft PR —— 我們更願意評審一份草圖,而不是出現重複勞動。 - -## 狀態與事件 - -託管服務(ObjectStack Cloud、包註冊中心): -[status.objectstack.ai](https://status.objectstack.ai)。 - -自託管的 ObjectOS 部署的狀態由你自己負責 —— 接到你常用的監控上 -(見 [可觀測性](/docs/operate/observability))。 diff --git a/tools/ci-scripts/run-self-tests.mjs b/tools/ci-scripts/run-self-tests.mjs index c0d9679..f753ff2 100644 --- a/tools/ci-scripts/run-self-tests.mjs +++ b/tools/ci-scripts/run-self-tests.mjs @@ -90,6 +90,13 @@ * rules — the copies of the positioning constant agreeing with it, the one * brand spelling in shipped output, the stale sentences staying gone — can * still go red, and stays silent on the shapes the rulings on #171 accepted. + * + * `check-search-locales.mjs` is listed for its `--self-test` only (#296). Its + * gate mode loads the built `/api/search` handler out of `apps/docs/.next/` + * and is a `ci.yml` step after the build, like the two gates above. Its + * fixtures are fake handlers. They prove that each rule (a throw, a non-200, + * a non-array, no hits, a page its own title cannot find, a negative control + * that matches) can still go red. */ import { readFileSync, readdirSync, existsSync } from 'node:fs'; @@ -112,6 +119,7 @@ const SELF_TESTED = [ 'check-prerender-cache.mjs', 'check-translation-ownership.mjs', 'check-positioning.mjs', + 'check-search-locales.mjs', ]; /**