@knowzai/cli 0.1.0 → 0.3.0
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.
- package/assets/portable/.env.example +3 -0
- package/assets/portable/docker-compose.yml +18 -0
- package/assets/portable/releases.json +22 -0
- package/assets/selfhosted/.env.example +19 -0
- package/assets/selfhosted/docker-compose.yml +96 -0
- package/assets/selfhosted/releases.json +28 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/base-command.d.ts +21 -2
- package/dist/base-command.d.ts.map +1 -1
- package/dist/base-command.js +47 -4
- package/dist/base-command.js.map +1 -1
- package/dist/commands/ask.d.ts.map +1 -1
- package/dist/commands/ask.js +5 -1
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/auth/status.d.ts +1 -1
- package/dist/commands/auth/status.d.ts.map +1 -1
- package/dist/commands/auth/status.js +4 -0
- package/dist/commands/auth/status.js.map +1 -1
- package/dist/commands/chat.d.ts +5 -0
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +32 -13
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/config/get.d.ts.map +1 -1
- package/dist/commands/config/get.js +3 -1
- package/dist/commands/config/get.js.map +1 -1
- package/dist/commands/config/list.d.ts.map +1 -1
- package/dist/commands/config/list.js +12 -4
- package/dist/commands/config/list.js.map +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/down.d.ts +9 -0
- package/dist/commands/down.d.ts.map +1 -1
- package/dist/commands/down.js +16 -1
- package/dist/commands/down.js.map +1 -1
- package/dist/commands/export.d.ts +27 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +155 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/import.d.ts +27 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +124 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/index/scan.d.ts.map +1 -1
- package/dist/commands/index/scan.js +24 -5
- package/dist/commands/index/scan.js.map +1 -1
- package/dist/commands/knowledge/amend.d.ts +1 -0
- package/dist/commands/knowledge/amend.d.ts.map +1 -1
- package/dist/commands/knowledge/amend.js +11 -2
- package/dist/commands/knowledge/amend.js.map +1 -1
- package/dist/commands/knowledge/attach.d.ts +19 -0
- package/dist/commands/knowledge/attach.d.ts.map +1 -0
- package/dist/commands/knowledge/attach.js +51 -0
- package/dist/commands/knowledge/attach.js.map +1 -0
- package/dist/commands/knowledge/create.d.ts +9 -1
- package/dist/commands/knowledge/create.d.ts.map +1 -1
- package/dist/commands/knowledge/create.js +26 -4
- package/dist/commands/knowledge/create.js.map +1 -1
- package/dist/commands/knowledge/update.d.ts +1 -0
- package/dist/commands/knowledge/update.d.ts.map +1 -1
- package/dist/commands/knowledge/update.js +4 -1
- package/dist/commands/knowledge/update.js.map +1 -1
- package/dist/commands/login.d.ts +19 -3
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +113 -64
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +35 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/mcp/serve.d.ts +16 -0
- package/dist/commands/mcp/serve.d.ts.map +1 -0
- package/dist/commands/mcp/serve.js +50 -0
- package/dist/commands/mcp/serve.js.map +1 -0
- package/dist/commands/menu.d.ts.map +1 -1
- package/dist/commands/menu.js +39 -3
- package/dist/commands/menu.js.map +1 -1
- package/dist/commands/peer/accept-fingerprint.d.ts +17 -0
- package/dist/commands/peer/accept-fingerprint.d.ts.map +1 -0
- package/dist/commands/peer/accept-fingerprint.js +35 -0
- package/dist/commands/peer/accept-fingerprint.js.map +1 -0
- package/dist/commands/peer/add.d.ts +22 -0
- package/dist/commands/peer/add.d.ts.map +1 -0
- package/dist/commands/peer/add.js +44 -0
- package/dist/commands/peer/add.js.map +1 -0
- package/dist/commands/peer/cancel.d.ts +13 -0
- package/dist/commands/peer/cancel.d.ts.map +1 -0
- package/dist/commands/peer/cancel.js +20 -0
- package/dist/commands/peer/cancel.js.map +1 -0
- package/dist/commands/peer/link.d.ts +16 -0
- package/dist/commands/peer/link.d.ts.map +1 -0
- package/dist/commands/peer/link.js +32 -0
- package/dist/commands/peer/link.js.map +1 -0
- package/dist/commands/peer/links.d.ts +12 -0
- package/dist/commands/peer/links.d.ts.map +1 -0
- package/dist/commands/peer/links.js +25 -0
- package/dist/commands/peer/links.js.map +1 -0
- package/dist/commands/peer/list.d.ts +10 -0
- package/dist/commands/peer/list.d.ts.map +1 -0
- package/dist/commands/peer/list.js +22 -0
- package/dist/commands/peer/list.js.map +1 -0
- package/dist/commands/peer/pull.d.ts +19 -0
- package/dist/commands/peer/pull.d.ts.map +1 -0
- package/dist/commands/peer/pull.js +30 -0
- package/dist/commands/peer/pull.js.map +1 -0
- package/dist/commands/peer/push.d.ts +19 -0
- package/dist/commands/peer/push.d.ts.map +1 -0
- package/dist/commands/peer/push.js +30 -0
- package/dist/commands/peer/push.js.map +1 -0
- package/dist/commands/peer/remove.d.ts +12 -0
- package/dist/commands/peer/remove.d.ts.map +1 -0
- package/dist/commands/peer/remove.js +19 -0
- package/dist/commands/peer/remove.js.map +1 -0
- package/dist/commands/peer/rotate-key.d.ts +14 -0
- package/dist/commands/peer/rotate-key.d.ts.map +1 -0
- package/dist/commands/peer/rotate-key.js +26 -0
- package/dist/commands/peer/rotate-key.js.map +1 -0
- package/dist/commands/peer/run.d.ts +13 -0
- package/dist/commands/peer/run.d.ts.map +1 -0
- package/dist/commands/peer/run.js +31 -0
- package/dist/commands/peer/run.js.map +1 -0
- package/dist/commands/peer/runs.d.ts +15 -0
- package/dist/commands/peer/runs.d.ts.map +1 -0
- package/dist/commands/peer/runs.js +32 -0
- package/dist/commands/peer/runs.js.map +1 -0
- package/dist/commands/peer/test.d.ts +13 -0
- package/dist/commands/peer/test.d.ts.map +1 -0
- package/dist/commands/peer/test.js +30 -0
- package/dist/commands/peer/test.js.map +1 -0
- package/dist/commands/peer/unlink.d.ts +13 -0
- package/dist/commands/peer/unlink.d.ts.map +1 -0
- package/dist/commands/peer/unlink.js +20 -0
- package/dist/commands/peer/unlink.js.map +1 -0
- package/dist/commands/pg/status.d.ts.map +1 -1
- package/dist/commands/pg/status.js +6 -3
- package/dist/commands/pg/status.js.map +1 -1
- package/dist/commands/pg/up.d.ts.map +1 -1
- package/dist/commands/pg/up.js +9 -4
- package/dist/commands/pg/up.js.map +1 -1
- package/dist/commands/platform/status.d.ts.map +1 -1
- package/dist/commands/platform/status.js +4 -4
- package/dist/commands/platform/status.js.map +1 -1
- package/dist/commands/profile/purge.d.ts +20 -0
- package/dist/commands/profile/purge.d.ts.map +1 -0
- package/dist/commands/profile/purge.js +43 -0
- package/dist/commands/profile/purge.js.map +1 -0
- package/dist/commands/repo/context.d.ts.map +1 -1
- package/dist/commands/repo/context.js +3 -1
- package/dist/commands/repo/context.js.map +1 -1
- package/dist/commands/repo/graph.d.ts +3 -6
- package/dist/commands/repo/graph.d.ts.map +1 -1
- package/dist/commands/repo/graph.js +24 -40
- package/dist/commands/repo/graph.js.map +1 -1
- package/dist/commands/repo/index/index.d.ts +1 -0
- package/dist/commands/repo/index/index.d.ts.map +1 -1
- package/dist/commands/repo/index/index.js +100 -12
- package/dist/commands/repo/index/index.js.map +1 -1
- package/dist/commands/repo/search.d.ts.map +1 -1
- package/dist/commands/repo/search.js +2 -0
- package/dist/commands/repo/search.js.map +1 -1
- package/dist/commands/repo/setup.d.ts +9 -2
- package/dist/commands/repo/setup.d.ts.map +1 -1
- package/dist/commands/repo/setup.js +84 -8
- package/dist/commands/repo/setup.js.map +1 -1
- package/dist/commands/status.d.ts +4 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +21 -3
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/transfer.d.ts +30 -0
- package/dist/commands/transfer.d.ts.map +1 -0
- package/dist/commands/transfer.js +140 -0
- package/dist/commands/transfer.js.map +1 -0
- package/dist/commands/tui.js +1 -1
- package/dist/commands/tui.js.map +1 -1
- package/dist/commands/up.d.ts +6 -27
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +63 -21
- package/dist/commands/up.js.map +1 -1
- package/dist/lib/attach.d.ts +48 -0
- package/dist/lib/attach.d.ts.map +1 -0
- package/dist/lib/attach.js +91 -0
- package/dist/lib/attach.js.map +1 -0
- package/dist/lib/chat-render.d.ts +39 -0
- package/dist/lib/chat-render.d.ts.map +1 -0
- package/dist/lib/chat-render.js +77 -0
- package/dist/lib/chat-render.js.map +1 -0
- package/dist/lib/cmek-guard.d.ts +52 -0
- package/dist/lib/cmek-guard.d.ts.map +1 -0
- package/dist/lib/cmek-guard.js +73 -0
- package/dist/lib/cmek-guard.js.map +1 -0
- package/dist/lib/content.d.ts +7 -0
- package/dist/lib/content.d.ts.map +1 -1
- package/dist/lib/content.js +9 -2
- package/dist/lib/content.js.map +1 -1
- package/dist/lib/credential-purge.d.ts +52 -0
- package/dist/lib/credential-purge.d.ts.map +1 -0
- package/dist/lib/credential-purge.js +37 -0
- package/dist/lib/credential-purge.js.map +1 -0
- package/dist/lib/ingest.d.ts.map +1 -1
- package/dist/lib/ingest.js +7 -3
- package/dist/lib/ingest.js.map +1 -1
- package/dist/lib/local-mcp-server.d.ts +82 -0
- package/dist/lib/local-mcp-server.d.ts.map +1 -0
- package/dist/lib/local-mcp-server.js +252 -0
- package/dist/lib/local-mcp-server.js.map +1 -0
- package/dist/lib/local-mcp-stdio.d.ts +8 -0
- package/dist/lib/local-mcp-stdio.d.ts.map +1 -0
- package/dist/lib/local-mcp-stdio.js +50 -0
- package/dist/lib/local-mcp-stdio.js.map +1 -0
- package/dist/lib/login-guided.d.ts +20 -0
- package/dist/lib/login-guided.d.ts.map +1 -0
- package/dist/lib/login-guided.js +89 -0
- package/dist/lib/login-guided.js.map +1 -0
- package/dist/lib/login.d.ts +58 -12
- package/dist/lib/login.d.ts.map +1 -1
- package/dist/lib/login.js +170 -12
- package/dist/lib/login.js.map +1 -1
- package/dist/lib/onboarding.d.ts +56 -0
- package/dist/lib/onboarding.d.ts.map +1 -0
- package/dist/lib/onboarding.js +67 -0
- package/dist/lib/onboarding.js.map +1 -0
- package/dist/lib/peer-command.d.ts +51 -0
- package/dist/lib/peer-command.d.ts.map +1 -0
- package/dist/lib/peer-command.js +120 -0
- package/dist/lib/peer-command.js.map +1 -0
- package/dist/lib/peer-support.d.ts +67 -0
- package/dist/lib/peer-support.d.ts.map +1 -0
- package/dist/lib/peer-support.js +154 -0
- package/dist/lib/peer-support.js.map +1 -0
- package/dist/lib/platform-edition.d.ts +34 -0
- package/dist/lib/platform-edition.d.ts.map +1 -0
- package/dist/lib/platform-edition.js +47 -0
- package/dist/lib/platform-edition.js.map +1 -0
- package/dist/lib/platform-frontdoor-runtime.d.ts.map +1 -1
- package/dist/lib/platform-frontdoor-runtime.js +32 -1
- package/dist/lib/platform-frontdoor-runtime.js.map +1 -1
- package/dist/lib/platform-frontdoor.d.ts +26 -2
- package/dist/lib/platform-frontdoor.d.ts.map +1 -1
- package/dist/lib/platform-frontdoor.js +363 -126
- package/dist/lib/platform-frontdoor.js.map +1 -1
- package/dist/lib/platform-lifecycle.d.ts +7 -0
- package/dist/lib/platform-lifecycle.d.ts.map +1 -1
- package/dist/lib/platform-lifecycle.js +14 -3
- package/dist/lib/platform-lifecycle.js.map +1 -1
- package/dist/lib/platform-onboarding.d.ts +1 -0
- package/dist/lib/platform-onboarding.d.ts.map +1 -1
- package/dist/lib/platform-onboarding.js +13 -2
- package/dist/lib/platform-onboarding.js.map +1 -1
- package/dist/lib/platform-profile-purge.d.ts +1 -1
- package/dist/lib/platform-profile-purge.d.ts.map +1 -1
- package/dist/lib/platform-profile-purge.js +2 -1
- package/dist/lib/platform-profile-purge.js.map +1 -1
- package/dist/lib/platform-provider-prompt.d.ts +4 -0
- package/dist/lib/platform-provider-prompt.d.ts.map +1 -1
- package/dist/lib/platform-provider-prompt.js +4 -0
- package/dist/lib/platform-provider-prompt.js.map +1 -1
- package/dist/lib/platform-release-manifest.d.ts +15 -1
- package/dist/lib/platform-release-manifest.d.ts.map +1 -1
- package/dist/lib/platform-release-manifest.js +24 -0
- package/dist/lib/platform-release-manifest.js.map +1 -1
- package/dist/lib/portability-shared.d.ts +49 -0
- package/dist/lib/portability-shared.d.ts.map +1 -0
- package/dist/lib/portability-shared.js +220 -0
- package/dist/lib/portability-shared.js.map +1 -0
- package/dist/lib/project-mcp-config.d.ts +14 -0
- package/dist/lib/project-mcp-config.d.ts.map +1 -0
- package/dist/lib/project-mcp-config.js +78 -0
- package/dist/lib/project-mcp-config.js.map +1 -0
- package/dist/lib/release-package-graph.d.ts +154 -0
- package/dist/lib/release-package-graph.d.ts.map +1 -0
- package/dist/lib/release-package-graph.js +249 -0
- package/dist/lib/release-package-graph.js.map +1 -0
- package/dist/lib/repo-binding.d.ts +7 -2
- package/dist/lib/repo-binding.d.ts.map +1 -1
- package/dist/lib/repo-binding.js +131 -18
- package/dist/lib/repo-binding.js.map +1 -1
- package/dist/lib/repo-command-support.d.ts +3 -1
- package/dist/lib/repo-command-support.d.ts.map +1 -1
- package/dist/lib/repo-command-support.js.map +1 -1
- package/dist/lib/repo-local-mcp-backend.d.ts +65 -0
- package/dist/lib/repo-local-mcp-backend.d.ts.map +1 -0
- package/dist/lib/repo-local-mcp-backend.js +288 -0
- package/dist/lib/repo-local-mcp-backend.js.map +1 -0
- package/dist/lib/repo-local-mcp-runtime.d.ts +17 -0
- package/dist/lib/repo-local-mcp-runtime.d.ts.map +1 -0
- package/dist/lib/repo-local-mcp-runtime.js +136 -0
- package/dist/lib/repo-local-mcp-runtime.js.map +1 -0
- package/dist/lib/repo-scope-migration.d.ts +4 -0
- package/dist/lib/repo-scope-migration.d.ts.map +1 -0
- package/dist/lib/repo-scope-migration.js +55 -0
- package/dist/lib/repo-scope-migration.js.map +1 -0
- package/dist/lib/repo-scope.d.ts +9 -0
- package/dist/lib/repo-scope.d.ts.map +1 -0
- package/dist/lib/repo-scope.js +15 -0
- package/dist/lib/repo-scope.js.map +1 -0
- package/dist/lib/safe-file.d.ts +141 -0
- package/dist/lib/safe-file.d.ts.map +1 -0
- package/dist/lib/safe-file.js +296 -0
- package/dist/lib/safe-file.js.map +1 -0
- package/dist/lib/selfhosted-lifecycle.d.ts +78 -0
- package/dist/lib/selfhosted-lifecycle.d.ts.map +1 -0
- package/dist/lib/selfhosted-lifecycle.js +195 -0
- package/dist/lib/selfhosted-lifecycle.js.map +1 -0
- package/dist/lib/setup-console.d.ts +1 -1
- package/dist/lib/setup-console.d.ts.map +1 -1
- package/dist/lib/setup-console.js +3 -1
- package/dist/lib/setup-console.js.map +1 -1
- package/dist/lib/setup-page.d.ts.map +1 -1
- package/dist/lib/setup-page.js +28 -10
- package/dist/lib/setup-page.js.map +1 -1
- package/dist/lib/setup-plan.d.ts +4 -1
- package/dist/lib/setup-plan.d.ts.map +1 -1
- package/dist/lib/setup-plan.js +10 -2
- package/dist/lib/setup-plan.js.map +1 -1
- package/dist/lib/setup-server.d.ts.map +1 -1
- package/dist/lib/setup-server.js +19 -3
- package/dist/lib/setup-server.js.map +1 -1
- package/dist/lib/sso-login.d.ts +42 -0
- package/dist/lib/sso-login.d.ts.map +1 -0
- package/dist/lib/sso-login.js +135 -0
- package/dist/lib/sso-login.js.map +1 -0
- package/dist/lib/transfer.d.ts +80 -0
- package/dist/lib/transfer.d.ts.map +1 -0
- package/dist/lib/transfer.js +173 -0
- package/dist/lib/transfer.js.map +1 -0
- package/dist/lib/tui.d.ts +0 -6
- package/dist/lib/tui.d.ts.map +1 -1
- package/dist/lib/tui.js +6 -1
- package/dist/lib/tui.js.map +1 -1
- package/dist/lib/ui.js +1 -1
- package/dist/lib/ui.js.map +1 -1
- package/dist/lib/up-result.d.ts +46 -0
- package/dist/lib/up-result.d.ts.map +1 -0
- package/dist/lib/up-result.js +25 -0
- package/dist/lib/up-result.js.map +1 -0
- package/dist/menu/run.d.ts +7 -0
- package/dist/menu/run.d.ts.map +1 -1
- package/dist/menu/run.js +38 -2
- package/dist/menu/run.js.map +1 -1
- package/oclif.manifest.json +3585 -1532
- package/package.json +19 -13
|
@@ -4,13 +4,17 @@ import { registerSecret, getPlatformDefaultProvider, setPlatformDefaultProvider,
|
|
|
4
4
|
import { applyPlatform, resolvePackagedAssetsDir, } from './platform-lifecycle.js';
|
|
5
5
|
import { parseEnv, redactPlatformSecrets, } from './platform-runtime.js';
|
|
6
6
|
import { resolveProviderSelection, } from './platform-provider-prompt.js';
|
|
7
|
-
import { acquireGhcrLogin, resolveImageSource } from './platform-image-source.js';
|
|
7
|
+
import { acquireGhcrLogin, detectRepoCheckout, resolveImageSource } from './platform-image-source.js';
|
|
8
|
+
import { resolveEditionIntent, shouldUseSelfHostedEdition } from './platform-edition.js';
|
|
9
|
+
import { STABLE_SELFHOSTED_RELEASE, applySelfHosted, resolvePackagedSelfHostedAssetsDir, selfHostedToPlatformResult, } from './selfhosted-lifecycle.js';
|
|
8
10
|
import { runOnboarding, runOnboardingProviderProbe, waitForOnboardingReady, DEFAULT_LOCAL_PROFILE, } from './platform-onboarding.js';
|
|
9
11
|
import { ensureEngineReady as ensureContainerEngineReady, } from './container-engine.js';
|
|
10
12
|
import { withSpinner } from './ui.js';
|
|
11
13
|
import { buildRegistryLoginInvocation } from './platform-image-source.js';
|
|
12
|
-
import { parsePlatformReleaseManifest, PlatformReleaseCatalogHttpError, resolvePlatformRelease, SelfServeResolutionError, } from './platform-release-manifest.js';
|
|
14
|
+
import { parsePlatformReleaseManifest, PlatformReleaseCatalogHttpError, releaseFreshnessNotice, resolvePlatformRelease, SelfServeResolutionError, } from './platform-release-manifest.js';
|
|
13
15
|
import { normalizeMothershipOrigin, } from './activate.js';
|
|
16
|
+
import { AGE_ELIGIBILITY_TEXT, AGE_ELIGIBILITY_UNDER_13_MESSAGE } from './login.js';
|
|
17
|
+
import { KnowzError, ExitCode } from '@knowzai/core';
|
|
14
18
|
/**
|
|
15
19
|
* `knowz up` front-door orchestration — the opinionated one-command onboarding
|
|
16
20
|
* that composes the AI-provider picker (N1) → image-source resolution (N2) →
|
|
@@ -26,9 +30,28 @@ import { normalizeMothershipOrigin, } from './activate.js';
|
|
|
26
30
|
* `platform up` (which fails closed without `--version`), `knowz up` supplies a
|
|
27
31
|
* concrete, deliberately-bumped version so a first-time user gets a working
|
|
28
32
|
* stack — NEVER a floating tag like `latest`. Override with `--version`.
|
|
33
|
+
*
|
|
34
|
+
* §2026-08-31 R3: this pin MUST equal the newest entry in the packaged
|
|
35
|
+
* `assets/portable/releases.json` (exact semver equality — enforced by the
|
|
36
|
+
* up.test.ts anti-rot tripwire). The /release-platform skill bumps BOTH in the
|
|
37
|
+
* same release commit; bump one without the other and the tripwire goes red.
|
|
29
38
|
*/
|
|
30
|
-
export const STABLE_PORTABLE_RELEASE = '0.
|
|
39
|
+
export const STABLE_PORTABLE_RELEASE = '0.41.0';
|
|
31
40
|
export const DEFAULT_PORTABLE_VERSION = STABLE_PORTABLE_RELEASE;
|
|
41
|
+
const DEFAULT_INSTANCE_NAME = 'knowz';
|
|
42
|
+
/**
|
|
43
|
+
* Per-instance CLI profile derivation (smoke gap 1, lead ruling): the default
|
|
44
|
+
* instance keeps the back-compat `local` profile; a named instance gets
|
|
45
|
+
* `local-<name>` so a second instance's `up` can never silently repoint the
|
|
46
|
+
* first instance's profile. Shared by terminal `up` and the setup console
|
|
47
|
+
* (`setupPlanToFrontDoorInput`) so both front-ends derive identically.
|
|
48
|
+
*/
|
|
49
|
+
export function localProfileNameFor(instanceName) {
|
|
50
|
+
const name = instanceName?.trim();
|
|
51
|
+
return !name || name === DEFAULT_INSTANCE_NAME
|
|
52
|
+
? DEFAULT_LOCAL_PROFILE
|
|
53
|
+
: `${DEFAULT_LOCAL_PROFILE}-${name}`;
|
|
54
|
+
}
|
|
32
55
|
export function resolveDefaultPortableVersion(env) {
|
|
33
56
|
const value = env.KNOWZ_PLATFORM_VERSION?.trim();
|
|
34
57
|
if (!value)
|
|
@@ -72,6 +95,31 @@ function e5() {
|
|
|
72
95
|
function activationRequired() {
|
|
73
96
|
return new SelfServeResolutionError("This device is not linked to a Knowz account. Run 'knowz activate' in an interactive terminal, then retry 'knowz up --json'.", 'ACTIVATION_REQUIRED');
|
|
74
97
|
}
|
|
98
|
+
const LICENSE_REQUIRED_FALLBACK = 'This installation does not have an active platform license. Complete registration and your commercial agreement to enable image pulls.';
|
|
99
|
+
const LICENSE_REQUIRED_REMEDIATION = 'Request a portable license from Settings → Installations on your Knowz account, or see https://knowz.io/pricing.';
|
|
100
|
+
const PROBLEM_DETAIL_MAX_LENGTH = 500;
|
|
101
|
+
function licenseRequiredError(preflight) {
|
|
102
|
+
const detail = sanitizeProblemDetail(preflight.detail);
|
|
103
|
+
return new SelfServeResolutionError(`${detail ?? LICENSE_REQUIRED_FALLBACK} ${LICENSE_REQUIRED_REMEDIATION}`, 'LICENSE_REQUIRED');
|
|
104
|
+
}
|
|
105
|
+
function sanitizeProblemDetail(detail) {
|
|
106
|
+
if (typeof detail !== 'string' || detail.length === 0)
|
|
107
|
+
return undefined;
|
|
108
|
+
const stripped = stripC0AndCsi(detail).trim();
|
|
109
|
+
if (!stripped)
|
|
110
|
+
return undefined;
|
|
111
|
+
return stripped.length > PROBLEM_DETAIL_MAX_LENGTH
|
|
112
|
+
? stripped.slice(0, PROBLEM_DETAIL_MAX_LENGTH)
|
|
113
|
+
: stripped;
|
|
114
|
+
}
|
|
115
|
+
function stripC0AndCsi(value) {
|
|
116
|
+
return value
|
|
117
|
+
.replace(/\u001b\[[0-9;?]*[ -/]*[@-~]/g, '')
|
|
118
|
+
.replace(/\u009b[0-9;?]*[ -/]*[@-~]/g, '')
|
|
119
|
+
.replace(/\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)/g, '')
|
|
120
|
+
.replace(/\u001b[@-Z\\-_]/g, '')
|
|
121
|
+
.replace(/[\u0000-\u001f\u007f-\u009f]/g, '');
|
|
122
|
+
}
|
|
75
123
|
async function defaultFetchReleaseManifest(url) {
|
|
76
124
|
const response = await fetch(url, {
|
|
77
125
|
headers: { accept: 'application/json' },
|
|
@@ -81,6 +129,63 @@ async function defaultFetchReleaseManifest(url) {
|
|
|
81
129
|
throw new PlatformReleaseCatalogHttpError(response.status);
|
|
82
130
|
return response.json();
|
|
83
131
|
}
|
|
132
|
+
/** §2026-08-31 R4 (lead ruling): the advisory fetch is bounded to 2s — never slower. */
|
|
133
|
+
const ADVISORY_MANIFEST_TIMEOUT_MS = 2_000;
|
|
134
|
+
async function withAdvisoryTimeout(work) {
|
|
135
|
+
let timer;
|
|
136
|
+
try {
|
|
137
|
+
return await Promise.race([
|
|
138
|
+
work,
|
|
139
|
+
new Promise((_, reject) => {
|
|
140
|
+
timer = setTimeout(() => reject(new Error('Advisory release-manifest fetch timed out.')), ADVISORY_MANIFEST_TIMEOUT_MS);
|
|
141
|
+
}),
|
|
142
|
+
]);
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
if (timer !== undefined)
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* §2026-08-31 R4: ADVISORY manifest load for the ghcr-token / preloaded paths —
|
|
151
|
+
* bounded fetch, packaged-copy fallback, and ANY failure returns undefined.
|
|
152
|
+
* Freshness must never block, slow (beyond the bound), or error an air-gapped
|
|
153
|
+
* boot. Requires the injected `fetchReleaseManifest` (the real runtime always
|
|
154
|
+
* binds it); when absent the advisory silently does not run, keeping legacy
|
|
155
|
+
* injected embedders/tests byte-identical and network-free.
|
|
156
|
+
*/
|
|
157
|
+
async function loadAdvisoryReleaseManifest(input) {
|
|
158
|
+
try {
|
|
159
|
+
const raw = await withAdvisoryTimeout(input.fetchReleaseManifest(input.manifestUrl));
|
|
160
|
+
return parsePlatformReleaseManifest(raw);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// Fall through to the packaged copy — advisory failures are silent by contract.
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const fallback = input.loadPackagedReleaseManifest
|
|
167
|
+
? await input.loadPackagedReleaseManifest(input.packagedManifestPath)
|
|
168
|
+
: JSON.parse(readFileSync(input.packagedManifestPath, 'utf8'));
|
|
169
|
+
return parsePlatformReleaseManifest(fallback);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* §2026-08-31 R-N2: static reference-only next-steps epilogue after a fresh
|
|
177
|
+
* successful `knowz up`. Copy mirrors the setup-console success panel (R-N1);
|
|
178
|
+
* the commands are defined by CLI_PortabilityTransfer / CLI_InstanceTransfer.
|
|
179
|
+
* Routed through the injectable sink — `--json` runs and the setup console
|
|
180
|
+
* (which forces `input.json`) never see these lines, and `loginMode:'existing'`
|
|
181
|
+
* re-ups skip the call entirely.
|
|
182
|
+
*/
|
|
183
|
+
function emitNextSteps(log) {
|
|
184
|
+
log('Next steps:');
|
|
185
|
+
log(' Connect this instance to Knowz Cloud: knowz login --profile cloud');
|
|
186
|
+
log(' Move data between instances: knowz transfer --from <profile> --to <profile>');
|
|
187
|
+
log(' Snapshot / restore: knowz export / knowz import');
|
|
188
|
+
}
|
|
84
189
|
export async function runFrontDoor(input, deps) {
|
|
85
190
|
const log = input.json
|
|
86
191
|
? (_line) => { }
|
|
@@ -142,14 +247,29 @@ export async function runFrontDoor(input, deps) {
|
|
|
142
247
|
if (requestedSuperAdminPassphrase)
|
|
143
248
|
registerSecret(requestedSuperAdminPassphrase);
|
|
144
249
|
let identity = input.identity;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
250
|
+
const collectRegistrationIdentity = async () => {
|
|
251
|
+
if (identity?.ageAttested === true)
|
|
252
|
+
return identity;
|
|
253
|
+
if (!canPrompt) {
|
|
254
|
+
if (identity) {
|
|
255
|
+
throw new KnowzError('Age eligibility is never assumed. Pass --age-13-plus to confirm eligibility before registration.', ExitCode.Usage);
|
|
256
|
+
}
|
|
257
|
+
return identity;
|
|
258
|
+
}
|
|
259
|
+
const ageAttested = await deps.prompt.confirm?.({ message: AGE_ELIGIBILITY_TEXT, default: false }) ?? false;
|
|
260
|
+
if (!ageAttested)
|
|
261
|
+
throw new KnowzError(AGE_ELIGIBILITY_UNDER_13_MESSAGE, ExitCode.Usage);
|
|
262
|
+
const name = identity?.name ?? (await deps.prompt.text({ message: 'First account name:', default: 'Local' })).trim();
|
|
263
|
+
const email = identity?.email ?? (await deps.prompt.text({ message: 'First account email:', default: 'local@knowz.local' })).trim();
|
|
264
|
+
return {
|
|
149
265
|
name: name || 'Local',
|
|
150
266
|
email: email || 'local@knowz.local',
|
|
267
|
+
// `as const` so the literal is not widened to `boolean`: `identity` is
|
|
268
|
+
// typed `ageAttested?: true`, and attestation is deliberately a one-way
|
|
269
|
+
// flag — there is no "attested: false" state, only an absent one.
|
|
270
|
+
ageAttested: true,
|
|
151
271
|
};
|
|
152
|
-
}
|
|
272
|
+
};
|
|
153
273
|
// Discoverability: when a saved default was silently reused (no --offline/--ai/--provider,
|
|
154
274
|
// where --provider folds into providerFlags.ai), explain why no prompt appeared.
|
|
155
275
|
if (cfgDefault && !interactivePromptOccurred && !input.providerFlags.offline && !input.providerFlags.ai) {
|
|
@@ -164,23 +284,76 @@ export async function runFrontDoor(input, deps) {
|
|
|
164
284
|
axes: selection.axes ?? input.base.axes,
|
|
165
285
|
superAdminPassphrase: requestedSuperAdminPassphrase,
|
|
166
286
|
};
|
|
167
|
-
// 2)
|
|
168
|
-
// the
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
287
|
+
// 2) Edition then image source. Unentitled `knowz up` uses public selfhosted
|
|
288
|
+
// images; the portable resolver is unchanged when edition is portable.
|
|
289
|
+
const envForEdition = input.ghcrToken
|
|
290
|
+
? { ...deps.env, GHCR_PULL_TOKEN: input.ghcrToken }
|
|
291
|
+
: deps.env;
|
|
292
|
+
const editionIntent = resolveEditionIntent({
|
|
293
|
+
flags: { edition: input.edition },
|
|
294
|
+
env: envForEdition,
|
|
295
|
+
});
|
|
296
|
+
const checkoutDetected = Boolean(detectRepoCheckout(deps.cwd, deps.pathExists));
|
|
297
|
+
let useSelfHosted = shouldUseSelfHostedEdition({
|
|
298
|
+
intent: editionIntent,
|
|
299
|
+
imageFlags: input.imageFlags,
|
|
300
|
+
checkoutDetected,
|
|
178
301
|
});
|
|
302
|
+
// R-ED3: omitted edition + stored kzin_ may promote to portable after a 200
|
|
303
|
+
// preflight. 403/401/410/transport stay selfhosted and MUST NOT reactivate.
|
|
304
|
+
if (useSelfHosted &&
|
|
305
|
+
!editionIntent.explicit &&
|
|
306
|
+
deps.loadStoredActivation &&
|
|
307
|
+
deps.preflightRegistryCredential) {
|
|
308
|
+
const mothershipUrl = normalizeMothershipOrigin(deps.env.KNOWZ_LICENSING_MOTHERSHIP_URL?.trim() || DEFAULT_MOTHERSHIP_URL);
|
|
309
|
+
try {
|
|
310
|
+
const stored = await deps.loadStoredActivation({
|
|
311
|
+
projectName: input.base.name,
|
|
312
|
+
configDir: input.base.configDir,
|
|
313
|
+
engine: engine ?? LEGACY_DOCKER_ENGINE,
|
|
314
|
+
});
|
|
315
|
+
if (stored) {
|
|
316
|
+
const preflight = await deps.preflightRegistryCredential({
|
|
317
|
+
mothershipUrl,
|
|
318
|
+
activation: stored,
|
|
319
|
+
});
|
|
320
|
+
if (preflight.kind === 'http-response' && preflight.status === 200) {
|
|
321
|
+
useSelfHosted = false;
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
log('Stored installation is not entitled for portable images; using public selfhosted.');
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
// Default knowz up must not fail because a mothership probe threw.
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const source = useSelfHosted
|
|
333
|
+
? {
|
|
334
|
+
mode: 'pull',
|
|
335
|
+
composeFile: 'selfhosted',
|
|
336
|
+
projectDir: 'selfhosted',
|
|
337
|
+
composePlan: 'config-pull-up',
|
|
338
|
+
}
|
|
339
|
+
: resolveImageSource({
|
|
340
|
+
cwd: deps.cwd,
|
|
341
|
+
flags: input.imageFlags,
|
|
342
|
+
canPrompt: deps.isTty && Boolean(deps.ghcrPrompt),
|
|
343
|
+
pathExists: deps.pathExists,
|
|
344
|
+
packagedAssetsDir: deps.packagedAssetsDir,
|
|
345
|
+
env: envForEdition,
|
|
346
|
+
});
|
|
179
347
|
const seam = source.mode === 'build'
|
|
180
348
|
? { composeFile: source.composeFile, projectDir: source.projectDir, composePlan: source.composePlan }
|
|
181
349
|
: source.mode === 'pull'
|
|
182
|
-
? { composePlan: source.composePlan, registry: source.registry ?? null }
|
|
350
|
+
? { composePlan: source.composePlan, registry: 'registry' in source ? source.registry ?? null : null }
|
|
183
351
|
: { composePlan: source.composePlan };
|
|
352
|
+
// §2026-08-31 R7: portable images are linux/amd64-only. Selfhosted GHCR is multi-arch.
|
|
353
|
+
const hostArch = deps.hostArch ?? process.arch;
|
|
354
|
+
if (!useSelfHosted && hostArch === 'arm64' && (source.mode === 'pull' || source.mode === 'preloaded')) {
|
|
355
|
+
log('Note: knowz images run under amd64 emulation on this Mac; native arm64 images are not yet published.');
|
|
356
|
+
}
|
|
184
357
|
const selfServePlan = source.loginPlan?.kind === 'self-serve' ? source.loginPlan : undefined;
|
|
185
358
|
if (selfServePlan) {
|
|
186
359
|
const mothershipUrl = normalizeMothershipOrigin(deps.env.KNOWZ_LICENSING_MOTHERSHIP_URL?.trim() || DEFAULT_MOTHERSHIP_URL);
|
|
@@ -235,6 +408,41 @@ export async function runFrontDoor(input, deps) {
|
|
|
235
408
|
if (resolved.note)
|
|
236
409
|
log(resolved.note);
|
|
237
410
|
log(`✓ Knowz Platform ${resolved.release.version} (${flavor}) — released ${resolved.release.releasedAt.slice(0, 10)}`);
|
|
411
|
+
// §2026-08-31 R4 (self-serve): zero new network — reuse the fetched manifest.
|
|
412
|
+
// Fires only for an explicit older pin; a minCliVersion skip already emitted
|
|
413
|
+
// its own note above, and the freshness notice must never duplicate it.
|
|
414
|
+
if (!resolved.note) {
|
|
415
|
+
const freshness = releaseFreshnessNotice({
|
|
416
|
+
currentVersion: resolved.release.version,
|
|
417
|
+
manifest,
|
|
418
|
+
flavor,
|
|
419
|
+
});
|
|
420
|
+
if (freshness)
|
|
421
|
+
log(freshness);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
else if (selection.provider !== 'offline' &&
|
|
425
|
+
(source.mode === 'preloaded' || source.loginPlan?.kind === 'ghcr') &&
|
|
426
|
+
deps.fetchReleaseManifest) {
|
|
427
|
+
// §2026-08-31 R4 (ghcr-token / preloaded): no manifest resolution runs on these
|
|
428
|
+
// paths, so the version about to boot is the pin/explicit choice. Advisory-only
|
|
429
|
+
// freshness check — bounded, fail-silent, and skipped entirely for the offline
|
|
430
|
+
// provider (declared no-network intent, lead ruling on OQ-2).
|
|
431
|
+
const advisoryManifest = await loadAdvisoryReleaseManifest({
|
|
432
|
+
manifestUrl: `${normalizeMothershipOrigin(deps.env.KNOWZ_LICENSING_MOTHERSHIP_URL?.trim() || DEFAULT_MOTHERSHIP_URL)}${RELEASE_MANIFEST_PATH}`,
|
|
433
|
+
packagedManifestPath: join(source.projectDir, 'releases.json'),
|
|
434
|
+
fetchReleaseManifest: deps.fetchReleaseManifest,
|
|
435
|
+
loadPackagedReleaseManifest: deps.loadPackagedReleaseManifest,
|
|
436
|
+
});
|
|
437
|
+
if (advisoryManifest) {
|
|
438
|
+
const freshness = releaseFreshnessNotice({
|
|
439
|
+
currentVersion: applyInput.version ?? DEFAULT_PORTABLE_VERSION,
|
|
440
|
+
manifest: advisoryManifest,
|
|
441
|
+
flavor: selection.provider === 'gcp' ? 'portable-gcp' : 'portable',
|
|
442
|
+
});
|
|
443
|
+
if (freshness)
|
|
444
|
+
log(freshness);
|
|
445
|
+
}
|
|
238
446
|
}
|
|
239
447
|
// Advisory credential reachability check. Failure is intentionally warn-only.
|
|
240
448
|
if (input.validate === true && deps.probeProvider) {
|
|
@@ -275,123 +483,146 @@ export async function runFrontDoor(input, deps) {
|
|
|
275
483
|
};
|
|
276
484
|
// 3) Bring the stack up; anonymous pull first, authenticate + retry once on auth failure.
|
|
277
485
|
let applied;
|
|
278
|
-
if (
|
|
279
|
-
log(
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
486
|
+
if (useSelfHosted) {
|
|
487
|
+
log('Using public selfhosted images. Portable platform requires --edition=portable and an entitled key.');
|
|
488
|
+
const selfhostedVersion = input.versionExplicit && applyInput.version
|
|
489
|
+
? applyInput.version
|
|
490
|
+
: (deps.env.KNOWZ_SELFHOSTED_VERSION?.trim() || STABLE_SELFHOSTED_RELEASE);
|
|
491
|
+
const selfhosted = applySelfHosted({
|
|
492
|
+
name: input.base.name,
|
|
493
|
+
version: selfhostedVersion,
|
|
494
|
+
configDir: input.base.configDir,
|
|
495
|
+
ports,
|
|
496
|
+
}, {
|
|
497
|
+
runner: deps.runner,
|
|
498
|
+
randomBytes: deps.randomBytes,
|
|
499
|
+
packagedAssetsDir: deps.selfHostedAssetsDir ?? resolvePackagedSelfHostedAssetsDir(),
|
|
500
|
+
});
|
|
501
|
+
applied = selfHostedToPlatformResult(selfhosted, selection.provider, deps.now);
|
|
284
502
|
}
|
|
285
|
-
|
|
286
|
-
if (
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
const login = await acquireGhcrLogin(source.loginPlan, deps.ghcrPrompt, loginEnv);
|
|
293
|
-
if (!login)
|
|
294
|
-
throw error;
|
|
295
|
-
log('Registry rejected an anonymous pull; authenticating and retrying…');
|
|
296
|
-
applied = await (deps.applyPlatform ?? applyPlatform)(applyInput, applyDeps, { ...seam, login });
|
|
503
|
+
else {
|
|
504
|
+
if (selfServePlan)
|
|
505
|
+
log(`◇ Pulling images from ${selfServePlan.registry}…`);
|
|
506
|
+
try {
|
|
507
|
+
applied = await (deps.applyPlatform ?? applyPlatform)(applyInput, applyDeps, seam);
|
|
508
|
+
if (selfServePlan)
|
|
509
|
+
log(`◇ Pulling images from ${selfServePlan.registry}… ✓`);
|
|
297
510
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
511
|
+
catch (error) {
|
|
512
|
+
if (source.mode === 'pull' &&
|
|
513
|
+
source.loginPlan?.kind === 'ghcr' &&
|
|
514
|
+
isRegistryAuthError(error)) {
|
|
515
|
+
const loginEnv = input.ghcrToken
|
|
516
|
+
? { ...deps.env, GHCR_PULL_TOKEN: input.ghcrToken }
|
|
517
|
+
: deps.env;
|
|
518
|
+
const login = await acquireGhcrLogin(source.loginPlan, deps.ghcrPrompt, loginEnv);
|
|
519
|
+
if (!login)
|
|
520
|
+
throw error;
|
|
521
|
+
log('Registry rejected an anonymous pull; authenticating and retrying…');
|
|
522
|
+
applied = await (deps.applyPlatform ?? applyPlatform)(applyInput, applyDeps, { ...seam, login });
|
|
305
523
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (input.json)
|
|
314
|
-
throw activationRequired();
|
|
315
|
-
log("This device isn't linked to a Knowz account yet.");
|
|
316
|
-
log('Linking is free and takes about a minute — your browser will open so you can approve this device.');
|
|
317
|
-
log('');
|
|
318
|
-
try {
|
|
319
|
-
activation = await deps.activateInstallation({
|
|
320
|
-
projectName: input.base.name,
|
|
321
|
-
configDir: input.base.configDir,
|
|
322
|
-
mothershipUrl,
|
|
323
|
-
engine: activeEngine,
|
|
324
|
-
});
|
|
325
|
-
activatedNow = true;
|
|
524
|
+
else if (source.mode === 'pull' && selfServePlan && isRegistryAuthError(error)) {
|
|
525
|
+
const activeEngine = engine ?? LEGACY_DOCKER_ENGINE;
|
|
526
|
+
const mothershipUrl = normalizeMothershipOrigin(deps.env.KNOWZ_LICENSING_MOTHERSHIP_URL?.trim() || DEFAULT_MOTHERSHIP_URL);
|
|
527
|
+
if (!deps.loadStoredActivation ||
|
|
528
|
+
!deps.activateInstallation ||
|
|
529
|
+
!deps.preflightRegistryCredential) {
|
|
530
|
+
throw new Error('Self-serve registry authentication dependencies are not configured.');
|
|
326
531
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
engine: activeEngine,
|
|
352
|
-
});
|
|
353
|
-
activatedNow = true;
|
|
354
|
-
}
|
|
355
|
-
catch {
|
|
356
|
-
throw e5();
|
|
532
|
+
let activation = await deps.loadStoredActivation({
|
|
533
|
+
projectName: input.base.name,
|
|
534
|
+
configDir: input.base.configDir,
|
|
535
|
+
engine: activeEngine,
|
|
536
|
+
});
|
|
537
|
+
let activatedNow = false;
|
|
538
|
+
if (!activation) {
|
|
539
|
+
if (input.json)
|
|
540
|
+
throw activationRequired();
|
|
541
|
+
log("This device isn't linked to a Knowz account yet.");
|
|
542
|
+
log('Linking is free and takes about a minute — your browser will open so you can approve this device.');
|
|
543
|
+
log('');
|
|
544
|
+
try {
|
|
545
|
+
activation = await deps.activateInstallation({
|
|
546
|
+
projectName: input.base.name,
|
|
547
|
+
configDir: input.base.configDir,
|
|
548
|
+
mothershipUrl,
|
|
549
|
+
engine: activeEngine,
|
|
550
|
+
});
|
|
551
|
+
activatedNow = true;
|
|
552
|
+
}
|
|
553
|
+
catch {
|
|
554
|
+
throw e5();
|
|
555
|
+
}
|
|
357
556
|
}
|
|
358
|
-
preflight = await deps.preflightRegistryCredential({ mothershipUrl, activation });
|
|
557
|
+
let preflight = await deps.preflightRegistryCredential({ mothershipUrl, activation });
|
|
359
558
|
if (preflight.kind === 'transport-failure') {
|
|
360
559
|
throw new SelfServeResolutionError(`Could not reach the Knowz image authorization service at ${mothershipUrl}/api/v1/registry/token. ` +
|
|
361
560
|
'Check your network connection, then retry.', 'REGISTRY_AUTH_UNREACHABLE');
|
|
362
561
|
}
|
|
363
|
-
preflightStatus = preflight.status;
|
|
562
|
+
let preflightStatus = preflight.status;
|
|
563
|
+
if (preflightStatus === 403)
|
|
564
|
+
throw licenseRequiredError(preflight);
|
|
364
565
|
if (preflightStatus === 410)
|
|
365
566
|
throw e4(activation.installationId);
|
|
567
|
+
if (preflightStatus === 401) {
|
|
568
|
+
if (activatedNow || !canPrompt || !deps.confirmReactivation) {
|
|
569
|
+
throw new SelfServeResolutionError(`Stored installation ${activation.installationId} is no longer valid. Run 'knowz activate' to link this device again.`, 'INSTALLATION_INVALID');
|
|
570
|
+
}
|
|
571
|
+
const accepted = await deps.confirmReactivation(activation.installationId);
|
|
572
|
+
if (!accepted)
|
|
573
|
+
throw e5();
|
|
574
|
+
try {
|
|
575
|
+
activation = await deps.activateInstallation({
|
|
576
|
+
projectName: input.base.name,
|
|
577
|
+
configDir: input.base.configDir,
|
|
578
|
+
mothershipUrl,
|
|
579
|
+
engine: activeEngine,
|
|
580
|
+
});
|
|
581
|
+
activatedNow = true;
|
|
582
|
+
}
|
|
583
|
+
catch {
|
|
584
|
+
throw e5();
|
|
585
|
+
}
|
|
586
|
+
preflight = await deps.preflightRegistryCredential({ mothershipUrl, activation });
|
|
587
|
+
if (preflight.kind === 'transport-failure') {
|
|
588
|
+
throw new SelfServeResolutionError(`Could not reach the Knowz image authorization service at ${mothershipUrl}/api/v1/registry/token. ` +
|
|
589
|
+
'Check your network connection, then retry.', 'REGISTRY_AUTH_UNREACHABLE');
|
|
590
|
+
}
|
|
591
|
+
preflightStatus = preflight.status;
|
|
592
|
+
if (preflightStatus === 403)
|
|
593
|
+
throw licenseRequiredError(preflight);
|
|
594
|
+
if (preflightStatus === 410)
|
|
595
|
+
throw e4(activation.installationId);
|
|
596
|
+
}
|
|
597
|
+
if (preflightStatus !== 200) {
|
|
598
|
+
throw new SelfServeResolutionError(`Knowz could not authorize installation ${activation.installationId} for image pulls (HTTP ${preflightStatus}).`, 'INSTALLATION_INVALID');
|
|
599
|
+
}
|
|
600
|
+
registerSecret(activation.credential);
|
|
601
|
+
if (activatedNow)
|
|
602
|
+
log(`✓ Linked — installation "${input.base.name}"`);
|
|
603
|
+
const login = buildRegistryLoginInvocation(selfServePlan.registry, activation.installationId, activation.credential);
|
|
604
|
+
try {
|
|
605
|
+
applied = await (deps.applyPlatform ?? applyPlatform)(applyInput, applyDeps, {
|
|
606
|
+
...seam,
|
|
607
|
+
login,
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
catch (retryError) {
|
|
611
|
+
throw new SelfServeResolutionError('Knowz could not pull the published platform images after signing in. The container engine reported: ' +
|
|
612
|
+
redactPlatformSecrets(errorMessage(retryError), [activation.credential]), 'REGISTRY_PULL_FAILED');
|
|
613
|
+
}
|
|
614
|
+
log(`◇ Signing in to ${selfServePlan.registry}… ✓`);
|
|
615
|
+
log(`◇ Pulling images from ${selfServePlan.registry}… ✓`);
|
|
366
616
|
}
|
|
367
|
-
if (
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
log(`✓ Linked — installation "${input.base.name}"`);
|
|
373
|
-
const login = buildRegistryLoginInvocation(selfServePlan.registry, activation.installationId, activation.credential);
|
|
374
|
-
try {
|
|
375
|
-
applied = await (deps.applyPlatform ?? applyPlatform)(applyInput, applyDeps, {
|
|
376
|
-
...seam,
|
|
377
|
-
login,
|
|
378
|
-
});
|
|
617
|
+
else if (source.mode === 'pull' &&
|
|
618
|
+
source.registry &&
|
|
619
|
+
!source.loginPlan &&
|
|
620
|
+
isRegistryAuthError(error)) {
|
|
621
|
+
throw new Error(`Registry override ${source.registry} refused image access: ${errorMessage(error)}`);
|
|
379
622
|
}
|
|
380
|
-
|
|
381
|
-
throw
|
|
382
|
-
redactPlatformSecrets(errorMessage(retryError), [activation.credential]), 'REGISTRY_PULL_FAILED');
|
|
623
|
+
else {
|
|
624
|
+
throw error;
|
|
383
625
|
}
|
|
384
|
-
log(`◇ Signing in to ${selfServePlan.registry}… ✓`);
|
|
385
|
-
log(`◇ Pulling images from ${selfServePlan.registry}… ✓`);
|
|
386
|
-
}
|
|
387
|
-
else if (source.mode === 'pull' &&
|
|
388
|
-
source.registry &&
|
|
389
|
-
!source.loginPlan &&
|
|
390
|
-
isRegistryAuthError(error)) {
|
|
391
|
-
throw new Error(`Registry override ${source.registry} refused image access: ${errorMessage(error)}`);
|
|
392
|
-
}
|
|
393
|
-
else {
|
|
394
|
-
throw error;
|
|
395
626
|
}
|
|
396
627
|
}
|
|
397
628
|
for (const line of applied.output.split('\n'))
|
|
@@ -421,7 +652,9 @@ export async function runFrontDoor(input, deps) {
|
|
|
421
652
|
// profile reuse. Passing the result into onboarding avoids a second poll.
|
|
422
653
|
const apiReady = await waitForOnboardingReady({}, onboardingDeps);
|
|
423
654
|
if (!apiReady) {
|
|
424
|
-
|
|
655
|
+
identity = await collectRegistrationIdentity();
|
|
656
|
+
const onboarding = await runOnboarding({ ...onboardingInput, register: identity, apiReady }, onboardingDeps);
|
|
657
|
+
emitNextSteps(log);
|
|
425
658
|
return {
|
|
426
659
|
state: applied.state,
|
|
427
660
|
imageMode: source.mode,
|
|
@@ -429,6 +662,7 @@ export async function runFrontDoor(input, deps) {
|
|
|
429
662
|
profile: onboarding.profile ?? null,
|
|
430
663
|
loginMode: onboarding.loginMode,
|
|
431
664
|
seeded: onboarding.seeded,
|
|
665
|
+
edition: useSelfHosted ? 'selfhosted' : 'portable',
|
|
432
666
|
};
|
|
433
667
|
}
|
|
434
668
|
// 4b) If a prior `up` already signed the CLI profile in and its key still authenticates,
|
|
@@ -442,10 +676,12 @@ export async function runFrontDoor(input, deps) {
|
|
|
442
676
|
log(` API: ${apiUrl}`);
|
|
443
677
|
if (input.open)
|
|
444
678
|
onboardingDeps.openBrowser(webUrl);
|
|
445
|
-
return { state: applied.state, imageMode: source.mode, provider: selection.provider, profile: profileName, loginMode: 'existing', seeded: false };
|
|
679
|
+
return { state: applied.state, imageMode: source.mode, provider: selection.provider, profile: profileName, loginMode: 'existing', seeded: false, edition: useSelfHosted ? 'selfhosted' : 'portable' };
|
|
446
680
|
}
|
|
447
681
|
// 4c) Onboarding: bootstrap → register fallback → manual degrade.
|
|
448
|
-
|
|
682
|
+
identity = await collectRegistrationIdentity();
|
|
683
|
+
const onboarding = await runOnboarding({ ...onboardingInput, register: identity, apiReady }, onboardingDeps);
|
|
684
|
+
emitNextSteps(log);
|
|
449
685
|
return {
|
|
450
686
|
state: applied.state,
|
|
451
687
|
imageMode: source.mode,
|
|
@@ -453,6 +689,7 @@ export async function runFrontDoor(input, deps) {
|
|
|
453
689
|
profile: onboarding.profile ?? null,
|
|
454
690
|
loginMode: onboarding.loginMode,
|
|
455
691
|
seeded: onboarding.seeded,
|
|
692
|
+
edition: useSelfHosted ? 'selfhosted' : 'portable',
|
|
456
693
|
};
|
|
457
694
|
}
|
|
458
695
|
/** Read the packaged runtime contract's `providerPresets.{preset}.requiredEnvironment` map (drift-fenced source). */
|