@commandable/mcp 0.1.3 → 0.2.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/{dist/app → .output}/nitro.json +1 -1
- package/{dist/app/public/_nuxt/-tOYwuj2.js → .output/public/_nuxt/B04gGCnx.js} +3 -3
- package/{dist/app/public/_nuxt/D-43HurL.js → .output/public/_nuxt/B2dAlp_u.js} +8 -8
- package/.output/public/_nuxt/Ba0BY0O0.js +1 -0
- package/.output/public/_nuxt/BvFUCPqA.js +1 -0
- package/{dist/app/public/_nuxt/BdctKXor.js → .output/public/_nuxt/Dm_hd4at.js} +1 -1
- package/{dist/app/public/_nuxt/BlP7Uu-5.js → .output/public/_nuxt/S2P9sd4n.js} +1 -1
- package/.output/public/_nuxt/builds/latest.json +1 -0
- package/.output/public/_nuxt/builds/meta/ee5097c4-b785-4b77-92d6-c16a7396d677.json +1 -0
- package/{dist/app/public/_nuxt/CsbkV5Bd.js → .output/public/_nuxt/d2XTSFt9.js} +1 -1
- package/{dist/app/server/chunks/build/_id_-DBwSV4AY.mjs → .output/server/chunks/build/_id_-Bnxenh08.mjs} +7 -7
- package/{dist/app/server/chunks/build/_id_-DBwSV4AY.mjs.map → .output/server/chunks/build/_id_-Bnxenh08.mjs.map} +1 -1
- package/{dist/app → .output}/server/chunks/build/client.precomputed.mjs +1 -1
- package/{dist/app/server/chunks/build/fetch-ZbqIFhDG.mjs → .output/server/chunks/build/fetch-BmYZnj75.mjs} +58 -6
- package/.output/server/chunks/build/fetch-BmYZnj75.mjs.map +1 -0
- package/{dist/app/server/chunks/build/index-C8flTcKI.mjs → .output/server/chunks/build/index-CL-Gkd-Y.mjs} +4 -4
- package/.output/server/chunks/build/index-CL-Gkd-Y.mjs.map +1 -0
- package/{dist/app → .output}/server/chunks/build/server.mjs +3 -3
- package/{dist/app → .output}/server/chunks/nitro/nitro.mjs +422 -209
- package/.output/server/chunks/nitro/nitro.mjs.map +1 -0
- package/{dist/app → .output}/server/chunks/routes/api/index.get.mjs +1 -1
- package/{dist/app → .output}/server/chunks/routes/api/index.post.mjs +1 -1
- package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/credentials-config.get.mjs +1 -1
- package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/credentials-status.get.mjs +1 -1
- package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/credentials.delete.mjs +1 -1
- package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/credentials.post.mjs +1 -1
- package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/permissions.post.mjs +1 -1
- package/.output/server/chunks/routes/api/integrations/_id/tools.delete.mjs +51 -0
- package/.output/server/chunks/routes/api/integrations/_id/tools.delete.mjs.map +1 -0
- package/.output/server/chunks/routes/api/integrations/_id/tools.get.mjs +57 -0
- package/.output/server/chunks/routes/api/integrations/_id/tools.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/integrations/_id/toolsets.get.mjs +53 -0
- package/.output/server/chunks/routes/api/integrations/_id/toolsets.get.mjs.map +1 -0
- package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/toolsets.post.mjs +1 -1
- package/.output/server/chunks/routes/api/integrations/_id_.delete.mjs +55 -0
- package/.output/server/chunks/routes/api/integrations/_id_.delete.mjs.map +1 -0
- package/{dist/app → .output}/server/chunks/routes/mcp/create.mjs +1 -1
- package/{dist/app → .output}/server/chunks/routes/mcp.mjs +1 -1
- package/{dist/app → .output}/server/chunks/routes/renderer.mjs +1 -1
- package/{dist/app → .output}/server/index.mjs +1 -1
- package/{dist/app → .output}/server/package.json +2 -2
- package/LICENSE +17 -6
- package/README.md +32 -32
- package/bin/cli.mjs +552 -0
- package/bin/commandable-mcp.mjs +8 -0
- package/package.json +30 -40
- package/dist/app/public/_nuxt/DU1mG77A.js +0 -1
- package/dist/app/public/_nuxt/builds/latest.json +0 -1
- package/dist/app/public/_nuxt/builds/meta/669e3b7a-802b-4f02-b218-3c758cac3ab7.json +0 -1
- package/dist/app/public/_nuxt/uS7FY2am.js +0 -1
- package/dist/app/server/chunks/build/fetch-ZbqIFhDG.mjs.map +0 -1
- package/dist/app/server/chunks/build/index-C8flTcKI.mjs.map +0 -1
- package/dist/app/server/chunks/nitro/nitro.mjs.map +0 -1
- package/dist/app/server/chunks/routes/api/integrations/_id_.delete.mjs +0 -44
- package/dist/app/server/chunks/routes/api/integrations/_id_.delete.mjs.map +0 -1
- package/dist/app/server/migrations/pg/0000_initial.sql +0 -74
- package/dist/app/server/migrations/pg/meta/_journal.json +0 -13
- package/dist/app/server/migrations/sqlite/0000_initial.sql +0 -74
- package/dist/app/server/migrations/sqlite/meta/_journal.json +0 -13
- package/dist/cli/bin.d.ts +0 -3
- package/dist/cli/bin.d.ts.map +0 -1
- package/dist/cli/bin.js +0 -7
- package/dist/cli/bin.js.map +0 -1
- package/dist/cli/credentialManager.d.ts +0 -19
- package/dist/cli/credentialManager.d.ts.map +0 -1
- package/dist/cli/credentialManager.js +0 -82
- package/dist/cli/credentialManager.js.map +0 -1
- package/dist/cli/index.d.ts +0 -17
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -832
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/setup.d.ts +0 -3
- package/dist/cli/setup.d.ts.map +0 -1
- package/dist/cli/setup.js +0 -353
- package/dist/cli/setup.js.map +0 -1
- package/dist/config/configApply.d.ts +0 -16
- package/dist/config/configApply.d.ts.map +0 -1
- package/dist/config/configApply.js +0 -77
- package/dist/config/configApply.js.map +0 -1
- package/dist/config/configLoader.d.ts +0 -9
- package/dist/config/configLoader.d.ts.map +0 -1
- package/dist/config/configLoader.js +0 -75
- package/dist/config/configLoader.js.map +0 -1
- package/dist/config/configSchema.d.ts +0 -45
- package/dist/config/configSchema.d.ts.map +0 -1
- package/dist/config/configSchema.js +0 -23
- package/dist/config/configSchema.js.map +0 -1
- package/dist/crypto/encryption.d.ts +0 -3
- package/dist/crypto/encryption.d.ts.map +0 -1
- package/dist/crypto/encryption.js +0 -29
- package/dist/crypto/encryption.js.map +0 -1
- package/dist/db/client.d.ts +0 -24
- package/dist/db/client.d.ts.map +0 -1
- package/dist/db/client.js +0 -50
- package/dist/db/client.js.map +0 -1
- package/dist/db/credentialStore.d.ts +0 -15
- package/dist/db/credentialStore.d.ts.map +0 -1
- package/dist/db/credentialStore.js +0 -56
- package/dist/db/credentialStore.js.map +0 -1
- package/dist/db/integrationStore.d.ts +0 -12
- package/dist/db/integrationStore.d.ts.map +0 -1
- package/dist/db/integrationStore.js +0 -111
- package/dist/db/integrationStore.js.map +0 -1
- package/dist/db/integrationTypeConfigStore.d.ts +0 -6
- package/dist/db/integrationTypeConfigStore.d.ts.map +0 -1
- package/dist/db/integrationTypeConfigStore.js +0 -94
- package/dist/db/integrationTypeConfigStore.js.map +0 -1
- package/dist/db/migrate.d.ts +0 -3
- package/dist/db/migrate.d.ts.map +0 -1
- package/dist/db/migrate.js +0 -11
- package/dist/db/migrate.js.map +0 -1
- package/dist/db/migrations/pg/0000_initial.sql +0 -74
- package/dist/db/migrations/pg/meta/_journal.json +0 -13
- package/dist/db/migrations/sqlite/0000_initial.sql +0 -74
- package/dist/db/migrations/sqlite/meta/_journal.json +0 -13
- package/dist/db/schema.d.ts +0 -1863
- package/dist/db/schema.d.ts.map +0 -1
- package/dist/db/schema.js +0 -133
- package/dist/db/schema.js.map +0 -1
- package/dist/db/toolDefinitionStore.d.ts +0 -6
- package/dist/db/toolDefinitionStore.d.ts.map +0 -1
- package/dist/db/toolDefinitionStore.js +0 -95
- package/dist/db/toolDefinitionStore.js.map +0 -1
- package/dist/errors/httpError.d.ts +0 -6
- package/dist/errors/httpError.d.ts.map +0 -1
- package/dist/errors/httpError.js +0 -11
- package/dist/errors/httpError.js.map +0 -1
- package/dist/index.d.ts +0 -32
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -32
- package/dist/index.js.map +0 -1
- package/dist/integrations/actionsFactory.d.ts +0 -16
- package/dist/integrations/actionsFactory.d.ts.map +0 -1
- package/dist/integrations/actionsFactory.js +0 -98
- package/dist/integrations/actionsFactory.js.map +0 -1
- package/dist/integrations/catalog.d.ts +0 -8
- package/dist/integrations/catalog.d.ts.map +0 -1
- package/dist/integrations/catalog.js +0 -45
- package/dist/integrations/catalog.js.map +0 -1
- package/dist/integrations/customToolFactory.d.ts +0 -13
- package/dist/integrations/customToolFactory.d.ts.map +0 -1
- package/dist/integrations/customToolFactory.js +0 -31
- package/dist/integrations/customToolFactory.js.map +0 -1
- package/dist/integrations/dataLoader.d.ts +0 -3
- package/dist/integrations/dataLoader.d.ts.map +0 -1
- package/dist/integrations/dataLoader.js +0 -2
- package/dist/integrations/dataLoader.js.map +0 -1
- package/dist/integrations/fileIntegrationTypeConfigStore.d.ts +0 -7
- package/dist/integrations/fileIntegrationTypeConfigStore.d.ts.map +0 -1
- package/dist/integrations/fileIntegrationTypeConfigStore.js +0 -34
- package/dist/integrations/fileIntegrationTypeConfigStore.js.map +0 -1
- package/dist/integrations/getIntegration.d.ts +0 -14
- package/dist/integrations/getIntegration.d.ts.map +0 -1
- package/dist/integrations/getIntegration.js +0 -30
- package/dist/integrations/getIntegration.js.map +0 -1
- package/dist/integrations/googleServiceAccount.d.ts +0 -6
- package/dist/integrations/googleServiceAccount.d.ts.map +0 -1
- package/dist/integrations/googleServiceAccount.js +0 -54
- package/dist/integrations/googleServiceAccount.js.map +0 -1
- package/dist/integrations/health.d.ts +0 -20
- package/dist/integrations/health.d.ts.map +0 -1
- package/dist/integrations/health.js +0 -43
- package/dist/integrations/health.js.map +0 -1
- package/dist/integrations/integrationTypeConfigLookup.d.ts +0 -12
- package/dist/integrations/integrationTypeConfigLookup.d.ts.map +0 -1
- package/dist/integrations/integrationTypeConfigLookup.js +0 -11
- package/dist/integrations/integrationTypeConfigLookup.js.map +0 -1
- package/dist/integrations/providerRegistry.d.ts +0 -2
- package/dist/integrations/providerRegistry.d.ts.map +0 -1
- package/dist/integrations/providerRegistry.js +0 -72
- package/dist/integrations/providerRegistry.js.map +0 -1
- package/dist/integrations/proxy.d.ts +0 -19
- package/dist/integrations/proxy.d.ts.map +0 -1
- package/dist/integrations/proxy.js +0 -377
- package/dist/integrations/proxy.js.map +0 -1
- package/dist/integrations/sandbox.d.ts +0 -8
- package/dist/integrations/sandbox.d.ts.map +0 -1
- package/dist/integrations/sandbox.js +0 -221
- package/dist/integrations/sandbox.js.map +0 -1
- package/dist/integrations/sandboxUtils.d.ts +0 -15
- package/dist/integrations/sandboxUtils.d.ts.map +0 -1
- package/dist/integrations/sandboxUtils.js +0 -489
- package/dist/integrations/sandboxUtils.js.map +0 -1
- package/dist/integrations/tools.d.ts +0 -3
- package/dist/integrations/tools.d.ts.map +0 -1
- package/dist/integrations/tools.js +0 -70
- package/dist/integrations/tools.js.map +0 -1
- package/dist/mcp/abilityCatalog.d.ts +0 -46
- package/dist/mcp/abilityCatalog.d.ts.map +0 -1
- package/dist/mcp/abilityCatalog.js +0 -275
- package/dist/mcp/abilityCatalog.js.map +0 -1
- package/dist/mcp/auth.d.ts +0 -18
- package/dist/mcp/auth.d.ts.map +0 -1
- package/dist/mcp/auth.js +0 -45
- package/dist/mcp/auth.js.map +0 -1
- package/dist/mcp/builder_guide.md +0 -441
- package/dist/mcp/commandable_readme.md +0 -29
- package/dist/mcp/handlers.d.ts +0 -21
- package/dist/mcp/handlers.d.ts.map +0 -1
- package/dist/mcp/handlers.js +0 -86
- package/dist/mcp/handlers.js.map +0 -1
- package/dist/mcp/metaTools.d.ts +0 -77
- package/dist/mcp/metaTools.d.ts.map +0 -1
- package/dist/mcp/metaTools.js +0 -753
- package/dist/mcp/metaTools.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -25
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js +0 -14
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/sessionState.d.ts +0 -18
- package/dist/mcp/sessionState.d.ts.map +0 -1
- package/dist/mcp/sessionState.js +0 -65
- package/dist/mcp/sessionState.js.map +0 -1
- package/dist/mcp/toolAdapter.d.ts +0 -34
- package/dist/mcp/toolAdapter.d.ts.map +0 -1
- package/dist/mcp/toolAdapter.js +0 -24
- package/dist/mcp/toolAdapter.js.map +0 -1
- package/dist/types.d.ts +0 -92
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -7
- package/dist/version.js.map +0 -1
- /package/{dist/app → .output}/public/_fonts/57NSSoFy1VLVs2gqly8Ls9awBnZMFyXGrefpmqvdqmc-zJfbBtpgM4cDmcXBsqZNW79_kFnlpPd62b48glgdydA.woff2 +0 -0
- /package/{dist/app → .output}/public/_fonts/8VR2wSMN-3U4NbWAVYXlkRV6hA0jFBXP-0RtL3X7fko-x2gYI4qfmkRdxyQQUPaBZdZdgl1TeVrquF_TxHeM4lM.woff2 +0 -0
- /package/{dist/app → .output}/public/_fonts/GsKUclqeNLJ96g5AU593ug6yanivOiwjW_7zESNPChw-jHA4tBeM1bjF7LATGUpfBuSTyomIFrWBTzjF7txVYfg.woff2 +0 -0
- /package/{dist/app → .output}/public/_fonts/Ld1FnTo3yTIwDyGfTQ5-Fws9AWsCbKfMvgxduXr7JcY-W25bL8NF1fjpLRSOgJb7RoZPHqGQNwMTM7S9tHVoxx8.woff2 +0 -0
- /package/{dist/app → .output}/public/_fonts/NdzqRASp2bovDUhQT1IRE_EMqKJ2KYQdTCfFcBvL8yw-KhwZiS86o3fErOe5GGMExHUemmI_dBfaEFxjISZrBd0.woff2 +0 -0
- /package/{dist/app → .output}/public/_fonts/iTkrULNFJJkTvihIg1Vqi5IODRH_9btXCioVF5l98I8-AndUyau2HR2felA_ra8V2mutQgschhasE5FD1dXGJX8.woff2 +0 -0
- /package/{dist/app → .output}/public/_nuxt/_id_.BKAjWkoP.css +0 -0
- /package/{dist/app → .output}/public/_nuxt/entry.Y3mA4bzA.css +0 -0
- /package/{dist/app → .output}/public/_nuxt/error-404.C7fg894-.css +0 -0
- /package/{dist/app → .output}/public/_nuxt/error-500.DjUK_N2Y.css +0 -0
- /package/{dist/app → .output}/public/favicon.ico +0 -0
- /package/{dist/app → .output}/server/chunks/_/error-500.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/_/error-500.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/_/icons.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/_/icons.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/_/icons2.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/_/icons2.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/build/IntegrationCredentials-styles.CULcCK6_.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/build/IntegrationCredentials-styles.CULcCK6_.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/build/client.precomputed.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/build/error-404-D2QibUBT.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/build/error-404-D2QibUBT.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/build/error-404-styles.Bvxdxqjk.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/build/error-404-styles.Bvxdxqjk.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/build/error-500-DYvawybF.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/build/error-500-DYvawybF.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/build/error-500-styles.BnYAAXSg.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/build/error-500-styles.BnYAAXSg.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/build/index-5H-nmhph.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/build/index-5H-nmhph.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/build/server.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/build/styles.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/build/styles.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/_commandable/status.get.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/_commandable/status.get.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/catalog/_type/tools.get.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/catalog/_type/tools.get.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/catalog/_type/toolsets.get.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/catalog/_type/toolsets.get.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/catalog.get.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/catalog.get.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/index.get.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/index.post.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/credentials-config.get.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/credentials-status.get.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/credentials.delete.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/credentials.post.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/permissions.post.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/api/integrations/_id/toolsets.post.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/health.get.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/routes/health.get.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/mcp/create.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/mcp.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/routes/renderer.mjs.map +0 -0
- /package/{dist/app → .output}/server/chunks/virtual/_virtual_spa-template.mjs +0 -0
- /package/{dist/app → .output}/server/chunks/virtual/_virtual_spa-template.mjs.map +0 -0
- /package/{dist/app → .output}/server/index.mjs.map +0 -0
package/dist/cli/index.js
DELETED
|
@@ -1,832 +0,0 @@
|
|
|
1
|
-
import picocolors from 'picocolors';
|
|
2
|
-
import crypto from 'node:crypto';
|
|
3
|
-
import { spawn, spawnSync } from 'node:child_process';
|
|
4
|
-
import { chmodSync, existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
5
|
-
import { homedir } from 'node:os';
|
|
6
|
-
import { dirname, resolve } from 'node:path';
|
|
7
|
-
import { fileURLToPath } from 'node:url';
|
|
8
|
-
import { isCancel, note, select } from '@clack/prompts';
|
|
9
|
-
import { IntegrationProxy } from '../integrations/proxy.js';
|
|
10
|
-
import { buildMcpToolIndex } from '../mcp/toolAdapter.js';
|
|
11
|
-
import { runStdioMcpServer } from '../mcp/server.js';
|
|
12
|
-
import { createApiKey, generateApiKey } from '../mcp/auth.js';
|
|
13
|
-
import { AbilityCatalog } from '../mcp/abilityCatalog.js';
|
|
14
|
-
import { SessionAbilityState } from '../mcp/sessionState.js';
|
|
15
|
-
import { getBuilderToolDefinitions } from '../mcp/metaTools.js';
|
|
16
|
-
import { COMMANDABLE_VERSION } from '../version.js';
|
|
17
|
-
import { runAddInteractive, runInitInteractive } from './setup.js';
|
|
18
|
-
import { getCommandableDir, getOrCreateEncryptionSecret, openLocalState } from './credentialManager.js';
|
|
19
|
-
import { listIntegrations } from '../db/integrationStore.js';
|
|
20
|
-
import { listToolDefinitions } from '../db/toolDefinitionStore.js';
|
|
21
|
-
import { listIntegrationTypeConfigs } from '../db/integrationTypeConfigStore.js';
|
|
22
|
-
import { createDbFromEnv } from '../db/client.js';
|
|
23
|
-
import { ensureSchema } from '../db/migrate.js';
|
|
24
|
-
import { SqlCredentialStore } from '../db/credentialStore.js';
|
|
25
|
-
import { applyConfig } from '../config/configApply.js';
|
|
26
|
-
import { loadConfig } from '../config/configLoader.js';
|
|
27
|
-
import { integrationDataRoot } from '../integrations/dataLoader.js';
|
|
28
|
-
function hasFlag(...flags) {
|
|
29
|
-
return flags.some(f => process.argv.includes(f));
|
|
30
|
-
}
|
|
31
|
-
function resolveMode() {
|
|
32
|
-
const explicit = (process.env.COMMANDABLE_MODE || '').toLowerCase().trim();
|
|
33
|
-
if (explicit === 'create')
|
|
34
|
-
return 'create';
|
|
35
|
-
return 'static';
|
|
36
|
-
}
|
|
37
|
-
async function fetchJsonWithTimeout(url, timeoutMs) {
|
|
38
|
-
const controller = new AbortController();
|
|
39
|
-
const t = setTimeout(() => controller.abort(), timeoutMs);
|
|
40
|
-
try {
|
|
41
|
-
const resp = await fetch(url, { signal: controller.signal });
|
|
42
|
-
const text = await resp.text();
|
|
43
|
-
let json = null;
|
|
44
|
-
try {
|
|
45
|
-
json = JSON.parse(text);
|
|
46
|
-
}
|
|
47
|
-
catch { }
|
|
48
|
-
return { ok: resp.ok, status: resp.status, json, text };
|
|
49
|
-
}
|
|
50
|
-
finally {
|
|
51
|
-
clearTimeout(t);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
function expectedUiIdentity() {
|
|
55
|
-
const spaceId = (process.env.COMMANDABLE_SPACE_ID || 'local').trim() || 'local';
|
|
56
|
-
const databaseUrl = process.env.DATABASE_URL;
|
|
57
|
-
if (databaseUrl && databaseUrl.trim().length)
|
|
58
|
-
return { spaceId, db: { dialect: 'postgres' } };
|
|
59
|
-
const forced = process.env.COMMANDABLE_MCP_SQLITE_PATH;
|
|
60
|
-
if (forced && forced.trim().length)
|
|
61
|
-
return { spaceId, db: { dialect: 'sqlite', sqlitePath: resolve(forced.trim()) } };
|
|
62
|
-
const dataDir = process.env.COMMANDABLE_DATA_DIR;
|
|
63
|
-
const sqlitePath = dataDir && dataDir.trim().length
|
|
64
|
-
? resolve(dataDir.trim(), 'credentials.sqlite')
|
|
65
|
-
: resolve(homedir(), '.commandable', 'credentials.sqlite');
|
|
66
|
-
return { spaceId, db: { dialect: 'sqlite', sqlitePath } };
|
|
67
|
-
}
|
|
68
|
-
async function waitForHttp(baseUrl, timeoutMs = 12_000) {
|
|
69
|
-
const start = Date.now();
|
|
70
|
-
while (Date.now() - start < timeoutMs) {
|
|
71
|
-
try {
|
|
72
|
-
const resp = await fetch(`${baseUrl}/api/_commandable/status`).catch(() => null);
|
|
73
|
-
if (resp && resp.ok) {
|
|
74
|
-
const data = await resp.json().catch(() => null);
|
|
75
|
-
if (data?.service === 'commandable-management-ui' && data?.ok === true)
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
catch { }
|
|
80
|
-
await new Promise(resolve => setTimeout(resolve, 150));
|
|
81
|
-
}
|
|
82
|
-
throw new Error(`Timed out waiting for management UI at ${baseUrl}`);
|
|
83
|
-
}
|
|
84
|
-
async function startBundledManagementUi(params) {
|
|
85
|
-
const port = params.port;
|
|
86
|
-
const baseUrl = `http://127.0.0.1:${port}`;
|
|
87
|
-
// If something is already listening, only reuse it if it's our UI and points
|
|
88
|
-
// at the same local DB + space. Otherwise fail fast with a clear message to
|
|
89
|
-
// avoid sending users to the wrong instance.
|
|
90
|
-
try {
|
|
91
|
-
const probe = await fetchJsonWithTimeout(`${baseUrl}/api/_commandable/status`, 400);
|
|
92
|
-
if (probe?.ok) {
|
|
93
|
-
const status = probe.json;
|
|
94
|
-
if (status?.service !== 'commandable-management-ui' || status?.ok !== true) {
|
|
95
|
-
throw new Error(`Port ${port} is already in use by a non-Commandable service. ` +
|
|
96
|
-
`Set COMMANDABLE_UI_PORT to a different port or stop the process using ${baseUrl}.`);
|
|
97
|
-
}
|
|
98
|
-
const expected = expectedUiIdentity();
|
|
99
|
-
const sameSpace = status?.spaceId === expected.spaceId;
|
|
100
|
-
const sameDialect = status?.db?.dialect === expected.db.dialect;
|
|
101
|
-
const sameSqlite = status?.db?.dialect !== 'sqlite' || expected.db.dialect !== 'sqlite'
|
|
102
|
-
? true
|
|
103
|
-
: status?.db?.sqlitePath === expected.db.sqlitePath;
|
|
104
|
-
if (!sameSpace || !sameDialect || !sameSqlite) {
|
|
105
|
-
const details = [
|
|
106
|
-
`expected spaceId=${expected.spaceId}, got=${status?.spaceId}`,
|
|
107
|
-
`expected dialect=${expected.db.dialect}, got=${status?.db?.dialect}`,
|
|
108
|
-
expected.db.dialect === 'sqlite' ? `expected sqlitePath=${expected.db.sqlitePath}` : null,
|
|
109
|
-
status?.db?.dialect === 'sqlite' ? `got sqlitePath=${status?.db?.sqlitePath}` : null,
|
|
110
|
-
].filter(Boolean).join(' | ');
|
|
111
|
-
throw new Error(`A Commandable management UI is already running at ${baseUrl} but it does not match this session's DB/space (${details}). ` +
|
|
112
|
-
`Stop the existing UI process or set COMMANDABLE_UI_PORT to avoid conflicts.`);
|
|
113
|
-
}
|
|
114
|
-
const runningVersion = typeof status?.version === 'string' && status.version.trim().length ? status.version.trim() : null;
|
|
115
|
-
if (runningVersion !== COMMANDABLE_VERSION) {
|
|
116
|
-
console.error(`[commandable] restarting management UI due to version mismatch (running=${runningVersion ?? 'unknown'}, installed=${COMMANDABLE_VERSION})`);
|
|
117
|
-
const info = readDaemonPid();
|
|
118
|
-
if (info?.pid && isProcessAlive(info.pid)) {
|
|
119
|
-
try {
|
|
120
|
-
process.kill(info.pid, 'SIGTERM');
|
|
121
|
-
}
|
|
122
|
-
catch { }
|
|
123
|
-
try {
|
|
124
|
-
unlinkSync(daemonPidPath());
|
|
125
|
-
}
|
|
126
|
-
catch { }
|
|
127
|
-
// Wait briefly for the port to be released.
|
|
128
|
-
await new Promise(resolve => setTimeout(resolve, 250));
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
throw new Error(`A Commandable management UI is running at ${baseUrl} with version=${runningVersion ?? 'unknown'}, but the daemon PID could not be determined. ` +
|
|
132
|
-
`Stop the process using ${baseUrl} (or change COMMANDABLE_UI_PORT) to continue.`);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
console.error(`[commandable] reusing existing management UI at ${baseUrl}`);
|
|
136
|
-
return { baseUrl, stop: async () => { }, reused: true };
|
|
137
|
-
}
|
|
138
|
-
else if (probe?.status && probe.status !== 404) {
|
|
139
|
-
throw new Error(`Port ${port} is already in use (HTTP ${probe.status}). ` +
|
|
140
|
-
`Set COMMANDABLE_UI_PORT to a different port or stop the process using ${baseUrl}.`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
// Connection refused / not reachable -> port is likely free; proceed to spawn.
|
|
145
|
-
}
|
|
146
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
147
|
-
// dist/cli/index.js -> dist/app/server/index.mjs
|
|
148
|
-
const serverEntry = resolve(here, '..', 'app', 'server', 'index.mjs');
|
|
149
|
-
const cwd = resolve(here, '..', 'app');
|
|
150
|
-
if (!existsSync(serverEntry)) {
|
|
151
|
-
console.error(`[commandable] bundled management UI not found at: ${serverEntry}`);
|
|
152
|
-
console.error(`[commandable] create-mode will run without the UI; credentials links will be unavailable.`);
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
const execPath = existsSync(process.execPath) ? process.execPath : 'node';
|
|
156
|
-
const child = spawn(execPath, [serverEntry], {
|
|
157
|
-
cwd,
|
|
158
|
-
env: {
|
|
159
|
-
...process.env,
|
|
160
|
-
HOST: '127.0.0.1',
|
|
161
|
-
PORT: String(port),
|
|
162
|
-
COMMANDABLE_MODE: 'create',
|
|
163
|
-
COMMANDABLE_VERSION,
|
|
164
|
-
COMMANDABLE_INTEGRATION_DATA_DIR: process.env.COMMANDABLE_INTEGRATION_DATA_DIR || integrationDataRoot(),
|
|
165
|
-
COMMANDABLE_MCP_SQLITE_PATH: process.env.COMMANDABLE_MCP_SQLITE_PATH || resolve(getCommandableDir(), 'credentials.sqlite'),
|
|
166
|
-
},
|
|
167
|
-
stdio: 'ignore',
|
|
168
|
-
detached: true,
|
|
169
|
-
});
|
|
170
|
-
child.unref();
|
|
171
|
-
const pidPath = resolve(getCommandableDir(), 'daemon.pid');
|
|
172
|
-
try {
|
|
173
|
-
// Format:
|
|
174
|
-
// <pid>
|
|
175
|
-
// <version>
|
|
176
|
-
writeFileSync(pidPath, `${child.pid}\n${COMMANDABLE_VERSION}\n`, { mode: 0o600 });
|
|
177
|
-
try {
|
|
178
|
-
chmodSync(pidPath, 0o600);
|
|
179
|
-
}
|
|
180
|
-
catch { }
|
|
181
|
-
}
|
|
182
|
-
catch { }
|
|
183
|
-
try {
|
|
184
|
-
await waitForHttp(baseUrl);
|
|
185
|
-
}
|
|
186
|
-
catch (err) {
|
|
187
|
-
console.error(`[commandable] management UI failed to start at ${baseUrl}`);
|
|
188
|
-
console.error(err?.message || err);
|
|
189
|
-
// Daemon start failed; attempt cleanup (best effort).
|
|
190
|
-
try {
|
|
191
|
-
process.kill(child.pid, 'SIGTERM');
|
|
192
|
-
}
|
|
193
|
-
catch { }
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
return {
|
|
197
|
-
baseUrl,
|
|
198
|
-
reused: false,
|
|
199
|
-
stop: async () => {
|
|
200
|
-
const pidFile = resolve(getCommandableDir(), 'daemon.pid');
|
|
201
|
-
let pid = null;
|
|
202
|
-
try {
|
|
203
|
-
const raw = readFileSync(pidFile, 'utf8');
|
|
204
|
-
const first = raw.split('\n')[0]?.trim() || '';
|
|
205
|
-
pid = first && /^\d+$/.test(first) ? Number(first) : null;
|
|
206
|
-
}
|
|
207
|
-
catch { }
|
|
208
|
-
if (pid) {
|
|
209
|
-
try {
|
|
210
|
-
process.kill(pid, 'SIGTERM');
|
|
211
|
-
}
|
|
212
|
-
catch { }
|
|
213
|
-
}
|
|
214
|
-
try {
|
|
215
|
-
unlinkSync(pidFile);
|
|
216
|
-
}
|
|
217
|
-
catch { }
|
|
218
|
-
},
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
function daemonPidPath() {
|
|
222
|
-
return resolve(getCommandableDir(), 'daemon.pid');
|
|
223
|
-
}
|
|
224
|
-
function readDaemonPid() {
|
|
225
|
-
try {
|
|
226
|
-
const raw = readFileSync(daemonPidPath(), 'utf8');
|
|
227
|
-
const lines = raw.split('\n').map(l => l.trim()).filter(Boolean);
|
|
228
|
-
const pidRaw = lines[0] || '';
|
|
229
|
-
const versionRaw = lines[1] || null;
|
|
230
|
-
const pid = pidRaw && /^\d+$/.test(pidRaw) ? Number(pidRaw) : null;
|
|
231
|
-
return pid ? { pid, version: versionRaw } : null;
|
|
232
|
-
}
|
|
233
|
-
catch {
|
|
234
|
-
return null;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
function isProcessAlive(pid) {
|
|
238
|
-
try {
|
|
239
|
-
process.kill(pid, 0);
|
|
240
|
-
return true;
|
|
241
|
-
}
|
|
242
|
-
catch {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
function getFlagValue(flag) {
|
|
247
|
-
const idx = process.argv.indexOf(flag);
|
|
248
|
-
if (idx === -1)
|
|
249
|
-
return null;
|
|
250
|
-
const val = process.argv[idx + 1];
|
|
251
|
-
if (!val || val.startsWith('-'))
|
|
252
|
-
return null;
|
|
253
|
-
return val;
|
|
254
|
-
}
|
|
255
|
-
function getUiPort() {
|
|
256
|
-
const uiPortRaw = process.env.COMMANDABLE_UI_PORT;
|
|
257
|
-
return uiPortRaw && /^\d+$/.test(uiPortRaw) ? Number(uiPortRaw) : 23432;
|
|
258
|
-
}
|
|
259
|
-
function getSqlitePathForLocalState() {
|
|
260
|
-
const forced = process.env.COMMANDABLE_MCP_SQLITE_PATH;
|
|
261
|
-
if (forced && forced.trim().length)
|
|
262
|
-
return resolve(forced.trim());
|
|
263
|
-
return resolve(getCommandableDir(), 'credentials.sqlite');
|
|
264
|
-
}
|
|
265
|
-
function getSourceValue() {
|
|
266
|
-
const raw = (getFlagValue('--source') || 'package').trim().toLowerCase();
|
|
267
|
-
if (raw === 'local' || raw === 'package')
|
|
268
|
-
return raw;
|
|
269
|
-
console.error(`Invalid --source value: ${raw}. Use ${picocolors.cyan('package')} or ${picocolors.cyan('local')}.`);
|
|
270
|
-
process.exit(1);
|
|
271
|
-
}
|
|
272
|
-
function getTransportValue() {
|
|
273
|
-
const raw = (getFlagValue('--transport') || 'stdio').trim().toLowerCase();
|
|
274
|
-
if (raw === 'stdio' || raw === 'http')
|
|
275
|
-
return raw;
|
|
276
|
-
console.error(`Invalid --transport value: ${raw}. Use ${picocolors.cyan('stdio')} or ${picocolors.cyan('http')}.`);
|
|
277
|
-
process.exit(1);
|
|
278
|
-
}
|
|
279
|
-
function getReadClientValue() {
|
|
280
|
-
const raw = (getFlagValue('--client') || 'claude-desktop').trim().toLowerCase();
|
|
281
|
-
if (raw === 'claude-desktop' || raw === 'cursor')
|
|
282
|
-
return raw;
|
|
283
|
-
console.error(`Invalid --client value: ${raw}. Use ${picocolors.cyan('claude-desktop')} or ${picocolors.cyan('cursor')}.`);
|
|
284
|
-
process.exit(1);
|
|
285
|
-
}
|
|
286
|
-
function stopDaemonProcess() {
|
|
287
|
-
const pid = readDaemonPid();
|
|
288
|
-
if (pid?.pid) {
|
|
289
|
-
try {
|
|
290
|
-
process.kill(pid.pid, 'SIGTERM');
|
|
291
|
-
}
|
|
292
|
-
catch { }
|
|
293
|
-
}
|
|
294
|
-
try {
|
|
295
|
-
unlinkSync(daemonPidPath());
|
|
296
|
-
}
|
|
297
|
-
catch { }
|
|
298
|
-
return { stopped: !!pid?.pid, pid: pid?.pid ?? null };
|
|
299
|
-
}
|
|
300
|
-
export function makeClaudeCodeAddCommand(source) {
|
|
301
|
-
const envArgs = getClaudeCodeEnvEntries()
|
|
302
|
-
.map(value => `-e ${quoteShellArg(value)}`)
|
|
303
|
-
.join(' ');
|
|
304
|
-
if (source === 'package')
|
|
305
|
-
return `claude mcp add commandable${envArgs ? ` ${envArgs}` : ''} -- npx -y @commandable/mcp create-mode`;
|
|
306
|
-
const localBin = process.argv[1] && process.argv[1].trim().length
|
|
307
|
-
? resolve(process.argv[1])
|
|
308
|
-
: '/absolute/path/to/commandable-mcp/packages/server/dist/cli/bin.js';
|
|
309
|
-
return `claude mcp add commandable${envArgs ? ` ${envArgs}` : ''} -- node ${localBin} create-mode`;
|
|
310
|
-
}
|
|
311
|
-
function execClaudeMcpAdd(args) {
|
|
312
|
-
const result = spawnSync('claude', args, { stdio: 'inherit' });
|
|
313
|
-
if (result.error) {
|
|
314
|
-
// claude CLI not available — print the command as fallback
|
|
315
|
-
console.error(`claude ${args.join(' ')}`);
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
if (result.status !== 0)
|
|
319
|
-
process.exit(result.status ?? 1);
|
|
320
|
-
}
|
|
321
|
-
const CLAUDE_CODE_STDIO_ENV_KEYS = [
|
|
322
|
-
'COMMANDABLE_SPACE_ID',
|
|
323
|
-
'COMMANDABLE_DATA_DIR',
|
|
324
|
-
'COMMANDABLE_MCP_SQLITE_PATH',
|
|
325
|
-
'COMMANDABLE_UI_PORT',
|
|
326
|
-
'DATABASE_URL',
|
|
327
|
-
'COMMANDABLE_CONFIG_FILE',
|
|
328
|
-
'COMMANDABLE_INTEGRATION_DATA_DIR',
|
|
329
|
-
];
|
|
330
|
-
function getClaudeCodeEnvEntries() {
|
|
331
|
-
return CLAUDE_CODE_STDIO_ENV_KEYS
|
|
332
|
-
.map((key) => {
|
|
333
|
-
const value = process.env[key];
|
|
334
|
-
return value && value.trim().length ? `${key}=${value}` : null;
|
|
335
|
-
})
|
|
336
|
-
.filter((value) => !!value);
|
|
337
|
-
}
|
|
338
|
-
function quoteShellArg(value) {
|
|
339
|
-
if (/^[A-Za-z0-9_./:=@-]+$/.test(value))
|
|
340
|
-
return value;
|
|
341
|
-
return `'${value.replace(/'/g, `'\"'\"'`)}'`;
|
|
342
|
-
}
|
|
343
|
-
export function makeReadModeConfig(source) {
|
|
344
|
-
if (source === 'package') {
|
|
345
|
-
return {
|
|
346
|
-
mcpServers: {
|
|
347
|
-
commandable: {
|
|
348
|
-
command: 'npx',
|
|
349
|
-
args: ['-y', '@commandable/mcp'],
|
|
350
|
-
},
|
|
351
|
-
},
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
const localBin = process.argv[1] && process.argv[1].trim().length
|
|
355
|
-
? resolve(process.argv[1])
|
|
356
|
-
: '/absolute/path/to/commandable-mcp/packages/server/dist/cli/bin.js';
|
|
357
|
-
return {
|
|
358
|
-
mcpServers: {
|
|
359
|
-
commandable: {
|
|
360
|
-
command: 'node',
|
|
361
|
-
args: [localBin],
|
|
362
|
-
},
|
|
363
|
-
},
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
export function makeHttpConnectionDetails() {
|
|
367
|
-
const url = getFlagValue('--url') || 'https://your-host/mcp';
|
|
368
|
-
const apiKey = getFlagValue('--api-key') || '<api-key>';
|
|
369
|
-
return {
|
|
370
|
-
url,
|
|
371
|
-
headers: {
|
|
372
|
-
Authorization: `Bearer ${apiKey}`,
|
|
373
|
-
},
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
function makeClaudeCodeHttpAddCommand() {
|
|
377
|
-
const details = makeHttpConnectionDetails();
|
|
378
|
-
return `claude mcp add --transport http commandable ${details.url} --header "Authorization: ${details.headers.Authorization}"`;
|
|
379
|
-
}
|
|
380
|
-
function printCreateInstructions(addCommand, instanceLabel) {
|
|
381
|
-
const line = picocolors.dim('─'.repeat(60));
|
|
382
|
-
console.error('');
|
|
383
|
-
console.error(picocolors.white('The current create experience requires an advanced MCP client. We recommend Claude Code.'));
|
|
384
|
-
console.error('');
|
|
385
|
-
console.error(picocolors.bold(`Connect Claude Code to your local ${instanceLabel}:`));
|
|
386
|
-
console.error(line);
|
|
387
|
-
console.error(picocolors.cyan('claude mcp remove commandable'));
|
|
388
|
-
console.error(picocolors.cyan(addCommand));
|
|
389
|
-
console.error(line);
|
|
390
|
-
console.error(picocolors.dim('Paste the commands above into your terminal, then restart Claude Code.'));
|
|
391
|
-
console.error(picocolors.dim('Previous Commandable instances keep their own state and can be re-added later.'));
|
|
392
|
-
console.error('');
|
|
393
|
-
}
|
|
394
|
-
function runCreate() {
|
|
395
|
-
const source = getSourceValue();
|
|
396
|
-
const transport = getTransportValue();
|
|
397
|
-
const shouldApply = hasFlag('--apply');
|
|
398
|
-
const command = transport === 'http'
|
|
399
|
-
? makeClaudeCodeHttpAddCommand()
|
|
400
|
-
: makeClaudeCodeAddCommand(source);
|
|
401
|
-
if (!shouldApply) {
|
|
402
|
-
const instanceLabel = source === 'local' ? 'dev instance' : 'instance';
|
|
403
|
-
printCreateInstructions(command, instanceLabel);
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
if (transport === 'http') {
|
|
407
|
-
const url = getFlagValue('--url');
|
|
408
|
-
const apiKey = getFlagValue('--api-key');
|
|
409
|
-
if (!url || !apiKey) {
|
|
410
|
-
console.error(`For ${picocolors.cyan('--apply')} with HTTP, pass ${picocolors.cyan('--url')} and ${picocolors.cyan('--api-key')}.`);
|
|
411
|
-
process.exit(1);
|
|
412
|
-
}
|
|
413
|
-
execClaudeMcpAdd(['mcp', 'add', '--transport', 'http', 'commandable', url, '--header', `Authorization: Bearer ${apiKey}`]);
|
|
414
|
-
console.error(`${picocolors.green('Done.')} Restart Claude Code.`);
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
const envArgs = getClaudeCodeEnvEntries().flatMap(value => ['-e', value]);
|
|
418
|
-
if (source === 'package')
|
|
419
|
-
execClaudeMcpAdd(['mcp', 'add', 'commandable', ...envArgs, '--', 'npx', '-y', '@commandable/mcp', 'create-mode']);
|
|
420
|
-
else {
|
|
421
|
-
const localBin = process.argv[1] && process.argv[1].trim().length
|
|
422
|
-
? resolve(process.argv[1])
|
|
423
|
-
: '/absolute/path/to/commandable-mcp/packages/server/dist/cli/bin.js';
|
|
424
|
-
execClaudeMcpAdd(['mcp', 'add', 'commandable', ...envArgs, '--', 'node', localBin, 'create-mode']);
|
|
425
|
-
}
|
|
426
|
-
console.error(`${picocolors.green('Done.')} Restart Claude Code.`);
|
|
427
|
-
}
|
|
428
|
-
async function runServeLocal(opts) {
|
|
429
|
-
const uiPort = getUiPort();
|
|
430
|
-
const baseUrl = `http://127.0.0.1:${uiPort}`;
|
|
431
|
-
if (opts.restart)
|
|
432
|
-
stopDaemonProcess();
|
|
433
|
-
// Run migrations once here before the app server starts. Both the app server
|
|
434
|
-
// and create-mode open the DB without running migrations themselves, so this
|
|
435
|
-
// is the single authoritative place schema is applied.
|
|
436
|
-
const migrateClient = createDbFromEnv();
|
|
437
|
-
await ensureSchema(migrateClient);
|
|
438
|
-
migrateClient.close();
|
|
439
|
-
const ui = await startBundledManagementUi({ port: uiPort });
|
|
440
|
-
if (!ui)
|
|
441
|
-
throw new Error(`Failed to ${opts.restart ? 'restart' : 'start'} local Commandable instance`);
|
|
442
|
-
const sqlitePath = getSqlitePathForLocalState();
|
|
443
|
-
console.error(picocolors.green(`Commandable local instance ${ui.reused && !opts.restart ? 'ready' : 'running'}.`));
|
|
444
|
-
console.error(`${picocolors.dim('Base URL:')} ${baseUrl}`);
|
|
445
|
-
console.error(`${picocolors.dim('Management UI:')} ${baseUrl}/`);
|
|
446
|
-
console.error(`${picocolors.dim('MCP endpoint:')} ${baseUrl}/mcp`);
|
|
447
|
-
console.error(`${picocolors.dim('Data dir:')} ${getCommandableDir()}`);
|
|
448
|
-
console.error(`${picocolors.dim('SQLite:')} ${sqlitePath}`);
|
|
449
|
-
console.error(`${picocolors.dim('State:')} ${ui.reused ? 'reused existing instance' : 'started fresh instance'}`);
|
|
450
|
-
console.error(`Next: ${picocolors.cyan('commandable-mcp create')} or ${picocolors.cyan('commandable-mcp connect --client claude-desktop')}`);
|
|
451
|
-
}
|
|
452
|
-
async function runServe() {
|
|
453
|
-
const transport = getFlagValue('--transport');
|
|
454
|
-
if (transport && transport.trim().toLowerCase() === 'http') {
|
|
455
|
-
console.error('HTTP deployment is served by the app runtime, not this CLI.');
|
|
456
|
-
console.error(`Use ${picocolors.cyan('yarn dev')} locally or deploy the app, then run ${picocolors.cyan('commandable-mcp create --transport http --url <url> --api-key <key>')}.`);
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
|
-
return await runServeLocal({ restart: hasFlag('--restart') });
|
|
460
|
-
}
|
|
461
|
-
function runConnect() {
|
|
462
|
-
const source = getSourceValue();
|
|
463
|
-
const transport = getTransportValue();
|
|
464
|
-
const client = getReadClientValue();
|
|
465
|
-
if (transport === 'http') {
|
|
466
|
-
console.error(JSON.stringify(makeHttpConnectionDetails(), null, 2));
|
|
467
|
-
return;
|
|
468
|
-
}
|
|
469
|
-
if (client === 'cursor' || client === 'claude-desktop') {
|
|
470
|
-
console.error(JSON.stringify(makeReadModeConfig(source), null, 2));
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
async function runDoctor() {
|
|
474
|
-
const uiPort = getUiPort();
|
|
475
|
-
const baseUrl = `http://127.0.0.1:${uiPort}`;
|
|
476
|
-
const pid = readDaemonPid();
|
|
477
|
-
const pidAlive = pid ? isProcessAlive(pid.pid) : false;
|
|
478
|
-
const probe = await fetchJsonWithTimeout(`${baseUrl}/api/_commandable/status`, 500).catch(() => null);
|
|
479
|
-
const probeVersion = typeof probe?.json?.version === 'string' && probe.json.version.trim().length
|
|
480
|
-
? probe.json.version.trim()
|
|
481
|
-
: null;
|
|
482
|
-
const runningVersion = probeVersion || pid?.version || null;
|
|
483
|
-
const databaseUrl = process.env.DATABASE_URL;
|
|
484
|
-
const sqlitePath = databaseUrl && databaseUrl.trim().length ? null : getSqlitePathForLocalState();
|
|
485
|
-
const report = {
|
|
486
|
-
ok: true,
|
|
487
|
-
installedVersion: COMMANDABLE_VERSION,
|
|
488
|
-
mode: resolveMode(),
|
|
489
|
-
env: {
|
|
490
|
-
COMMANDABLE_SPACE_ID: (process.env.COMMANDABLE_SPACE_ID || 'local').trim() || 'local',
|
|
491
|
-
COMMANDABLE_DATA_DIR: process.env.COMMANDABLE_DATA_DIR || null,
|
|
492
|
-
COMMANDABLE_MCP_SQLITE_PATH: process.env.COMMANDABLE_MCP_SQLITE_PATH || null,
|
|
493
|
-
COMMANDABLE_UI_PORT: uiPort,
|
|
494
|
-
DATABASE_URL: databaseUrl && databaseUrl.trim().length ? '[set]' : null,
|
|
495
|
-
},
|
|
496
|
-
localState: {
|
|
497
|
-
dataDir: getCommandableDir(),
|
|
498
|
-
sqlitePath,
|
|
499
|
-
daemonPidPath: daemonPidPath(),
|
|
500
|
-
encryptionKeyPath: resolve(getCommandableDir(), 'encryption.key'),
|
|
501
|
-
},
|
|
502
|
-
daemon: {
|
|
503
|
-
running: !!(pidAlive && probe?.ok),
|
|
504
|
-
pid: pid ?? null,
|
|
505
|
-
baseUrl,
|
|
506
|
-
runningVersion,
|
|
507
|
-
versionMatch: !!runningVersion && runningVersion === COMMANDABLE_VERSION,
|
|
508
|
-
status: probe?.json ?? null,
|
|
509
|
-
},
|
|
510
|
-
hints: [
|
|
511
|
-
'Use "commandable-mcp destroy local --yes" for a full local wipe.',
|
|
512
|
-
'Use "commandable-mcp serve" to start the local Commandable instance.',
|
|
513
|
-
'Use "commandable-mcp create" for the Claude Code authoring flow.',
|
|
514
|
-
'Use "commandable-mcp connect --client claude-desktop" for a read-client config snippet.',
|
|
515
|
-
],
|
|
516
|
-
};
|
|
517
|
-
console.error(JSON.stringify(report, null, 2));
|
|
518
|
-
}
|
|
519
|
-
async function confirmDestroyLocal(params) {
|
|
520
|
-
note([
|
|
521
|
-
picocolors.bold(picocolors.red('This will delete all of your local saved Commandable data.')),
|
|
522
|
-
'',
|
|
523
|
-
`${picocolors.white('•')} saved integrations and credentials`,
|
|
524
|
-
`${picocolors.white('•')} local SQLite state and daemon state`,
|
|
525
|
-
`${picocolors.white('•')} ${params.keepKey ? 'the encryption key will be kept (--keep-key is set)' : 'the local encryption key'}`,
|
|
526
|
-
'',
|
|
527
|
-
picocolors.yellow('Remote Postgres data will not be deleted.'),
|
|
528
|
-
].join('\n'), picocolors.yellow('Warning'), { format: (str) => str });
|
|
529
|
-
const result = await select({
|
|
530
|
-
message: 'Do you want to continue?',
|
|
531
|
-
options: [
|
|
532
|
-
{ value: 'destroy', label: picocolors.red('Yes, destroy local data') },
|
|
533
|
-
{ value: 'cancel', label: picocolors.cyan('No, keep local data') },
|
|
534
|
-
],
|
|
535
|
-
initialValue: 'cancel',
|
|
536
|
-
});
|
|
537
|
-
if (isCancel(result) || result !== 'destroy') {
|
|
538
|
-
console.error(picocolors.yellow('Destroy cancelled.'));
|
|
539
|
-
return false;
|
|
540
|
-
}
|
|
541
|
-
return true;
|
|
542
|
-
}
|
|
543
|
-
async function runDestroyLocal() {
|
|
544
|
-
const keepKey = hasFlag('--keep-key');
|
|
545
|
-
if (!hasFlag('--yes')) {
|
|
546
|
-
const confirmed = await confirmDestroyLocal({ keepKey });
|
|
547
|
-
if (!confirmed)
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
const dataDir = getCommandableDir();
|
|
551
|
-
const sqlitePath = getSqlitePathForLocalState();
|
|
552
|
-
const keyPath = resolve(dataDir, 'encryption.key');
|
|
553
|
-
const daemonPath = daemonPidPath();
|
|
554
|
-
const stopped = stopDaemonProcess();
|
|
555
|
-
const removed = [];
|
|
556
|
-
const missing = [];
|
|
557
|
-
for (const file of [sqlitePath, daemonPath, ...(keepKey ? [] : [keyPath])]) {
|
|
558
|
-
if (!existsSync(file)) {
|
|
559
|
-
missing.push(file);
|
|
560
|
-
continue;
|
|
561
|
-
}
|
|
562
|
-
try {
|
|
563
|
-
unlinkSync(file);
|
|
564
|
-
removed.push(file);
|
|
565
|
-
}
|
|
566
|
-
catch (err) {
|
|
567
|
-
console.error(`Failed to remove ${file}: ${err?.message || err}`);
|
|
568
|
-
process.exit(1);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
console.error(picocolors.green('Local destroy complete.'));
|
|
572
|
-
console.error(`${picocolors.dim('Data dir:')} ${dataDir}`);
|
|
573
|
-
console.error(`${picocolors.dim('Daemon stopped:')} ${stopped.stopped ? 'yes' : 'no (no PID found)'}`);
|
|
574
|
-
if (removed.length)
|
|
575
|
-
console.error(`${picocolors.dim('Removed:')} ${removed.join(', ')}`);
|
|
576
|
-
if (missing.length)
|
|
577
|
-
console.error(`${picocolors.dim('Already absent:')} ${missing.join(', ')}`);
|
|
578
|
-
if (process.env.DATABASE_URL && process.env.DATABASE_URL.trim().length)
|
|
579
|
-
console.error(`${picocolors.yellow('Warning:')} DATABASE_URL is set; remote Postgres data was not modified.`);
|
|
580
|
-
console.error(`Next step: ${picocolors.cyan('commandable-mcp serve')}`);
|
|
581
|
-
console.error(`Then connect create mode: ${picocolors.cyan('commandable-mcp create')}`);
|
|
582
|
-
console.error(`Legacy bootstrap: ${picocolors.cyan('commandable-mcp static-init')}`);
|
|
583
|
-
}
|
|
584
|
-
async function runRefreshLocalDev() {
|
|
585
|
-
await runServeLocal({ restart: true });
|
|
586
|
-
}
|
|
587
|
-
function help(exitCode = 0) {
|
|
588
|
-
const lines = [
|
|
589
|
-
'',
|
|
590
|
-
`${picocolors.bold('Commandable MCP')} — build and serve app-connected MCP tools`,
|
|
591
|
-
picocolors.dim(`v${COMMANDABLE_VERSION}`),
|
|
592
|
-
'',
|
|
593
|
-
picocolors.bold('Usage'),
|
|
594
|
-
` ${picocolors.cyan('commandable-mcp serve')} ${picocolors.dim('[--restart]')}`,
|
|
595
|
-
` ${picocolors.cyan('commandable-mcp create')} ${picocolors.dim('[--transport stdio|http] [--source package|local] [--apply] [--url] [--api-key]')}`,
|
|
596
|
-
` ${picocolors.cyan('commandable-mcp connect')} ${picocolors.dim('[--client claude-desktop|cursor] [--transport stdio|http] [--source package|local] [--url] [--api-key]')}`,
|
|
597
|
-
` ${picocolors.cyan('commandable-mcp doctor')}`,
|
|
598
|
-
` ${picocolors.cyan('commandable-mcp destroy local')} ${picocolors.dim('[--yes] [--keep-key]')}`,
|
|
599
|
-
` ${picocolors.cyan('commandable-mcp apply')} ${picocolors.dim('[--config ./commandable.config.yaml]')}`,
|
|
600
|
-
` ${picocolors.cyan('commandable-mcp create-api-key')} ${picocolors.dim('[name]')}`,
|
|
601
|
-
` ${picocolors.cyan('commandable-mcp --version')}`,
|
|
602
|
-
'',
|
|
603
|
-
picocolors.bold('Notes'),
|
|
604
|
-
`- Credentials entered via the CLI are stored encrypted at ${picocolors.dim('~/.commandable/')} (override with ${picocolors.cyan('COMMANDABLE_DATA_DIR')}).`,
|
|
605
|
-
`- ${picocolors.bold('Serve')}: starts or reuses the local Commandable instance.`,
|
|
606
|
-
`- ${picocolors.bold('Create')}: Claude Code authoring flow. Prints or applies the ${picocolors.cyan('claude mcp add')} command.`,
|
|
607
|
-
`- ${picocolors.bold('Connect')}: prints read-client connection details for the MCP server you already configured.`,
|
|
608
|
-
'',
|
|
609
|
-
];
|
|
610
|
-
console.error(lines.join('\n'));
|
|
611
|
-
process.exit(exitCode);
|
|
612
|
-
}
|
|
613
|
-
async function runStdioFromDb(forceMode) {
|
|
614
|
-
const spaceId = process.env.COMMANDABLE_SPACE_ID || 'local';
|
|
615
|
-
const { db, credentialStore } = await openLocalState();
|
|
616
|
-
const integrations = await listIntegrations(db, spaceId);
|
|
617
|
-
const toolDefinitions = await listToolDefinitions(db, spaceId);
|
|
618
|
-
const integrationTypeConfigs = await listIntegrationTypeConfigs(db, spaceId);
|
|
619
|
-
const integrationTypeConfigsRef = { current: integrationTypeConfigs };
|
|
620
|
-
const proxy = new IntegrationProxy({
|
|
621
|
-
credentialStore,
|
|
622
|
-
trelloApiKey: process.env.TRELLO_API_KEY,
|
|
623
|
-
integrationTypeConfigsRef,
|
|
624
|
-
});
|
|
625
|
-
const mode = forceMode ?? resolveMode();
|
|
626
|
-
if (!integrations.length && mode !== 'create') {
|
|
627
|
-
console.error(`No integrations configured yet.`);
|
|
628
|
-
console.error(`Preferred: ${picocolors.cyan('commandable-mcp create')} then configure tools in Claude Code.`);
|
|
629
|
-
console.error(`Legacy read-mode bootstrap: ${picocolors.cyan('commandable-mcp static-init')}.`);
|
|
630
|
-
process.exit(0);
|
|
631
|
-
}
|
|
632
|
-
const integrationsRef = { current: integrations };
|
|
633
|
-
const index = buildMcpToolIndex({ spaceId, integrations, proxy, integrationsRef, toolDefinitions });
|
|
634
|
-
const toolIndex = { list: index.tools, byName: index.byName };
|
|
635
|
-
const uiPortRaw = process.env.COMMANDABLE_UI_PORT;
|
|
636
|
-
const uiPort = uiPortRaw && /^\d+$/.test(uiPortRaw) ? Number(uiPortRaw) : 23432;
|
|
637
|
-
const managementUi = mode === 'create'
|
|
638
|
-
? await startBundledManagementUi({ port: uiPort })
|
|
639
|
-
: null;
|
|
640
|
-
console.error(`[commandable] v${COMMANDABLE_VERSION}`);
|
|
641
|
-
await runStdioMcpServer({
|
|
642
|
-
serverInfo: { name: 'commandable', version: COMMANDABLE_VERSION },
|
|
643
|
-
tools: toolIndex,
|
|
644
|
-
...(mode === 'create'
|
|
645
|
-
? {
|
|
646
|
-
createMode: (() => {
|
|
647
|
-
const builderDefs = getBuilderToolDefinitions();
|
|
648
|
-
const extraToolDefinitions = new Map(builderDefs.map(d => [d.name, d]));
|
|
649
|
-
const catalogRef = {
|
|
650
|
-
current: new AbilityCatalog({
|
|
651
|
-
integrations: integrationsRef.current,
|
|
652
|
-
toolIndex: toolIndex.byName,
|
|
653
|
-
extraToolDefinitions,
|
|
654
|
-
}),
|
|
655
|
-
};
|
|
656
|
-
const sessionState = new SessionAbilityState();
|
|
657
|
-
const ctx = {
|
|
658
|
-
spaceId,
|
|
659
|
-
db,
|
|
660
|
-
credentialStore,
|
|
661
|
-
proxy,
|
|
662
|
-
credentialSetupBaseUrl: managementUi?.baseUrl,
|
|
663
|
-
integrationsRef,
|
|
664
|
-
integrationTypeConfigsRef,
|
|
665
|
-
toolIndexRef: toolIndex,
|
|
666
|
-
catalogRef,
|
|
667
|
-
};
|
|
668
|
-
return { catalogRef, sessionState, ctx };
|
|
669
|
-
})(),
|
|
670
|
-
}
|
|
671
|
-
: {}),
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
async function openEnvState() {
|
|
675
|
-
const db = createDbFromEnv();
|
|
676
|
-
await ensureSchema(db);
|
|
677
|
-
const secret = getOrCreateEncryptionSecret();
|
|
678
|
-
const credentialStore = new SqlCredentialStore(db, secret);
|
|
679
|
-
return {
|
|
680
|
-
db,
|
|
681
|
-
credentialStore,
|
|
682
|
-
close: async () => {
|
|
683
|
-
if (db.dialect === 'sqlite')
|
|
684
|
-
db.close();
|
|
685
|
-
else
|
|
686
|
-
await db.close();
|
|
687
|
-
},
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
async function runApplyHeadless() {
|
|
691
|
-
const cfgPath = getFlagValue('--config') || process.env.COMMANDABLE_CONFIG_FILE || null;
|
|
692
|
-
const { config, path } = loadConfig(cfgPath || undefined);
|
|
693
|
-
const spaceId = process.env.COMMANDABLE_SPACE_ID || config.spaceId || 'local';
|
|
694
|
-
const { db, credentialStore, close } = await openEnvState();
|
|
695
|
-
try {
|
|
696
|
-
const res = await applyConfig({ config, db, credentialStore, defaultSpaceId: spaceId });
|
|
697
|
-
console.error(`${picocolors.green('Config applied.')}`);
|
|
698
|
-
console.error(`${picocolors.dim('File:')} ${path}`);
|
|
699
|
-
console.error(`${picocolors.dim('Space:')} ${res.spaceId}`);
|
|
700
|
-
console.error(`${picocolors.dim('Integrations upserted:')} ${res.integrationsUpserted}`);
|
|
701
|
-
console.error(`${picocolors.dim('Credentials written:')} ${res.credentialsWritten}`);
|
|
702
|
-
console.error(`${picocolors.dim('Credentials unchanged:')} ${res.credentialsUnchanged}`);
|
|
703
|
-
}
|
|
704
|
-
finally {
|
|
705
|
-
await close();
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
async function runCreateApiKey() {
|
|
709
|
-
const name = process.argv[3] && !process.argv[3].startsWith('-') ? String(process.argv[3]) : 'default';
|
|
710
|
-
const rawKey = generateApiKey();
|
|
711
|
-
const id = crypto.randomUUID ? crypto.randomUUID() : crypto.randomBytes(16).toString('hex');
|
|
712
|
-
const { db, close } = await openEnvState();
|
|
713
|
-
try {
|
|
714
|
-
await createApiKey(db, { id, name, rawKey });
|
|
715
|
-
console.error(`${picocolors.green('API key created.')}`);
|
|
716
|
-
console.error(`${picocolors.dim('Name:')} ${name}`);
|
|
717
|
-
console.error(`${picocolors.dim('ID:')} ${id}`);
|
|
718
|
-
console.error(`${picocolors.dim('Key (store this now):')} ${rawKey}`);
|
|
719
|
-
}
|
|
720
|
-
finally {
|
|
721
|
-
await close();
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
export async function main() {
|
|
725
|
-
const cmd = process.argv[2];
|
|
726
|
-
if (hasFlag('--version', '-v')) {
|
|
727
|
-
console.error(COMMANDABLE_VERSION);
|
|
728
|
-
process.exit(0);
|
|
729
|
-
}
|
|
730
|
-
if (hasFlag('--help', '-h'))
|
|
731
|
-
help(0);
|
|
732
|
-
if (cmd === 'serve')
|
|
733
|
-
return await runServe();
|
|
734
|
-
if (cmd === 'create')
|
|
735
|
-
return runCreate();
|
|
736
|
-
if (cmd === 'connect')
|
|
737
|
-
return runConnect();
|
|
738
|
-
if (cmd === 'static-init') {
|
|
739
|
-
const cfgPath = getFlagValue('--config') || process.env.COMMANDABLE_CONFIG_FILE || null;
|
|
740
|
-
if (cfgPath)
|
|
741
|
-
return await runApplyHeadless();
|
|
742
|
-
return await runInitInteractive();
|
|
743
|
-
}
|
|
744
|
-
if (cmd === 'add')
|
|
745
|
-
return await runAddInteractive();
|
|
746
|
-
if (cmd === 'status') {
|
|
747
|
-
const { db, close } = await openLocalState();
|
|
748
|
-
try {
|
|
749
|
-
const items = await listIntegrations(db, 'local');
|
|
750
|
-
if (!items.length) {
|
|
751
|
-
console.error('No integrations configured.');
|
|
752
|
-
return;
|
|
753
|
-
}
|
|
754
|
-
console.error('Enabled integrations:');
|
|
755
|
-
for (const it of items)
|
|
756
|
-
console.error(`- ${it.type}`);
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
finally {
|
|
760
|
-
await close();
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
if (cmd === 'apply')
|
|
764
|
-
return await runApplyHeadless();
|
|
765
|
-
if (cmd === 'doctor')
|
|
766
|
-
return await runDoctor();
|
|
767
|
-
if (cmd === 'destroy') {
|
|
768
|
-
const sub = (process.argv[3] || '').trim().toLowerCase();
|
|
769
|
-
if (sub === 'local')
|
|
770
|
-
return await runDestroyLocal();
|
|
771
|
-
help(1);
|
|
772
|
-
}
|
|
773
|
-
if (cmd === 'setup') {
|
|
774
|
-
const sub = (process.argv[3] || '').trim().toLowerCase();
|
|
775
|
-
if (sub === 'claude-code')
|
|
776
|
-
return runCreate();
|
|
777
|
-
help(1);
|
|
778
|
-
}
|
|
779
|
-
if (cmd === 'refresh') {
|
|
780
|
-
const sub = (process.argv[3] || '').trim().toLowerCase();
|
|
781
|
-
if (sub === 'local-dev')
|
|
782
|
-
return await runRefreshLocalDev();
|
|
783
|
-
help(1);
|
|
784
|
-
}
|
|
785
|
-
if (cmd === 'create-api-key')
|
|
786
|
-
return await runCreateApiKey();
|
|
787
|
-
if (cmd === 'create-mode')
|
|
788
|
-
return await runStdioFromDb('create');
|
|
789
|
-
if (cmd === 'daemon') {
|
|
790
|
-
const sub = (process.argv[3] || '').trim().toLowerCase();
|
|
791
|
-
const uiPort = getUiPort();
|
|
792
|
-
const baseUrl = `http://127.0.0.1:${uiPort}`;
|
|
793
|
-
if (sub === 'status' || !sub) {
|
|
794
|
-
const pid = readDaemonPid();
|
|
795
|
-
const alive = pid ? isProcessAlive(pid.pid) : false;
|
|
796
|
-
const probe = await fetchJsonWithTimeout(`${baseUrl}/api/_commandable/status`, 400).catch(() => null);
|
|
797
|
-
const ok = !!probe?.ok;
|
|
798
|
-
const probeVersion = typeof probe?.json?.version === 'string' && probe.json.version.trim().length ? probe.json.version.trim() : null;
|
|
799
|
-
const runningVersion = probeVersion || pid?.version || null;
|
|
800
|
-
console.error(JSON.stringify({
|
|
801
|
-
running: alive && ok,
|
|
802
|
-
pid,
|
|
803
|
-
baseUrl,
|
|
804
|
-
installedVersion: COMMANDABLE_VERSION,
|
|
805
|
-
runningVersion,
|
|
806
|
-
versionMatch: !!runningVersion && runningVersion === COMMANDABLE_VERSION,
|
|
807
|
-
status: probe?.json ?? null,
|
|
808
|
-
}, null, 2));
|
|
809
|
-
return;
|
|
810
|
-
}
|
|
811
|
-
if (sub === 'stop') {
|
|
812
|
-
const stopped = stopDaemonProcess();
|
|
813
|
-
console.error(stopped.stopped
|
|
814
|
-
? `Stopped daemon${stopped.pid ? ` (pid ${stopped.pid})` : ''}.`
|
|
815
|
-
: 'No daemon PID found; nothing to stop.');
|
|
816
|
-
return;
|
|
817
|
-
}
|
|
818
|
-
if (sub === 'start') {
|
|
819
|
-
await runServeLocal({ restart: false });
|
|
820
|
-
return;
|
|
821
|
-
}
|
|
822
|
-
if (sub === 'restart') {
|
|
823
|
-
await runServeLocal({ restart: true });
|
|
824
|
-
return;
|
|
825
|
-
}
|
|
826
|
-
help(1);
|
|
827
|
-
}
|
|
828
|
-
if (cmd && !cmd.startsWith('-'))
|
|
829
|
-
help(1);
|
|
830
|
-
return await runStdioFromDb();
|
|
831
|
-
}
|
|
832
|
-
//# sourceMappingURL=index.js.map
|