@knowzai/cli 0.1.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/LICENSE +21 -0
- package/assets/portable/.env.example +250 -0
- package/assets/portable/docker-compose.yml +444 -0
- package/assets/portable/postgres-initdb/00-databases-and-extensions.sql +16 -0
- package/assets/portable/releases.json +37 -0
- package/assets/portable/runtime-contract.json +149 -0
- package/bin/run.js +4 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/base-command.d.ts +47 -0
- package/dist/base-command.d.ts.map +1 -0
- package/dist/base-command.js +98 -0
- package/dist/base-command.js.map +1 -0
- package/dist/commands/activate.d.ts +39 -0
- package/dist/commands/activate.d.ts.map +1 -0
- package/dist/commands/activate.js +103 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/ask.d.ts +14 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +33 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/auth/status.d.ts +7 -0
- package/dist/commands/auth/status.d.ts.map +1 -0
- package/dist/commands/auth/status.js +26 -0
- package/dist/commands/auth/status.js.map +1 -0
- package/dist/commands/backup.d.ts +15 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +52 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/capture/observe.d.ts +23 -0
- package/dist/commands/capture/observe.d.ts.map +1 -0
- package/dist/commands/capture/observe.js +68 -0
- package/dist/commands/capture/observe.js.map +1 -0
- package/dist/commands/capture/seal.d.ts +27 -0
- package/dist/commands/capture/seal.d.ts.map +1 -0
- package/dist/commands/capture/seal.js +144 -0
- package/dist/commands/capture/seal.js.map +1 -0
- package/dist/commands/capture/status.d.ts +33 -0
- package/dist/commands/capture/status.d.ts.map +1 -0
- package/dist/commands/capture/status.js +52 -0
- package/dist/commands/capture/status.js.map +1 -0
- package/dist/commands/chat.d.ts +21 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +142 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/cmek/decrypt.d.ts +13 -0
- package/dist/commands/cmek/decrypt.d.ts.map +1 -0
- package/dist/commands/cmek/decrypt.js +25 -0
- package/dist/commands/cmek/decrypt.js.map +1 -0
- package/dist/commands/cmek/encrypt.d.ts +15 -0
- package/dist/commands/cmek/encrypt.d.ts.map +1 -0
- package/dist/commands/cmek/encrypt.js +26 -0
- package/dist/commands/cmek/encrypt.js.map +1 -0
- package/dist/commands/cmek/init.d.ts +13 -0
- package/dist/commands/cmek/init.d.ts.map +1 -0
- package/dist/commands/cmek/init.js +27 -0
- package/dist/commands/cmek/init.js.map +1 -0
- package/dist/commands/cmek/status.d.ts +11 -0
- package/dist/commands/cmek/status.d.ts.map +1 -0
- package/dist/commands/cmek/status.js +23 -0
- package/dist/commands/cmek/status.js.map +1 -0
- package/dist/commands/completion.d.ts +13 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +19 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/config/get.d.ts +13 -0
- package/dist/commands/config/get.d.ts.map +1 -0
- package/dist/commands/config/get.js +28 -0
- package/dist/commands/config/get.js.map +1 -0
- package/dist/commands/config/list.d.ts +7 -0
- package/dist/commands/config/list.d.ts.map +1 -0
- package/dist/commands/config/list.js +28 -0
- package/dist/commands/config/list.js.map +1 -0
- package/dist/commands/config/path.d.ts +9 -0
- package/dist/commands/config/path.d.ts.map +1 -0
- package/dist/commands/config/path.js +15 -0
- package/dist/commands/config/path.js.map +1 -0
- package/dist/commands/config/set.d.ts +16 -0
- package/dist/commands/config/set.d.ts.map +1 -0
- package/dist/commands/config/set.js +36 -0
- package/dist/commands/config/set.js.map +1 -0
- package/dist/commands/doctor.d.ts +56 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +151 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/down.d.ts +30 -0
- package/dist/commands/down.d.ts.map +1 -0
- package/dist/commands/down.js +20 -0
- package/dist/commands/down.js.map +1 -0
- package/dist/commands/entities/find.d.ts +16 -0
- package/dist/commands/entities/find.d.ts.map +1 -0
- package/dist/commands/entities/find.js +27 -0
- package/dist/commands/entities/find.js.map +1 -0
- package/dist/commands/hooks/install.d.ts +19 -0
- package/dist/commands/hooks/install.d.ts.map +1 -0
- package/dist/commands/hooks/install.js +53 -0
- package/dist/commands/hooks/install.js.map +1 -0
- package/dist/commands/index/graph.d.ts +11 -0
- package/dist/commands/index/graph.d.ts.map +1 -0
- package/dist/commands/index/graph.js +31 -0
- package/dist/commands/index/graph.js.map +1 -0
- package/dist/commands/index/scan.d.ts +22 -0
- package/dist/commands/index/scan.d.ts.map +1 -0
- package/dist/commands/index/scan.js +48 -0
- package/dist/commands/index/scan.js.map +1 -0
- package/dist/commands/index/search.d.ts +18 -0
- package/dist/commands/index/search.d.ts.map +1 -0
- package/dist/commands/index/search.js +40 -0
- package/dist/commands/index/search.js.map +1 -0
- package/dist/commands/ingest/add.d.ts +15 -0
- package/dist/commands/ingest/add.d.ts.map +1 -0
- package/dist/commands/ingest/add.js +50 -0
- package/dist/commands/ingest/add.js.map +1 -0
- package/dist/commands/knowledge/amend.d.ts +19 -0
- package/dist/commands/knowledge/amend.d.ts.map +1 -0
- package/dist/commands/knowledge/amend.js +27 -0
- package/dist/commands/knowledge/amend.js.map +1 -0
- package/dist/commands/knowledge/comment.d.ts +16 -0
- package/dist/commands/knowledge/comment.d.ts.map +1 -0
- package/dist/commands/knowledge/comment.js +27 -0
- package/dist/commands/knowledge/comment.js.map +1 -0
- package/dist/commands/knowledge/comments.d.ts +11 -0
- package/dist/commands/knowledge/comments.d.ts.map +1 -0
- package/dist/commands/knowledge/comments.js +20 -0
- package/dist/commands/knowledge/comments.js.map +1 -0
- package/dist/commands/knowledge/create.d.ts +18 -0
- package/dist/commands/knowledge/create.d.ts.map +1 -0
- package/dist/commands/knowledge/create.js +45 -0
- package/dist/commands/knowledge/create.js.map +1 -0
- package/dist/commands/knowledge/delete.d.ts +14 -0
- package/dist/commands/knowledge/delete.d.ts.map +1 -0
- package/dist/commands/knowledge/delete.js +30 -0
- package/dist/commands/knowledge/delete.js.map +1 -0
- package/dist/commands/knowledge/get.d.ts +13 -0
- package/dist/commands/knowledge/get.d.ts.map +1 -0
- package/dist/commands/knowledge/get.js +20 -0
- package/dist/commands/knowledge/get.js.map +1 -0
- package/dist/commands/knowledge/list.d.ts +13 -0
- package/dist/commands/knowledge/list.d.ts.map +1 -0
- package/dist/commands/knowledge/list.js +31 -0
- package/dist/commands/knowledge/list.js.map +1 -0
- package/dist/commands/knowledge/status.d.ts +11 -0
- package/dist/commands/knowledge/status.d.ts.map +1 -0
- package/dist/commands/knowledge/status.js +23 -0
- package/dist/commands/knowledge/status.js.map +1 -0
- package/dist/commands/knowledge/update.d.ts +16 -0
- package/dist/commands/knowledge/update.d.ts.map +1 -0
- package/dist/commands/knowledge/update.js +32 -0
- package/dist/commands/knowledge/update.js.map +1 -0
- package/dist/commands/knowledge/versions.d.ts +11 -0
- package/dist/commands/knowledge/versions.d.ts.map +1 -0
- package/dist/commands/knowledge/versions.js +22 -0
- package/dist/commands/knowledge/versions.js.map +1 -0
- package/dist/commands/local/info.d.ts +17 -0
- package/dist/commands/local/info.d.ts.map +1 -0
- package/dist/commands/local/info.js +26 -0
- package/dist/commands/local/info.js.map +1 -0
- package/dist/commands/local/init.d.ts +16 -0
- package/dist/commands/local/init.d.ts.map +1 -0
- package/dist/commands/local/init.js +31 -0
- package/dist/commands/local/init.js.map +1 -0
- package/dist/commands/local/list.d.ts +13 -0
- package/dist/commands/local/list.d.ts.map +1 -0
- package/dist/commands/local/list.js +29 -0
- package/dist/commands/local/list.js.map +1 -0
- package/dist/commands/local/reset.d.ts +12 -0
- package/dist/commands/local/reset.d.ts.map +1 -0
- package/dist/commands/local/reset.js +34 -0
- package/dist/commands/local/reset.js.map +1 -0
- package/dist/commands/local/show.d.ts +15 -0
- package/dist/commands/local/show.d.ts.map +1 -0
- package/dist/commands/local/show.js +33 -0
- package/dist/commands/local/show.js.map +1 -0
- package/dist/commands/login.d.ts +23 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +139 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +11 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +23 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/menu.d.ts +10 -0
- package/dist/commands/menu.d.ts.map +1 -0
- package/dist/commands/menu.js +50 -0
- package/dist/commands/menu.js.map +1 -0
- package/dist/commands/pg/destroy.d.ts +13 -0
- package/dist/commands/pg/destroy.d.ts.map +1 -0
- package/dist/commands/pg/destroy.js +36 -0
- package/dist/commands/pg/destroy.js.map +1 -0
- package/dist/commands/pg/down.d.ts +12 -0
- package/dist/commands/pg/down.d.ts.map +1 -0
- package/dist/commands/pg/down.js +20 -0
- package/dist/commands/pg/down.js.map +1 -0
- package/dist/commands/pg/status.d.ts +13 -0
- package/dist/commands/pg/status.d.ts.map +1 -0
- package/dist/commands/pg/status.js +28 -0
- package/dist/commands/pg/status.js.map +1 -0
- package/dist/commands/pg/up.d.ts +13 -0
- package/dist/commands/pg/up.d.ts.map +1 -0
- package/dist/commands/pg/up.js +34 -0
- package/dist/commands/pg/up.js.map +1 -0
- package/dist/commands/platform/destroy.d.ts +18 -0
- package/dist/commands/platform/destroy.d.ts.map +1 -0
- package/dist/commands/platform/destroy.js +41 -0
- package/dist/commands/platform/destroy.js.map +1 -0
- package/dist/commands/platform/doctor.d.ts +11 -0
- package/dist/commands/platform/doctor.d.ts.map +1 -0
- package/dist/commands/platform/doctor.js +18 -0
- package/dist/commands/platform/doctor.js.map +1 -0
- package/dist/commands/platform/down.d.ts +26 -0
- package/dist/commands/platform/down.d.ts.map +1 -0
- package/dist/commands/platform/down.js +16 -0
- package/dist/commands/platform/down.js.map +1 -0
- package/dist/commands/platform/logs.d.ts +26 -0
- package/dist/commands/platform/logs.d.ts.map +1 -0
- package/dist/commands/platform/logs.js +24 -0
- package/dist/commands/platform/logs.js.map +1 -0
- package/dist/commands/platform/reset.d.ts +26 -0
- package/dist/commands/platform/reset.d.ts.map +1 -0
- package/dist/commands/platform/reset.js +49 -0
- package/dist/commands/platform/reset.js.map +1 -0
- package/dist/commands/platform/setup.d.ts +24 -0
- package/dist/commands/platform/setup.d.ts.map +1 -0
- package/dist/commands/platform/setup.js +21 -0
- package/dist/commands/platform/setup.js.map +1 -0
- package/dist/commands/platform/status.d.ts +28 -0
- package/dist/commands/platform/status.d.ts.map +1 -0
- package/dist/commands/platform/status.js +37 -0
- package/dist/commands/platform/status.js.map +1 -0
- package/dist/commands/platform/up.d.ts +42 -0
- package/dist/commands/platform/up.d.ts.map +1 -0
- package/dist/commands/platform/up.js +22 -0
- package/dist/commands/platform/up.js.map +1 -0
- package/dist/commands/platform/upgrade.d.ts +14 -0
- package/dist/commands/platform/upgrade.d.ts.map +1 -0
- package/dist/commands/platform/upgrade.js +22 -0
- package/dist/commands/platform/upgrade.js.map +1 -0
- package/dist/commands/profile/add.d.ts +18 -0
- package/dist/commands/profile/add.d.ts.map +1 -0
- package/dist/commands/profile/add.js +26 -0
- package/dist/commands/profile/add.js.map +1 -0
- package/dist/commands/profile/list.d.ts +10 -0
- package/dist/commands/profile/list.d.ts.map +1 -0
- package/dist/commands/profile/list.js +20 -0
- package/dist/commands/profile/list.js.map +1 -0
- package/dist/commands/profile/remove.d.ts +15 -0
- package/dist/commands/profile/remove.d.ts.map +1 -0
- package/dist/commands/profile/remove.js +19 -0
- package/dist/commands/profile/remove.js.map +1 -0
- package/dist/commands/profile/use.d.ts +12 -0
- package/dist/commands/profile/use.d.ts.map +1 -0
- package/dist/commands/profile/use.js +18 -0
- package/dist/commands/profile/use.js.map +1 -0
- package/dist/commands/recall.d.ts +29 -0
- package/dist/commands/recall.d.ts.map +1 -0
- package/dist/commands/recall.js +94 -0
- package/dist/commands/recall.js.map +1 -0
- package/dist/commands/repo/context.d.ts +24 -0
- package/dist/commands/repo/context.d.ts.map +1 -0
- package/dist/commands/repo/context.js +52 -0
- package/dist/commands/repo/context.js.map +1 -0
- package/dist/commands/repo/graph.d.ts +24 -0
- package/dist/commands/repo/graph.d.ts.map +1 -0
- package/dist/commands/repo/graph.js +72 -0
- package/dist/commands/repo/graph.js.map +1 -0
- package/dist/commands/repo/index/index.d.ts +28 -0
- package/dist/commands/repo/index/index.d.ts.map +1 -0
- package/dist/commands/repo/index/index.js +76 -0
- package/dist/commands/repo/index/index.js.map +1 -0
- package/dist/commands/repo/search.d.ts +22 -0
- package/dist/commands/repo/search.d.ts.map +1 -0
- package/dist/commands/repo/search.js +50 -0
- package/dist/commands/repo/search.js.map +1 -0
- package/dist/commands/repo/setup.d.ts +41 -0
- package/dist/commands/repo/setup.d.ts.map +1 -0
- package/dist/commands/repo/setup.js +144 -0
- package/dist/commands/repo/setup.js.map +1 -0
- package/dist/commands/repo/status.d.ts +31 -0
- package/dist/commands/repo/status.d.ts.map +1 -0
- package/dist/commands/repo/status.js +60 -0
- package/dist/commands/repo/status.js.map +1 -0
- package/dist/commands/restore.d.ts +16 -0
- package/dist/commands/restore.d.ts.map +1 -0
- package/dist/commands/restore.js +53 -0
- package/dist/commands/restore.js.map +1 -0
- package/dist/commands/search.d.ts +14 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +32 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/setup.d.ts +24 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +21 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/stats.d.ts +6 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +16 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/status.d.ts +20 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +33 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync/conflicts.d.ts +14 -0
- package/dist/commands/sync/conflicts.d.ts.map +1 -0
- package/dist/commands/sync/conflicts.js +23 -0
- package/dist/commands/sync/conflicts.js.map +1 -0
- package/dist/commands/sync/pull.d.ts +13 -0
- package/dist/commands/sync/pull.d.ts.map +1 -0
- package/dist/commands/sync/pull.js +26 -0
- package/dist/commands/sync/pull.js.map +1 -0
- package/dist/commands/sync/push.d.ts +13 -0
- package/dist/commands/sync/push.d.ts.map +1 -0
- package/dist/commands/sync/push.js +26 -0
- package/dist/commands/sync/push.js.map +1 -0
- package/dist/commands/sync/recover.d.ts +16 -0
- package/dist/commands/sync/recover.d.ts.map +1 -0
- package/dist/commands/sync/recover.js +29 -0
- package/dist/commands/sync/recover.js.map +1 -0
- package/dist/commands/sync/resolve.d.ts +21 -0
- package/dist/commands/sync/resolve.d.ts.map +1 -0
- package/dist/commands/sync/resolve.js +38 -0
- package/dist/commands/sync/resolve.js.map +1 -0
- package/dist/commands/sync/run.d.ts +13 -0
- package/dist/commands/sync/run.d.ts.map +1 -0
- package/dist/commands/sync/run.js +26 -0
- package/dist/commands/sync/run.js.map +1 -0
- package/dist/commands/sync/status.d.ts +13 -0
- package/dist/commands/sync/status.d.ts.map +1 -0
- package/dist/commands/sync/status.js +28 -0
- package/dist/commands/sync/status.js.map +1 -0
- package/dist/commands/topics/list.d.ts +11 -0
- package/dist/commands/topics/list.d.ts.map +1 -0
- package/dist/commands/topics/list.js +20 -0
- package/dist/commands/topics/list.js.map +1 -0
- package/dist/commands/tui.d.ts +10 -0
- package/dist/commands/tui.d.ts.map +1 -0
- package/dist/commands/tui.js +124 -0
- package/dist/commands/tui.js.map +1 -0
- package/dist/commands/up.d.ts +108 -0
- package/dist/commands/up.d.ts.map +1 -0
- package/dist/commands/up.js +210 -0
- package/dist/commands/up.js.map +1 -0
- package/dist/commands/vault/contents.d.ts +14 -0
- package/dist/commands/vault/contents.d.ts.map +1 -0
- package/dist/commands/vault/contents.js +24 -0
- package/dist/commands/vault/contents.js.map +1 -0
- package/dist/commands/vault/create.d.ts +15 -0
- package/dist/commands/vault/create.d.ts.map +1 -0
- package/dist/commands/vault/create.js +26 -0
- package/dist/commands/vault/create.js.map +1 -0
- package/dist/commands/vault/get.d.ts +10 -0
- package/dist/commands/vault/get.d.ts.map +1 -0
- package/dist/commands/vault/get.js +25 -0
- package/dist/commands/vault/get.js.map +1 -0
- package/dist/commands/vault/list.d.ts +7 -0
- package/dist/commands/vault/list.d.ts.map +1 -0
- package/dist/commands/vault/list.js +17 -0
- package/dist/commands/vault/list.js.map +1 -0
- package/dist/commands/web.d.ts +14 -0
- package/dist/commands/web.d.ts.map +1 -0
- package/dist/commands/web.js +50 -0
- package/dist/commands/web.js.map +1 -0
- package/dist/commands/whoami.d.ts +7 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +24 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/hooks/init/launch-menu.d.ts +10 -0
- package/dist/hooks/init/launch-menu.d.ts.map +1 -0
- package/dist/hooks/init/launch-menu.js +11 -0
- package/dist/hooks/init/launch-menu.js.map +1 -0
- package/dist/lib/activate.d.ts +92 -0
- package/dist/lib/activate.d.ts.map +1 -0
- package/dist/lib/activate.js +292 -0
- package/dist/lib/activate.js.map +1 -0
- package/dist/lib/browser.d.ts +30 -0
- package/dist/lib/browser.d.ts.map +1 -0
- package/dist/lib/browser.js +45 -0
- package/dist/lib/browser.js.map +1 -0
- package/dist/lib/chat.d.ts +41 -0
- package/dist/lib/chat.d.ts.map +1 -0
- package/dist/lib/chat.js +63 -0
- package/dist/lib/chat.js.map +1 -0
- package/dist/lib/claude-hooks.d.ts +34 -0
- package/dist/lib/claude-hooks.d.ts.map +1 -0
- package/dist/lib/claude-hooks.js +85 -0
- package/dist/lib/claude-hooks.js.map +1 -0
- package/dist/lib/completion.d.ts +9 -0
- package/dist/lib/completion.d.ts.map +1 -0
- package/dist/lib/completion.js +57 -0
- package/dist/lib/completion.js.map +1 -0
- package/dist/lib/container-engine.d.ts +45 -0
- package/dist/lib/container-engine.d.ts.map +1 -0
- package/dist/lib/container-engine.js +348 -0
- package/dist/lib/container-engine.js.map +1 -0
- package/dist/lib/content.d.ts +9 -0
- package/dist/lib/content.d.ts.map +1 -0
- package/dist/lib/content.js +20 -0
- package/dist/lib/content.js.map +1 -0
- package/dist/lib/doctor-fixture.d.ts +8 -0
- package/dist/lib/doctor-fixture.d.ts.map +1 -0
- package/dist/lib/doctor-fixture.js +50 -0
- package/dist/lib/doctor-fixture.js.map +1 -0
- package/dist/lib/embedding-guard.d.ts +34 -0
- package/dist/lib/embedding-guard.d.ts.map +1 -0
- package/dist/lib/embedding-guard.js +50 -0
- package/dist/lib/embedding-guard.js.map +1 -0
- package/dist/lib/hook-io.d.ts +24 -0
- package/dist/lib/hook-io.d.ts.map +1 -0
- package/dist/lib/hook-io.js +73 -0
- package/dist/lib/hook-io.js.map +1 -0
- package/dist/lib/ingest.d.ts +24 -0
- package/dist/lib/ingest.d.ts.map +1 -0
- package/dist/lib/ingest.js +44 -0
- package/dist/lib/ingest.js.map +1 -0
- package/dist/lib/login.d.ts +40 -0
- package/dist/lib/login.d.ts.map +1 -0
- package/dist/lib/login.js +56 -0
- package/dist/lib/login.js.map +1 -0
- package/dist/lib/pending-captures.d.ts +25 -0
- package/dist/lib/pending-captures.d.ts.map +1 -0
- package/dist/lib/pending-captures.js +143 -0
- package/dist/lib/pending-captures.js.map +1 -0
- package/dist/lib/platform-backup.d.ts +110 -0
- package/dist/lib/platform-backup.d.ts.map +1 -0
- package/dist/lib/platform-backup.js +579 -0
- package/dist/lib/platform-backup.js.map +1 -0
- package/dist/lib/platform-command-shared.d.ts +132 -0
- package/dist/lib/platform-command-shared.d.ts.map +1 -0
- package/dist/lib/platform-command-shared.js +159 -0
- package/dist/lib/platform-command-shared.js.map +1 -0
- package/dist/lib/platform-frontdoor-runtime.d.ts +33 -0
- package/dist/lib/platform-frontdoor-runtime.d.ts.map +1 -0
- package/dist/lib/platform-frontdoor-runtime.js +285 -0
- package/dist/lib/platform-frontdoor-runtime.js.map +1 -0
- package/dist/lib/platform-frontdoor.d.ts +155 -0
- package/dist/lib/platform-frontdoor.d.ts.map +1 -0
- package/dist/lib/platform-frontdoor.js +467 -0
- package/dist/lib/platform-frontdoor.js.map +1 -0
- package/dist/lib/platform-image-source.d.ts +81 -0
- package/dist/lib/platform-image-source.d.ts.map +1 -0
- package/dist/lib/platform-image-source.js +143 -0
- package/dist/lib/platform-image-source.js.map +1 -0
- package/dist/lib/platform-lifecycle.d.ts +112 -0
- package/dist/lib/platform-lifecycle.d.ts.map +1 -0
- package/dist/lib/platform-lifecycle.js +725 -0
- package/dist/lib/platform-lifecycle.js.map +1 -0
- package/dist/lib/platform-onboarding.d.ts +128 -0
- package/dist/lib/platform-onboarding.d.ts.map +1 -0
- package/dist/lib/platform-onboarding.js +227 -0
- package/dist/lib/platform-onboarding.js.map +1 -0
- package/dist/lib/platform-preflight.d.ts +48 -0
- package/dist/lib/platform-preflight.d.ts.map +1 -0
- package/dist/lib/platform-preflight.js +90 -0
- package/dist/lib/platform-preflight.js.map +1 -0
- package/dist/lib/platform-profile-purge.d.ts +18 -0
- package/dist/lib/platform-profile-purge.d.ts.map +1 -0
- package/dist/lib/platform-profile-purge.js +26 -0
- package/dist/lib/platform-profile-purge.js.map +1 -0
- package/dist/lib/platform-provider-fields.d.ts +2 -0
- package/dist/lib/platform-provider-fields.d.ts.map +1 -0
- package/dist/lib/platform-provider-fields.js +2 -0
- package/dist/lib/platform-provider-fields.js.map +1 -0
- package/dist/lib/platform-provider-probe.d.ts +75 -0
- package/dist/lib/platform-provider-probe.d.ts.map +1 -0
- package/dist/lib/platform-provider-probe.js +781 -0
- package/dist/lib/platform-provider-probe.js.map +1 -0
- package/dist/lib/platform-provider-prompt.d.ts +118 -0
- package/dist/lib/platform-provider-prompt.d.ts.map +1 -0
- package/dist/lib/platform-provider-prompt.js +245 -0
- package/dist/lib/platform-provider-prompt.js.map +1 -0
- package/dist/lib/platform-release-manifest.d.ts +34 -0
- package/dist/lib/platform-release-manifest.d.ts.map +1 -0
- package/dist/lib/platform-release-manifest.js +100 -0
- package/dist/lib/platform-release-manifest.js.map +1 -0
- package/dist/lib/platform-runtime.d.ts +212 -0
- package/dist/lib/platform-runtime.d.ts.map +1 -0
- package/dist/lib/platform-runtime.js +866 -0
- package/dist/lib/platform-runtime.js.map +1 -0
- package/dist/lib/poll.d.ts +9 -0
- package/dist/lib/poll.d.ts.map +1 -0
- package/dist/lib/poll.js +18 -0
- package/dist/lib/poll.js.map +1 -0
- package/dist/lib/prompt.d.ts +7 -0
- package/dist/lib/prompt.d.ts.map +1 -0
- package/dist/lib/prompt.js +28 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/provider-presets.d.ts +108 -0
- package/dist/lib/provider-presets.d.ts.map +1 -0
- package/dist/lib/provider-presets.js +184 -0
- package/dist/lib/provider-presets.js.map +1 -0
- package/dist/lib/recall.d.ts +32 -0
- package/dist/lib/recall.d.ts.map +1 -0
- package/dist/lib/recall.js +69 -0
- package/dist/lib/recall.js.map +1 -0
- package/dist/lib/redact.d.ts +41 -0
- package/dist/lib/redact.d.ts.map +1 -0
- package/dist/lib/redact.js +130 -0
- package/dist/lib/redact.js.map +1 -0
- package/dist/lib/render.d.ts +55 -0
- package/dist/lib/render.d.ts.map +1 -0
- package/dist/lib/render.js +172 -0
- package/dist/lib/render.js.map +1 -0
- package/dist/lib/repo-binding.d.ts +53 -0
- package/dist/lib/repo-binding.d.ts.map +1 -0
- package/dist/lib/repo-binding.js +127 -0
- package/dist/lib/repo-binding.js.map +1 -0
- package/dist/lib/repo-command-support.d.ts +18 -0
- package/dist/lib/repo-command-support.d.ts.map +1 -0
- package/dist/lib/repo-command-support.js +54 -0
- package/dist/lib/repo-command-support.js.map +1 -0
- package/dist/lib/seal-core.d.ts +34 -0
- package/dist/lib/seal-core.d.ts.map +1 -0
- package/dist/lib/seal-core.js +154 -0
- package/dist/lib/seal-core.js.map +1 -0
- package/dist/lib/setup-console.d.ts +46 -0
- package/dist/lib/setup-console.d.ts.map +1 -0
- package/dist/lib/setup-console.js +191 -0
- package/dist/lib/setup-console.js.map +1 -0
- package/dist/lib/setup-page.d.ts +21 -0
- package/dist/lib/setup-page.d.ts.map +1 -0
- package/dist/lib/setup-page.js +656 -0
- package/dist/lib/setup-page.js.map +1 -0
- package/dist/lib/setup-plan.d.ts +52 -0
- package/dist/lib/setup-plan.d.ts.map +1 -0
- package/dist/lib/setup-plan.js +154 -0
- package/dist/lib/setup-plan.js.map +1 -0
- package/dist/lib/setup-server.d.ts +71 -0
- package/dist/lib/setup-server.d.ts.map +1 -0
- package/dist/lib/setup-server.js +936 -0
- package/dist/lib/setup-server.js.map +1 -0
- package/dist/lib/tui.d.ts +77 -0
- package/dist/lib/tui.d.ts.map +1 -0
- package/dist/lib/tui.js +126 -0
- package/dist/lib/tui.js.map +1 -0
- package/dist/lib/ui.d.ts +23 -0
- package/dist/lib/ui.d.ts.map +1 -0
- package/dist/lib/ui.js +100 -0
- package/dist/lib/ui.js.map +1 -0
- package/dist/lib/vault.d.ts +10 -0
- package/dist/lib/vault.d.ts.map +1 -0
- package/dist/lib/vault.js +18 -0
- package/dist/lib/vault.js.map +1 -0
- package/dist/menu/forms.d.ts +13 -0
- package/dist/menu/forms.d.ts.map +1 -0
- package/dist/menu/forms.js +45 -0
- package/dist/menu/forms.js.map +1 -0
- package/dist/menu/frontends.d.ts +32 -0
- package/dist/menu/frontends.d.ts.map +1 -0
- package/dist/menu/frontends.js +31 -0
- package/dist/menu/frontends.js.map +1 -0
- package/dist/menu/help.d.ts +11 -0
- package/dist/menu/help.d.ts.map +1 -0
- package/dist/menu/help.js +33 -0
- package/dist/menu/help.js.map +1 -0
- package/dist/menu/palette.d.ts +28 -0
- package/dist/menu/palette.d.ts.map +1 -0
- package/dist/menu/palette.js +57 -0
- package/dist/menu/palette.js.map +1 -0
- package/dist/menu/reducer.d.ts +19 -0
- package/dist/menu/reducer.d.ts.map +1 -0
- package/dist/menu/reducer.js +37 -0
- package/dist/menu/reducer.js.map +1 -0
- package/dist/menu/run.d.ts +34 -0
- package/dist/menu/run.d.ts.map +1 -0
- package/dist/menu/run.js +490 -0
- package/dist/menu/run.js.map +1 -0
- package/dist/menu/screens.d.ts +15 -0
- package/dist/menu/screens.d.ts.map +1 -0
- package/dist/menu/screens.js +251 -0
- package/dist/menu/screens.js.map +1 -0
- package/dist/menu/should-launch.d.ts +19 -0
- package/dist/menu/should-launch.d.ts.map +1 -0
- package/dist/menu/should-launch.js +22 -0
- package/dist/menu/should-launch.js.map +1 -0
- package/dist/menu/types.d.ts +95 -0
- package/dist/menu/types.d.ts.map +1 -0
- package/dist/menu/types.js +7 -0
- package/dist/menu/types.js.map +1 -0
- package/oclif.manifest.json +7995 -0
- package/package.json +133 -0
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { isIP } from 'node:net';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { buildPlatformEnvironment, buildPlatformPlan, composeFailureError, createPlatformState, executeComposeInvocations, executeComposeInvocationsAsync, nodeAsyncProcessRunner, nodeProcessRunner, parseEnv, planComposeInvocations, PLATFORM_PROVIDERS, PLATFORM_SECRET_KEYS, redactPlatformSecrets, renderEnv, resolvePlatformPaths, serializePlatformState, writePrivateFile, } from './platform-runtime.js';
|
|
6
|
+
import { engineCheckSlice, loginCommandFor, resolveEngineStatus, runEngineProbes, runEngineProbesAsync, } from './container-engine.js';
|
|
7
|
+
import { withSpinner } from './ui.js';
|
|
8
|
+
const AMBIENT_ENV_KEYS = [
|
|
9
|
+
'KNOWZ_VERSION',
|
|
10
|
+
'KNOWZ_PROVIDER',
|
|
11
|
+
'BIND_ADDRESS',
|
|
12
|
+
'PUBLIC_API_URL',
|
|
13
|
+
'PUBLIC_WEB_ORIGIN',
|
|
14
|
+
'PUBLIC_MCP_URL',
|
|
15
|
+
'PUBLIC_SITE_URL',
|
|
16
|
+
'KNOWZ_COMPONENTS',
|
|
17
|
+
'KNOWZ__CLOUDPROVIDER__AI',
|
|
18
|
+
'KNOWZ__CLOUDPROVIDER__DOCINTELLIGENCE',
|
|
19
|
+
'KNOWZ__CLOUDPROVIDER__VISION',
|
|
20
|
+
'KNOWZ__CLOUDPROVIDER__TRANSCRIPTION',
|
|
21
|
+
'API_PORT',
|
|
22
|
+
'WEB_PORT',
|
|
23
|
+
'MCP_PORT',
|
|
24
|
+
'PUBLIC_SITE_PORT',
|
|
25
|
+
'STORAGE_PROVIDER',
|
|
26
|
+
'AZURE_OPENAI_ENDPOINT',
|
|
27
|
+
'AZURE_OPENAI_API_KEY',
|
|
28
|
+
'GCLOUD_ADC_PATH',
|
|
29
|
+
'VERTEX__PROJECT',
|
|
30
|
+
'VERTEX__REGION',
|
|
31
|
+
'VERTEX__CHATMODEL',
|
|
32
|
+
'VERTEX__EMBEDDINGMODEL',
|
|
33
|
+
'VERTEX__EMBEDDINGDIMENSIONS',
|
|
34
|
+
'OPENAICOMPAT__ENDPOINT',
|
|
35
|
+
'OPENAICOMPAT__APIKEY',
|
|
36
|
+
'OPENAICOMPAT__CHATMODEL',
|
|
37
|
+
'OPENAICOMPAT__EMBEDDINGMODEL',
|
|
38
|
+
'OPENAICOMPAT__EMBEDDINGDIMENSIONS',
|
|
39
|
+
'EMBEDDING_DIMENSIONS',
|
|
40
|
+
];
|
|
41
|
+
function profilesForComponents(components) {
|
|
42
|
+
return [
|
|
43
|
+
...(components?.mcp === false ? [] : ['mcp']),
|
|
44
|
+
...(components?.publicSite === true ? ['public-site'] : []),
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
export function resolvePackagedAssetsDir(moduleUrl = import.meta.url) {
|
|
48
|
+
return fileURLToPath(new URL('../../assets/portable', moduleUrl));
|
|
49
|
+
}
|
|
50
|
+
function readTextIfPresent(path) {
|
|
51
|
+
return existsSync(path) ? readFileSync(path, 'utf8') : undefined;
|
|
52
|
+
}
|
|
53
|
+
function parseState(path) {
|
|
54
|
+
const contents = readTextIfPresent(path);
|
|
55
|
+
if (contents === undefined)
|
|
56
|
+
return undefined;
|
|
57
|
+
let state;
|
|
58
|
+
try {
|
|
59
|
+
state = JSON.parse(contents);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
throw new Error(`Platform state is invalid JSON: ${path}`);
|
|
63
|
+
}
|
|
64
|
+
if (typeof state !== 'object' ||
|
|
65
|
+
state === null ||
|
|
66
|
+
!('schemaVersion' in state) ||
|
|
67
|
+
state.schemaVersion !== 1 ||
|
|
68
|
+
!('name' in state) ||
|
|
69
|
+
typeof state.name !== 'string' ||
|
|
70
|
+
!('version' in state) ||
|
|
71
|
+
typeof state.version !== 'string' ||
|
|
72
|
+
!('provider' in state) ||
|
|
73
|
+
typeof state.provider !== 'string') {
|
|
74
|
+
throw new Error(`Platform state has an unsupported shape: ${path}`);
|
|
75
|
+
}
|
|
76
|
+
return state;
|
|
77
|
+
}
|
|
78
|
+
function requireInitialized(name, configDir) {
|
|
79
|
+
const paths = resolvePlatformPaths(name, configDir);
|
|
80
|
+
const state = parseState(paths.stateFile);
|
|
81
|
+
if (!state || !existsSync(paths.composeFile) || !existsSync(paths.envFile)) {
|
|
82
|
+
throw new Error(`Platform '${name}' is not initialized. Run \`knowz platform up\` first.`);
|
|
83
|
+
}
|
|
84
|
+
if (state.name !== name)
|
|
85
|
+
throw new Error(`Platform state name does not match '${name}'.`);
|
|
86
|
+
return { paths, state };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Best-effort state rebuilt from the rendered .env when state.json is missing/unreadable.
|
|
90
|
+
* Only the project name + compose file + env file are load-bearing for a Compose teardown;
|
|
91
|
+
* the rest is display metadata, so unknown fields degrade to defaults.
|
|
92
|
+
*/
|
|
93
|
+
function reconstructStateFromEnv(name, paths) {
|
|
94
|
+
const env = existsSync(paths.envFile) ? parseEnv(readFileSync(paths.envFile, 'utf8')) : {};
|
|
95
|
+
const provider = PLATFORM_PROVIDERS.includes(env.KNOWZ_PROVIDER ?? '')
|
|
96
|
+
? env.KNOWZ_PROVIDER
|
|
97
|
+
: 'offline';
|
|
98
|
+
return {
|
|
99
|
+
schemaVersion: 1,
|
|
100
|
+
name,
|
|
101
|
+
version: env.KNOWZ_VERSION ?? 'unknown',
|
|
102
|
+
provider,
|
|
103
|
+
storage: env.STORAGE_PROVIDER === 'FileSystem' ? 'filesystem' : 'minio',
|
|
104
|
+
imageFlavor: env.KNOWZ_FLAVOR === '-gcp' ? '-gcp' : '',
|
|
105
|
+
axes: { ai: undefined, docIntelligence: 'None', vision: 'None', transcription: 'None' },
|
|
106
|
+
ports: { api: 5000, web: 3000, mcp: 3001, publicSite: 3002 },
|
|
107
|
+
serviceUrls: {
|
|
108
|
+
api: env.PUBLIC_API_URL ?? '',
|
|
109
|
+
web: env.PUBLIC_WEB_ORIGIN ?? '',
|
|
110
|
+
mcp: env.PUBLIC_MCP_URL ?? '',
|
|
111
|
+
publicSite: env.PUBLIC_SITE_URL ?? '',
|
|
112
|
+
},
|
|
113
|
+
components: {
|
|
114
|
+
mcp: env.KNOWZ_COMPONENTS === undefined || env.KNOWZ_COMPONENTS.split(',').includes('mcp'),
|
|
115
|
+
publicSite: env.KNOWZ_COMPONENTS?.split(',').includes('public-site') ?? false,
|
|
116
|
+
},
|
|
117
|
+
updatedAt: new Date().toISOString(),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Teardown-tolerant resolver for `down`/`destroy`. A failed or partial `up` can leave the
|
|
122
|
+
* containers running with an absent/corrupt state.json; as long as the compose file + env
|
|
123
|
+
* exist we still let the CLI stop them (reconciling a minimal state from disk) rather than
|
|
124
|
+
* refusing with "not initialized" and forcing the user to raw docker.
|
|
125
|
+
*/
|
|
126
|
+
function resolveTeardownTarget(name, configDir) {
|
|
127
|
+
const paths = resolvePlatformPaths(name, configDir);
|
|
128
|
+
if (!existsSync(paths.composeFile) || !existsSync(paths.envFile)) {
|
|
129
|
+
throw new Error(`Platform '${name}' is not initialized. Run \`knowz platform up\` first.`);
|
|
130
|
+
}
|
|
131
|
+
let state;
|
|
132
|
+
try {
|
|
133
|
+
state = parseState(paths.stateFile);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
state = undefined; // corrupt state.json — reconcile from the env instead of blocking teardown
|
|
137
|
+
}
|
|
138
|
+
if (state && state.name !== name)
|
|
139
|
+
throw new Error(`Platform state name does not match '${name}'.`);
|
|
140
|
+
return { paths, state: state ?? reconstructStateFromEnv(name, paths) };
|
|
141
|
+
}
|
|
142
|
+
function pickAmbientEnvironment(ambient) {
|
|
143
|
+
const selected = {};
|
|
144
|
+
for (const key of AMBIENT_ENV_KEYS) {
|
|
145
|
+
const value = ambient[key];
|
|
146
|
+
if (value !== undefined)
|
|
147
|
+
selected[key] = value;
|
|
148
|
+
}
|
|
149
|
+
return selected;
|
|
150
|
+
}
|
|
151
|
+
function integerFromEnvironment(value, label) {
|
|
152
|
+
if (value === undefined || value.trim() === '')
|
|
153
|
+
return undefined;
|
|
154
|
+
const parsed = Number(value);
|
|
155
|
+
if (!Number.isInteger(parsed))
|
|
156
|
+
throw new Error(`Invalid ${label}: expected an integer.`);
|
|
157
|
+
return parsed;
|
|
158
|
+
}
|
|
159
|
+
function axisFromEnvironment(value) {
|
|
160
|
+
return value;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* A persisted public URL is only reused across reruns when it's an explicit REMOTE URL
|
|
164
|
+
* (custom host). A loopback URL (`http://localhost:<port>`) is derived from the port, so drop
|
|
165
|
+
* it here and let it re-derive from the CURRENT port — otherwise a `--*-port` change on a
|
|
166
|
+
* re-up would keep announcing the stale old-port URL in the banner / `--open` / "sign in at"
|
|
167
|
+
* (NEW-MED). Malformed values are dropped so a bad persisted value can't poison the plan.
|
|
168
|
+
*/
|
|
169
|
+
function preservedPublicUrl(value) {
|
|
170
|
+
if (value === undefined || value.trim() === '')
|
|
171
|
+
return undefined;
|
|
172
|
+
let host;
|
|
173
|
+
try {
|
|
174
|
+
host = new URL(value).hostname.toLowerCase();
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
const loopback = host === 'localhost' || host.endsWith('.localhost') || (isIP(host) === 4 && host.startsWith('127.'));
|
|
180
|
+
return loopback ? undefined : value;
|
|
181
|
+
}
|
|
182
|
+
function secretValues(environment) {
|
|
183
|
+
const exactKeys = new Set(PLATFORM_SECRET_KEYS);
|
|
184
|
+
return Object.entries(environment)
|
|
185
|
+
.filter(([key, value]) => value.length > 0 && (exactKeys.has(key) || /(api[_-]?key|password|secret|token|credential)/i.test(key)))
|
|
186
|
+
.map(([, value]) => value);
|
|
187
|
+
}
|
|
188
|
+
function installAssets(paths, assetsDir) {
|
|
189
|
+
const composeSource = join(assetsDir, 'docker-compose.yml');
|
|
190
|
+
const contractSource = join(assetsDir, 'runtime-contract.json');
|
|
191
|
+
const postgresSource = join(assetsDir, 'postgres-initdb');
|
|
192
|
+
if (!existsSync(composeSource) || !existsSync(contractSource) || !existsSync(postgresSource)) {
|
|
193
|
+
throw new Error(`Portable runtime assets are incomplete: ${assetsDir}`);
|
|
194
|
+
}
|
|
195
|
+
mkdirSync(paths.runtimeDir, { recursive: true, mode: 0o700 });
|
|
196
|
+
cpSync(composeSource, paths.composeFile);
|
|
197
|
+
cpSync(contractSource, join(paths.runtimeDir, 'runtime-contract.json'));
|
|
198
|
+
rmSync(paths.postgresInitDir, { recursive: true, force: true });
|
|
199
|
+
cpSync(postgresSource, paths.postgresInitDir, { recursive: true });
|
|
200
|
+
}
|
|
201
|
+
function backupRuntimeAssets(paths) {
|
|
202
|
+
const backupDir = join(paths.runtimeDir, '.upgrade-backup');
|
|
203
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
204
|
+
mkdirSync(backupDir, { recursive: true, mode: 0o700 });
|
|
205
|
+
cpSync(paths.composeFile, join(backupDir, 'docker-compose.yml'));
|
|
206
|
+
const contractPath = join(paths.runtimeDir, 'runtime-contract.json');
|
|
207
|
+
if (existsSync(contractPath))
|
|
208
|
+
cpSync(contractPath, join(backupDir, 'runtime-contract.json'));
|
|
209
|
+
if (existsSync(paths.postgresInitDir)) {
|
|
210
|
+
cpSync(paths.postgresInitDir, join(backupDir, 'postgres-initdb'), { recursive: true });
|
|
211
|
+
}
|
|
212
|
+
return backupDir;
|
|
213
|
+
}
|
|
214
|
+
function restoreRuntimeAssets(paths, backupDir) {
|
|
215
|
+
cpSync(join(backupDir, 'docker-compose.yml'), paths.composeFile);
|
|
216
|
+
const contractBackup = join(backupDir, 'runtime-contract.json');
|
|
217
|
+
const contractPath = join(paths.runtimeDir, 'runtime-contract.json');
|
|
218
|
+
if (existsSync(contractBackup))
|
|
219
|
+
cpSync(contractBackup, contractPath);
|
|
220
|
+
else
|
|
221
|
+
rmSync(contractPath, { force: true });
|
|
222
|
+
rmSync(paths.postgresInitDir, { recursive: true, force: true });
|
|
223
|
+
const postgresBackup = join(backupDir, 'postgres-initdb');
|
|
224
|
+
if (existsSync(postgresBackup))
|
|
225
|
+
cpSync(postgresBackup, paths.postgresInitDir, { recursive: true });
|
|
226
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
227
|
+
}
|
|
228
|
+
function formatReadyOutput(state, paths, verb) {
|
|
229
|
+
return [
|
|
230
|
+
`Knowz platform '${state.name}' ${verb} (${state.version}, ${state.provider}, flavor ${state.imageFlavor || 'default'}).`,
|
|
231
|
+
`Web: ${state.serviceUrls.web}`,
|
|
232
|
+
`API: ${state.serviceUrls.api}`,
|
|
233
|
+
`MCP: ${state.serviceUrls.mcp}`,
|
|
234
|
+
`Runtime: ${paths.runtimeDir}`,
|
|
235
|
+
`Next: sign in at ${state.serviceUrls.web} with ADMIN_USERNAME/ADMIN_PASSWORD from ${paths.envFile}; use SUPERADMIN_PASSPHRASE at ${state.serviceUrls.web}/superadmin.`,
|
|
236
|
+
`Then create a self-hosted API key and pipe it to: knowz login --self-hosted --api-url ${state.serviceUrls.api} --key-stdin`,
|
|
237
|
+
].join('\n');
|
|
238
|
+
}
|
|
239
|
+
function processOutput(results, knownSecrets) {
|
|
240
|
+
return redactPlatformSecrets(results
|
|
241
|
+
.flatMap((result) => [result.stdout, result.stderr])
|
|
242
|
+
.filter((value) => Boolean(value?.trim()))
|
|
243
|
+
.join('\n')
|
|
244
|
+
.trim(), knownSecrets);
|
|
245
|
+
}
|
|
246
|
+
function sanitizedProcessResults(results, knownSecrets) {
|
|
247
|
+
return results.map((result) => ({
|
|
248
|
+
status: result.status,
|
|
249
|
+
stdout: result.stdout === undefined ? undefined : redactPlatformSecrets(result.stdout, knownSecrets),
|
|
250
|
+
stderr: result.stderr === undefined ? undefined : redactPlatformSecrets(result.stderr, knownSecrets),
|
|
251
|
+
error: result.error === undefined
|
|
252
|
+
? undefined
|
|
253
|
+
: new Error(redactPlatformSecrets(result.error.message, knownSecrets)),
|
|
254
|
+
}));
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Run `docker login` with the token on stdin only (never argv, never disk). The
|
|
258
|
+
* token is added to `knownSecrets` by the caller so any echoed output is redacted.
|
|
259
|
+
*/
|
|
260
|
+
async function authenticateRegistry(login, runner, knownSecrets, cwd, engine) {
|
|
261
|
+
const loginFront = loginCommandFor(engine);
|
|
262
|
+
const result = await Promise.resolve(runner(loginFront.command, login.args, {
|
|
263
|
+
cwd,
|
|
264
|
+
shell: false,
|
|
265
|
+
input: login.stdin,
|
|
266
|
+
...(loginFront.env ? { env: loginFront.env } : {}),
|
|
267
|
+
}));
|
|
268
|
+
if (result.error || result.status !== 0) {
|
|
269
|
+
const detail = result.stderr || result.stdout || result.error?.message || `exit status ${String(result.status)}`;
|
|
270
|
+
throw new Error(`Docker registry login failed: ${redactPlatformSecrets(detail.trim(), knownSecrets)}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function processFailed(result) {
|
|
274
|
+
return result.error !== undefined || result.status !== 0;
|
|
275
|
+
}
|
|
276
|
+
function missingPreloadedRefs(refs, result) {
|
|
277
|
+
const detail = `${result.stderr ?? ''}\n${result.stdout ?? ''}`;
|
|
278
|
+
const named = refs.filter((ref) => detail.includes(ref));
|
|
279
|
+
return named.length > 0 ? named : [...refs];
|
|
280
|
+
}
|
|
281
|
+
async function assertPreloadedImagesPresent(input, paths, imageSource, engine, runner, knownSecrets) {
|
|
282
|
+
const [config] = planComposeInvocations(input.action, paths, input.name, {
|
|
283
|
+
composeFile: imageSource.composeFile,
|
|
284
|
+
projectDir: imageSource.projectDir,
|
|
285
|
+
composePlan: 'config-up',
|
|
286
|
+
engine,
|
|
287
|
+
});
|
|
288
|
+
if (!config)
|
|
289
|
+
throw new Error('Preloaded image preflight could not plan Compose config.');
|
|
290
|
+
const configResult = await Promise.resolve(runner(config.command, [...config.args, '--images'], config.options));
|
|
291
|
+
if (processFailed(configResult))
|
|
292
|
+
throw composeFailureError(configResult, knownSecrets);
|
|
293
|
+
const refs = [...new Set((configResult.stdout ?? '').split(/\s+/).filter(Boolean))].sort();
|
|
294
|
+
if (refs.length === 0) {
|
|
295
|
+
throw new Error('Preloaded image preflight could not derive any image references from Compose.');
|
|
296
|
+
}
|
|
297
|
+
const engineFront = loginCommandFor(engine);
|
|
298
|
+
const inspectResult = await Promise.resolve(runner(engineFront.command, ['image', 'inspect', ...refs], {
|
|
299
|
+
cwd: paths.runtimeDir,
|
|
300
|
+
shell: false,
|
|
301
|
+
...(engineFront.env ? { env: engineFront.env } : {}),
|
|
302
|
+
}));
|
|
303
|
+
if (processFailed(inspectResult)) {
|
|
304
|
+
const missing = missingPreloadedRefs(refs, inspectResult);
|
|
305
|
+
throw new Error(`Preloaded platform images are missing: ${missing.join(', ')}. Load the release image bundle with load-image-bundle.sh (normally via knowz-image-load.service), or use docker load, then retry.`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
export function spinnerTextFor(invocation) {
|
|
309
|
+
if (invocation.args.includes('config'))
|
|
310
|
+
return 'Validating configuration…';
|
|
311
|
+
if (invocation.args.includes('pull'))
|
|
312
|
+
return 'Pulling images (first run can take a few minutes)…';
|
|
313
|
+
if (invocation.args.includes('build'))
|
|
314
|
+
return 'Building images…';
|
|
315
|
+
if (invocation.args.includes('up'))
|
|
316
|
+
return 'Starting services…';
|
|
317
|
+
return 'Running docker compose…';
|
|
318
|
+
}
|
|
319
|
+
export async function applyPlatform(input, dependencies = {}, imageSource = {}) {
|
|
320
|
+
const paths = resolvePlatformPaths(input.name, input.configDir);
|
|
321
|
+
let previousState;
|
|
322
|
+
try {
|
|
323
|
+
previousState = parseState(paths.stateFile);
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
// `up` is the repair path for an otherwise complete runtime whose state
|
|
327
|
+
// file was interrupted/corrupted. Reconstruct only secret-free metadata
|
|
328
|
+
// from the private env; upgrades stay strict because rollback needs the
|
|
329
|
+
// authoritative prior state.
|
|
330
|
+
if (input.action !== 'up' || !existsSync(paths.composeFile) || !existsSync(paths.envFile))
|
|
331
|
+
throw error;
|
|
332
|
+
previousState = reconstructStateFromEnv(input.name, paths);
|
|
333
|
+
}
|
|
334
|
+
if (input.action === 'upgrade' && !previousState) {
|
|
335
|
+
throw new Error(`Platform '${input.name}' is not initialized. Run \`knowz platform up\` first.`);
|
|
336
|
+
}
|
|
337
|
+
const previousEnvContents = readTextIfPresent(paths.envFile);
|
|
338
|
+
const existingEnvironment = previousEnvContents === undefined ? {} : parseEnv(previousEnvContents);
|
|
339
|
+
const ambient = pickAmbientEnvironment(dependencies.ambientEnv ?? process.env);
|
|
340
|
+
const configurationAmbient = input.action === 'upgrade' ? {} : ambient;
|
|
341
|
+
const environmentFallback = { ...existingEnvironment, ...configurationAmbient };
|
|
342
|
+
const bindAddress = configurationAmbient.BIND_ADDRESS ?? existingEnvironment.BIND_ADDRESS;
|
|
343
|
+
if (bindAddress !== undefined && isIP(bindAddress) !== 4) {
|
|
344
|
+
throw new Error('Platform bind address must be an IPv4 address such as 127.0.0.1 or 0.0.0.0.');
|
|
345
|
+
}
|
|
346
|
+
const requestedVersion = input.version ?? ambient.KNOWZ_VERSION;
|
|
347
|
+
if (input.action === 'upgrade' && !requestedVersion) {
|
|
348
|
+
throw new Error('A new platform version is required for upgrade. Pass --version or set KNOWZ_VERSION.');
|
|
349
|
+
}
|
|
350
|
+
const version = requestedVersion ?? existingEnvironment.KNOWZ_VERSION ?? previousState?.version;
|
|
351
|
+
if (!version)
|
|
352
|
+
throw new Error('Platform version is required. Pass --version or set KNOWZ_VERSION.');
|
|
353
|
+
if (input.action === 'upgrade' && version === previousState?.version) {
|
|
354
|
+
throw new Error(`Platform '${input.name}' already uses ${version}; choose a different pinned version.`);
|
|
355
|
+
}
|
|
356
|
+
if (input.action === 'up' && previousState !== undefined && version !== previousState.version) {
|
|
357
|
+
throw new Error(`Platform '${input.name}' uses ${previousState.version}; run \`knowz platform upgrade --version ${version}\` to change versions.`);
|
|
358
|
+
}
|
|
359
|
+
const provider = input.provider ?? configurationAmbient.KNOWZ_PROVIDER ?? previousState?.provider ?? 'offline';
|
|
360
|
+
const plan = buildPlatformPlan({
|
|
361
|
+
name: input.name,
|
|
362
|
+
configDir: input.configDir,
|
|
363
|
+
version,
|
|
364
|
+
provider,
|
|
365
|
+
storage: input.storage,
|
|
366
|
+
ports: {
|
|
367
|
+
api: input.ports?.api ??
|
|
368
|
+
integerFromEnvironment(configurationAmbient.API_PORT ?? existingEnvironment.API_PORT, 'API port'),
|
|
369
|
+
web: input.ports?.web ??
|
|
370
|
+
integerFromEnvironment(configurationAmbient.WEB_PORT ?? existingEnvironment.WEB_PORT, 'web port'),
|
|
371
|
+
mcp: input.ports?.mcp ??
|
|
372
|
+
integerFromEnvironment(configurationAmbient.MCP_PORT ?? existingEnvironment.MCP_PORT, 'MCP port'),
|
|
373
|
+
publicSite: input.ports?.publicSite ??
|
|
374
|
+
integerFromEnvironment(configurationAmbient.PUBLIC_SITE_PORT ?? existingEnvironment.PUBLIC_SITE_PORT, 'public site port'),
|
|
375
|
+
},
|
|
376
|
+
publicUrls: {
|
|
377
|
+
api: input.publicUrls?.api ?? configurationAmbient.PUBLIC_API_URL ?? preservedPublicUrl(existingEnvironment.PUBLIC_API_URL),
|
|
378
|
+
web: input.publicUrls?.web ??
|
|
379
|
+
configurationAmbient.PUBLIC_WEB_ORIGIN ??
|
|
380
|
+
preservedPublicUrl(existingEnvironment.PUBLIC_WEB_ORIGIN),
|
|
381
|
+
mcp: input.publicUrls?.mcp ?? configurationAmbient.PUBLIC_MCP_URL ?? preservedPublicUrl(existingEnvironment.PUBLIC_MCP_URL),
|
|
382
|
+
publicSite: input.publicUrls?.publicSite ??
|
|
383
|
+
configurationAmbient.PUBLIC_SITE_URL ??
|
|
384
|
+
preservedPublicUrl(existingEnvironment.PUBLIC_SITE_URL),
|
|
385
|
+
},
|
|
386
|
+
// Per-FIELD fallback, not per-object. `platformApplyInputFromFlags` always emits a DEFINED
|
|
387
|
+
// components object whose values are `undefined` when the flags were absent, so an
|
|
388
|
+
// object-level `??` never falls back and the empty object always wins. That silently
|
|
389
|
+
// re-enabled a deselected MCP on the next plain `knowz up` — an operator's decision to shut
|
|
390
|
+
// a listening surface off must survive later applies (R7). SEC-001.
|
|
391
|
+
components: {
|
|
392
|
+
mcp: input.components?.mcp ??
|
|
393
|
+
(configurationAmbient.KNOWZ_COMPONENTS === undefined
|
|
394
|
+
? previousState?.components?.mcp
|
|
395
|
+
: configurationAmbient.KNOWZ_COMPONENTS.split(',').includes('mcp')),
|
|
396
|
+
publicSite: input.components?.publicSite ??
|
|
397
|
+
(configurationAmbient.KNOWZ_COMPONENTS === undefined
|
|
398
|
+
? previousState?.components?.publicSite
|
|
399
|
+
: configurationAmbient.KNOWZ_COMPONENTS.split(',').includes('public-site')),
|
|
400
|
+
},
|
|
401
|
+
embeddingDimensions: input.embeddingDimensions ??
|
|
402
|
+
integerFromEnvironment(configurationAmbient.EMBEDDING_DIMENSIONS ?? existingEnvironment.EMBEDDING_DIMENSIONS, 'embedding dimensions'),
|
|
403
|
+
requestedFlavor: input.requestedFlavor,
|
|
404
|
+
axes: {
|
|
405
|
+
ai: input.axes?.ai ??
|
|
406
|
+
axisFromEnvironment(configurationAmbient.KNOWZ__CLOUDPROVIDER__AI ?? existingEnvironment.KNOWZ__CLOUDPROVIDER__AI),
|
|
407
|
+
docIntelligence: input.axes?.docIntelligence ??
|
|
408
|
+
axisFromEnvironment(configurationAmbient.KNOWZ__CLOUDPROVIDER__DOCINTELLIGENCE ??
|
|
409
|
+
existingEnvironment.KNOWZ__CLOUDPROVIDER__DOCINTELLIGENCE),
|
|
410
|
+
vision: input.axes?.vision ??
|
|
411
|
+
axisFromEnvironment(configurationAmbient.KNOWZ__CLOUDPROVIDER__VISION ?? existingEnvironment.KNOWZ__CLOUDPROVIDER__VISION),
|
|
412
|
+
transcription: input.axes?.transcription ??
|
|
413
|
+
axisFromEnvironment(configurationAmbient.KNOWZ__CLOUDPROVIDER__TRANSCRIPTION ??
|
|
414
|
+
existingEnvironment.KNOWZ__CLOUDPROVIDER__TRANSCRIPTION),
|
|
415
|
+
},
|
|
416
|
+
azure: input.azure,
|
|
417
|
+
gcp: input.gcp,
|
|
418
|
+
openAiCompatible: input.openAiCompatible,
|
|
419
|
+
existingEnv: environmentFallback,
|
|
420
|
+
});
|
|
421
|
+
if (bindAddress !== undefined &&
|
|
422
|
+
bindAddress !== '127.0.0.1' &&
|
|
423
|
+
Object.entries(plan.publicUrls).some(([key, value]) => {
|
|
424
|
+
if (key === 'publicSite' && !plan.components.publicSite)
|
|
425
|
+
return false;
|
|
426
|
+
const host = new URL(value).hostname.toLowerCase();
|
|
427
|
+
return host === 'localhost' || host.endsWith('.localhost') || host.startsWith('127.');
|
|
428
|
+
})) {
|
|
429
|
+
throw new Error('Explicit non-local public API, web, and MCP URLs are required for a non-loopback bind address.');
|
|
430
|
+
}
|
|
431
|
+
const environment = buildPlatformEnvironment(plan, existingEnvironment, {
|
|
432
|
+
randomBytes: dependencies.randomBytes,
|
|
433
|
+
orgName: input.orgName,
|
|
434
|
+
superAdminPassphrase: input.superAdminPassphrase,
|
|
435
|
+
});
|
|
436
|
+
if (imageSource.registry === null)
|
|
437
|
+
delete environment.KNOWZ_REGISTRY;
|
|
438
|
+
else if (imageSource.registry !== undefined)
|
|
439
|
+
environment.KNOWZ_REGISTRY = imageSource.registry;
|
|
440
|
+
if (bindAddress !== undefined)
|
|
441
|
+
environment.BIND_ADDRESS = bindAddress;
|
|
442
|
+
const knownSecrets = imageSource.login
|
|
443
|
+
? [...secretValues(environment), imageSource.login.stdin]
|
|
444
|
+
: secretValues(environment);
|
|
445
|
+
const runner = dependencies.runner ?? nodeAsyncProcessRunner;
|
|
446
|
+
const engine = dependencies.engine ?? resolveEngineStatus(await runEngineProbesAsync(runner), process.platform, process.env);
|
|
447
|
+
const progress = dependencies.progress ?? (process.stdout.isTTY
|
|
448
|
+
? withSpinner
|
|
449
|
+
: async (_text, run) => run());
|
|
450
|
+
const state = createPlatformState(plan, dependencies.now);
|
|
451
|
+
state.imageMode = imageSource.composePlan === 'config-build-up'
|
|
452
|
+
? 'build'
|
|
453
|
+
: imageSource.composePlan === 'config-up'
|
|
454
|
+
? 'preloaded'
|
|
455
|
+
: 'pull';
|
|
456
|
+
const freshInstall = previousState === undefined;
|
|
457
|
+
let processResults;
|
|
458
|
+
const backupDir = previousState === undefined ? undefined : backupRuntimeAssets(paths);
|
|
459
|
+
try {
|
|
460
|
+
installAssets(paths, dependencies.assetsDir ?? resolvePackagedAssetsDir());
|
|
461
|
+
writePrivateFile(paths.envFile, renderEnv(environment));
|
|
462
|
+
// Persist state BEFORE bringing the stack up on a fresh install, so that a failed
|
|
463
|
+
// `up --wait` still leaves a teardownable runtime (compose file + env + state) — the
|
|
464
|
+
// CLI can then `knowz down`/`platform reset` the containers `up` may have started
|
|
465
|
+
// instead of the user reaching for raw docker. Upgrades keep write-after-success below
|
|
466
|
+
// (their prior state.json already makes teardown work, and rollback must not advance it).
|
|
467
|
+
if (freshInstall)
|
|
468
|
+
writePrivateFile(paths.stateFile, serializePlatformState(state));
|
|
469
|
+
if (imageSource.composePlan === 'config-up') {
|
|
470
|
+
await assertPreloadedImagesPresent(input, paths, imageSource, engine, runner, knownSecrets);
|
|
471
|
+
}
|
|
472
|
+
if (imageSource.login) {
|
|
473
|
+
await authenticateRegistry(imageSource.login, runner, knownSecrets, paths.runtimeDir, engine);
|
|
474
|
+
}
|
|
475
|
+
processResults = await executeComposeInvocationsAsync(planComposeInvocations(input.action, paths, input.name, {
|
|
476
|
+
composeFile: imageSource.composeFile,
|
|
477
|
+
projectDir: imageSource.projectDir,
|
|
478
|
+
composePlan: imageSource.composePlan,
|
|
479
|
+
engine,
|
|
480
|
+
profiles: [
|
|
481
|
+
...(plan.components.mcp ? ['mcp'] : []),
|
|
482
|
+
...(plan.components.publicSite ? ['public-site'] : []),
|
|
483
|
+
],
|
|
484
|
+
}), runner, knownSecrets, (invocation, run) => progress(spinnerTextFor(invocation), run));
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
if (backupDir !== undefined)
|
|
488
|
+
restoreRuntimeAssets(paths, backupDir);
|
|
489
|
+
if (previousEnvContents !== undefined) {
|
|
490
|
+
writePrivateFile(paths.envFile, previousEnvContents);
|
|
491
|
+
}
|
|
492
|
+
// Fresh install: intentionally leave env + state + assets on disk so down/reset can
|
|
493
|
+
// clean up an orphaned stack from a failed `up`. A retry `up` at the same version
|
|
494
|
+
// reruns idempotently; `reset` tears it down.
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
497
|
+
if (backupDir !== undefined)
|
|
498
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
499
|
+
writePrivateFile(paths.stateFile, serializePlatformState(state));
|
|
500
|
+
return {
|
|
501
|
+
paths,
|
|
502
|
+
state,
|
|
503
|
+
processResults: sanitizedProcessResults(processResults, knownSecrets),
|
|
504
|
+
output: formatReadyOutput(state, paths, input.action === 'upgrade' ? 'upgraded' : 'started'),
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
export function runPlatformLifecycle(action, input, dependencies = {}) {
|
|
508
|
+
// down/destroy must be able to clean up an orphaned stack from a failed `up`, so they
|
|
509
|
+
// tolerate a missing/corrupt state.json; status/logs still require a healthy runtime.
|
|
510
|
+
const { paths, state } = action === 'down' || action === 'destroy'
|
|
511
|
+
? resolveTeardownTarget(input.name, input.configDir)
|
|
512
|
+
: requireInitialized(input.name, input.configDir);
|
|
513
|
+
const environment = parseEnv(readFileSync(paths.envFile, 'utf8'));
|
|
514
|
+
const knownSecrets = secretValues(environment);
|
|
515
|
+
const runner = dependencies.runner ?? nodeProcessRunner;
|
|
516
|
+
const engine = dependencies.engine ?? resolveEngineStatus(runEngineProbes(runner), process.platform, process.env);
|
|
517
|
+
const processResults = executeComposeInvocations(planComposeInvocations(action, paths, input.name, {
|
|
518
|
+
confirmed: input.confirmed,
|
|
519
|
+
follow: input.follow,
|
|
520
|
+
tail: input.tail,
|
|
521
|
+
engine,
|
|
522
|
+
...(action === 'status' || action === 'logs'
|
|
523
|
+
? { profiles: profilesForComponents(state.components) }
|
|
524
|
+
: {}),
|
|
525
|
+
}), runner, knownSecrets);
|
|
526
|
+
let output = processOutput(processResults, knownSecrets);
|
|
527
|
+
let versionSources;
|
|
528
|
+
let versionConsistent;
|
|
529
|
+
if (action === 'status') {
|
|
530
|
+
const rows = parseComposePsRows(processResults[0]?.stdout ?? '');
|
|
531
|
+
({ versionSources, versionConsistent } = observePlatformVersions(state, environment, rows));
|
|
532
|
+
output = rows.map((row) => [row.Service ?? 'unknown', row.State ?? 'unknown', row.Health].filter(Boolean).join(' ')).join('\n');
|
|
533
|
+
}
|
|
534
|
+
if (action === 'destroy')
|
|
535
|
+
rmSync(paths.runtimeDir, { recursive: true, force: true });
|
|
536
|
+
return {
|
|
537
|
+
paths,
|
|
538
|
+
state,
|
|
539
|
+
processResults: sanitizedProcessResults(processResults, knownSecrets),
|
|
540
|
+
output,
|
|
541
|
+
destroyed: action === 'destroy',
|
|
542
|
+
...(versionSources ? { versionSources, versionConsistent } : {}),
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
function doctorCheckName(id) {
|
|
546
|
+
switch (id) {
|
|
547
|
+
case 'docker-cli': return 'Docker';
|
|
548
|
+
case 'docker-compose': return 'Docker Compose';
|
|
549
|
+
case 'docker-daemon': return 'Docker daemon';
|
|
550
|
+
case 'podman-cli': return 'Podman';
|
|
551
|
+
case 'compose-v2': return 'Docker Compose v2';
|
|
552
|
+
case 'podman-machine': return 'Podman machine';
|
|
553
|
+
case 'podman-socket': return 'Podman socket';
|
|
554
|
+
default: return 'Container engine';
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
function doctorChecks(engine) {
|
|
558
|
+
return engineCheckSlice(engine).map((check) => ({
|
|
559
|
+
name: doctorCheckName(check.id),
|
|
560
|
+
ok: check.ok,
|
|
561
|
+
detail: check.ok
|
|
562
|
+
? check.label
|
|
563
|
+
: [check.message, check.remedy].filter(Boolean).join(' '),
|
|
564
|
+
}));
|
|
565
|
+
}
|
|
566
|
+
const KNOWZ_APPLICATION_SERVICES = new Set(['api', 'worker', 'web', 'mcp', 'public-site']);
|
|
567
|
+
const IMAGE_VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
568
|
+
function imageVersion(image) {
|
|
569
|
+
const lastSlash = image.lastIndexOf('/');
|
|
570
|
+
const tagSeparator = image.lastIndexOf(':');
|
|
571
|
+
if (tagSeparator <= lastSlash)
|
|
572
|
+
return undefined;
|
|
573
|
+
const tag = image.slice(tagSeparator + 1).replace(/-portable(?:-gcp)?$/, '');
|
|
574
|
+
return IMAGE_VERSION.test(tag) ? tag : undefined;
|
|
575
|
+
}
|
|
576
|
+
export function observePlatformVersions(state, environment, rows) {
|
|
577
|
+
const running = {};
|
|
578
|
+
const unparsedApplicationImages = [];
|
|
579
|
+
for (const row of rows) {
|
|
580
|
+
const service = row.Service?.toLowerCase();
|
|
581
|
+
if (!service || !KNOWZ_APPLICATION_SERVICES.has(service) || row.State?.toLowerCase() !== 'running')
|
|
582
|
+
continue;
|
|
583
|
+
const version = row.Image ? imageVersion(row.Image) : undefined;
|
|
584
|
+
if (version)
|
|
585
|
+
running[service] = version;
|
|
586
|
+
else
|
|
587
|
+
unparsedApplicationImages.push(service);
|
|
588
|
+
}
|
|
589
|
+
const environmentVersion = environment.KNOWZ_VERSION?.trim() || undefined;
|
|
590
|
+
const observed = [state.version, environmentVersion, ...Object.values(running)]
|
|
591
|
+
.filter((value) => Boolean(value));
|
|
592
|
+
return {
|
|
593
|
+
versionSources: {
|
|
594
|
+
state: state.version,
|
|
595
|
+
environment: environmentVersion,
|
|
596
|
+
running,
|
|
597
|
+
unparsedApplicationImages: unparsedApplicationImages.sort(),
|
|
598
|
+
},
|
|
599
|
+
versionConsistent: Boolean(environmentVersion) &&
|
|
600
|
+
unparsedApplicationImages.length === 0 &&
|
|
601
|
+
new Set(observed).size === 1,
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
function versionDetail(sources) {
|
|
605
|
+
const running = Object.entries(sources.running)
|
|
606
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
607
|
+
.map(([service, version]) => `${service}=${version}`)
|
|
608
|
+
.join(', ') || 'none observed';
|
|
609
|
+
const warning = sources.unparsedApplicationImages.length > 0
|
|
610
|
+
? `; warning: unparseable application images for ${sources.unparsedApplicationImages.join(', ')}`
|
|
611
|
+
: '';
|
|
612
|
+
return `state=${sources.state}; env=${sources.environment ?? 'missing'}; running=${running}${warning}`;
|
|
613
|
+
}
|
|
614
|
+
function requiredComposeServices(paths, components) {
|
|
615
|
+
const contractPath = join(paths.runtimeDir, 'runtime-contract.json');
|
|
616
|
+
let contract;
|
|
617
|
+
try {
|
|
618
|
+
contract = JSON.parse(readFileSync(contractPath, 'utf8'));
|
|
619
|
+
}
|
|
620
|
+
catch {
|
|
621
|
+
throw new Error(`Portable runtime contract is invalid: ${contractPath}`);
|
|
622
|
+
}
|
|
623
|
+
const required = (contract.services ?? [])
|
|
624
|
+
.filter((service) => {
|
|
625
|
+
if (typeof service.id !== 'string')
|
|
626
|
+
return false;
|
|
627
|
+
if (service.required === true)
|
|
628
|
+
return true;
|
|
629
|
+
if (service.profile === 'mcp')
|
|
630
|
+
return components?.mcp !== false;
|
|
631
|
+
if (service.profile === 'public-site')
|
|
632
|
+
return components?.publicSite === true;
|
|
633
|
+
return false;
|
|
634
|
+
})
|
|
635
|
+
.map((service) => ({
|
|
636
|
+
service: service.id === 'object-storage' ? 'minio' : service.id,
|
|
637
|
+
health: service.health ?? 'compose-process',
|
|
638
|
+
}));
|
|
639
|
+
if (required.length === 0)
|
|
640
|
+
throw new Error('Portable runtime contract declares no required services.');
|
|
641
|
+
return required;
|
|
642
|
+
}
|
|
643
|
+
function parseComposePsRows(output) {
|
|
644
|
+
try {
|
|
645
|
+
const parsed = JSON.parse(output);
|
|
646
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
647
|
+
}
|
|
648
|
+
catch {
|
|
649
|
+
try {
|
|
650
|
+
return output
|
|
651
|
+
.split(/\r?\n/)
|
|
652
|
+
.filter((line) => line.trim().length > 0)
|
|
653
|
+
.map((line) => JSON.parse(line));
|
|
654
|
+
}
|
|
655
|
+
catch {
|
|
656
|
+
throw new Error('Docker Compose returned invalid JSON service status.');
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
function validateComposeHealth(paths, state, result) {
|
|
661
|
+
const rows = parseComposePsRows(result.stdout ?? '');
|
|
662
|
+
const byService = new Map(rows.map((row) => [row.Service, row]));
|
|
663
|
+
const required = requiredComposeServices(paths, state.components);
|
|
664
|
+
for (const requirement of required) {
|
|
665
|
+
const service = requirement.service;
|
|
666
|
+
const row = byService.get(service);
|
|
667
|
+
if (!row)
|
|
668
|
+
throw new Error(`Required portable service '${service}' is missing.`);
|
|
669
|
+
if (row.State?.toLowerCase() !== 'running') {
|
|
670
|
+
throw new Error(`Required portable service '${service}' is ${row.State || 'not running'}.`);
|
|
671
|
+
}
|
|
672
|
+
if (requirement.health !== 'compose-process' && row.Health?.toLowerCase() !== 'healthy') {
|
|
673
|
+
throw new Error(`Required portable service '${service}' is ${row.Health || 'not healthy'}.`);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
return `${required.length}/${required.length} required services running`;
|
|
677
|
+
}
|
|
678
|
+
export function runPlatformDoctor(input, dependencies = {}) {
|
|
679
|
+
const runner = dependencies.runner ?? nodeProcessRunner;
|
|
680
|
+
const engine = dependencies.engine ?? resolveEngineStatus(runEngineProbes(runner), process.platform, process.env);
|
|
681
|
+
const checks = doctorChecks(engine);
|
|
682
|
+
const paths = resolvePlatformPaths(input.name, input.configDir);
|
|
683
|
+
const state = parseState(paths.stateFile);
|
|
684
|
+
if (!state) {
|
|
685
|
+
return {
|
|
686
|
+
initialized: false,
|
|
687
|
+
checks,
|
|
688
|
+
output: `${checks.map((check) => `${check.name}: ${check.detail}`).join('\n')}\nRuntime: not initialized`,
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
if (checks.some((check) => !check.ok)) {
|
|
692
|
+
return {
|
|
693
|
+
initialized: true,
|
|
694
|
+
checks,
|
|
695
|
+
state,
|
|
696
|
+
output: checks.map((check) => `${check.name}: ${check.detail}`).join('\n'),
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
const initialized = requireInitialized(input.name, input.configDir);
|
|
700
|
+
const environment = parseEnv(readFileSync(initialized.paths.envFile, 'utf8'));
|
|
701
|
+
const knownSecrets = secretValues(environment);
|
|
702
|
+
const results = executeComposeInvocations(planComposeInvocations('doctor', initialized.paths, input.name, {
|
|
703
|
+
engine,
|
|
704
|
+
profiles: profilesForComponents(initialized.state.components),
|
|
705
|
+
}), runner, knownSecrets);
|
|
706
|
+
// A successful `compose config` is a validation signal; never return its rendered environment.
|
|
707
|
+
const composeDetail = validateComposeHealth(initialized.paths, initialized.state, results[1] ?? { status: null });
|
|
708
|
+
checks.push({ name: 'Runtime Compose', ok: true, detail: composeDetail || 'configuration and service status are valid' });
|
|
709
|
+
const rows = parseComposePsRows(results[1]?.stdout ?? '');
|
|
710
|
+
const versions = observePlatformVersions(initialized.state, environment, rows);
|
|
711
|
+
checks.push({
|
|
712
|
+
name: 'Runtime Versions',
|
|
713
|
+
ok: versions.versionConsistent,
|
|
714
|
+
detail: versionDetail(versions.versionSources),
|
|
715
|
+
});
|
|
716
|
+
return {
|
|
717
|
+
initialized: true,
|
|
718
|
+
checks,
|
|
719
|
+
state: initialized.state,
|
|
720
|
+
versionSources: versions.versionSources,
|
|
721
|
+
versionConsistent: versions.versionConsistent,
|
|
722
|
+
output: checks.map((check) => `${check.name}: ${check.detail}`).join('\n'),
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
//# sourceMappingURL=platform-lifecycle.js.map
|