@kya-os/create-mcpi-app 1.7.37 → 1.7.38-canary.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.
@@ -7,7 +7,7 @@
7
7
  * @module @kya-os/create-mcpi-app/config-builder
8
8
  */
9
9
  import type { MCPIConfig } from '@kya-os/contracts/config';
10
- import { type RemoteConfigCache } from '@kya-os/mcp-i-core';
10
+ import { type RemoteConfigCache } from '../utils/fetch-remote-config.js';
11
11
  /**
12
12
  * Options for building configuration with remote fetching support
13
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"config-builder.d.ts","sourceRoot":"","sources":["../../src/helpers/config-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,UAAU,EAQX,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEzB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEzE;;;OAGG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,UAAU,CA4DpE;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,CAAC,CAwBrB"}
1
+ {"version":3,"file":"config-builder.d.ts","sourceRoot":"","sources":["../../src/helpers/config-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,UAAU,EAQX,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEzB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEzE;;;OAGG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,UAAU,CA4DpE;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,CAAC,CAwBrB"}
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @module @kya-os/create-mcpi-app/config-builder
8
8
  */
9
- import { fetchRemoteConfig } from '@kya-os/mcp-i-core';
9
+ import { fetchRemoteConfig } from '../utils/fetch-remote-config.js';
10
10
  /**
11
11
  * Build base MCPIConfig that works across all platforms
12
12
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config-builder.js","sourceRoot":"","sources":["../../src/helpers/config-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,OAAO,EACL,iBAAiB,EAGlB,MAAM,oBAAoB,CAAC;AAgC5B;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,GAAwB;IACtD,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,WAAW,IAAI,aAAa,CAAiC,CAAC;IACvG,MAAM,aAAa,GAAG,WAAW,KAAK,aAAa,CAAC;IAEpD,MAAM,UAAU,GAAe;QAC7B,WAAW;QAEX,QAAQ,EAAE;YACR,OAAO,EAAE,IAAI;YACb,WAAW;YACX,eAAe,EAAE,qBAAqB;SACd;QAE1B,QAAQ,EAAE;YACR,OAAO,EAAE,IAAI;YACb,UAAU,EAAE;gBACV,YAAY,EAAE;oBACZ;wBACE,IAAI,EAAE,aAAsB;wBAC5B,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,wBAAwB;wBAC3D,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,EAAE;qBACtC;iBACF;gBACD,YAAY,EAAE,EAAE;gBAChB,eAAe,EAAE,IAAI;gBACrB,UAAU,EAAE,CAAC;gBACb,KAAK,EAAE,aAAa;aACrB;SACgB;QAEnB,UAAU,EAAE;YACV,OAAO,EAAE,IAAI;YACb,kBAAkB,EAAE,IAAI;YACxB,QAAQ,EAAE;gBACR,IAAI,EAAE,aAAsB;gBAC5B,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,wBAAwB;gBAC3D,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,EAAE;gBACrC,QAAQ,EAAE,KAAK,EAAE,iBAAiB;gBAClC,KAAK,EAAE,aAAa;aACO;YAC7B,aAAa,EAAE;gBACb,gBAAgB,EAAE,GAAG,CAAC,iBAAiB,IAAI,GAAG,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,YAAY;gBAC7G,cAAc,EAAE,MAAM,EAAE,aAAa;gBACrC,kBAAkB,EAAE,EAAE;aACA;SACL;QAErB,KAAK,EAAE;YACL,OAAO,EAAE,IAAI;YACb,kBAAkB,EAAE,KAAK;YACzB,eAAe,EAAE,KAAK;SACvB;QAED,OAAO,EAAE;YACP,oBAAoB,EAAE,GAAG;YACzB,UAAU,EAAE,EAAE;SACf;KACF,CAAC;IAEF,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAA6B;IAE7B,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAExD,sEAAsE;IACtE,IAAI,GAAG,CAAC,mBAAmB,IAAI,aAAa,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC;YACE,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,wBAAwB;YAC3D,MAAM,EAAE,GAAG,CAAC,mBAAmB;YAC/B,SAAS,EAAE,GAAG,CAAC,sBAAsB;YACrC,QAAQ;YACR,QAAQ,EAAE,MAAM,EAAE,YAAY;YAC9B,aAAa;SACd,EACD,KAAK,CACN,CAAC;QAEF,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"config-builder.js","sourceRoot":"","sources":["../../src/helpers/config-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,OAAO,EACL,iBAAiB,EAGlB,MAAM,iCAAiC,CAAC;AAgCzC;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,GAAwB;IACtD,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,WAAW,IAAI,aAAa,CAAiC,CAAC;IACvG,MAAM,aAAa,GAAG,WAAW,KAAK,aAAa,CAAC;IAEpD,MAAM,UAAU,GAAe;QAC7B,WAAW;QAEX,QAAQ,EAAE;YACR,OAAO,EAAE,IAAI;YACb,WAAW;YACX,eAAe,EAAE,qBAAqB;SACd;QAE1B,QAAQ,EAAE;YACR,OAAO,EAAE,IAAI;YACb,UAAU,EAAE;gBACV,YAAY,EAAE;oBACZ;wBACE,IAAI,EAAE,aAAsB;wBAC5B,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,wBAAwB;wBAC3D,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,EAAE;qBACtC;iBACF;gBACD,YAAY,EAAE,EAAE;gBAChB,eAAe,EAAE,IAAI;gBACrB,UAAU,EAAE,CAAC;gBACb,KAAK,EAAE,aAAa;aACrB;SACgB;QAEnB,UAAU,EAAE;YACV,OAAO,EAAE,IAAI;YACb,kBAAkB,EAAE,IAAI;YACxB,QAAQ,EAAE;gBACR,IAAI,EAAE,aAAsB;gBAC5B,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,wBAAwB;gBAC3D,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,EAAE;gBACrC,QAAQ,EAAE,KAAK,EAAE,iBAAiB;gBAClC,KAAK,EAAE,aAAa;aACO;YAC7B,aAAa,EAAE;gBACb,gBAAgB,EAAE,GAAG,CAAC,iBAAiB,IAAI,GAAG,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,YAAY;gBAC7G,cAAc,EAAE,MAAM,EAAE,aAAa;gBACrC,kBAAkB,EAAE,EAAE;aACA;SACL;QAErB,KAAK,EAAE;YACL,OAAO,EAAE,IAAI;YACb,kBAAkB,EAAE,KAAK;YACzB,eAAe,EAAE,KAAK;SACvB;QAED,OAAO,EAAE;YACP,oBAAoB,EAAE,GAAG;YACzB,UAAU,EAAE,EAAE;SACf;KACF,CAAC;IAEF,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAA6B;IAE7B,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAExD,sEAAsE;IACtE,IAAI,GAAG,CAAC,mBAAmB,IAAI,aAAa,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC;YACE,MAAM,EAAE,GAAG,CAAC,mBAAmB,IAAI,wBAAwB;YAC3D,MAAM,EAAE,GAAG,CAAC,mBAAmB;YAC/B,SAAS,EAAE,GAAG,CAAC,sBAAsB;YACrC,QAAQ;YACR,QAAQ,EAAE,MAAM,EAAE,YAAY;YAC9B,aAAa;SACd,EACD,KAAK,CACN,CAAC;QAEF,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC"}
@@ -1,4 +1,4 @@
1
- import { ScaffolderResult } from "@kya-os/contracts";
1
+ import type { ScaffolderResult } from "@kya-os/contracts";
2
2
  interface CreateProjectOptions {
3
3
  projectPath: string;
4
4
  projectName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/helpers/create.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AA4CrD,UAAU,oBAAoB;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AASD;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAkJ3B"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/helpers/create.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AA4C1D,UAAU,oBAAoB;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AASD;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAkJ3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"generate-config.d.ts","sourceRoot":"","sources":["../../src/helpers/generate-config.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAAE,EACpB,YAAY,UAAQ,GACnB,IAAI,CAkDN"}
1
+ {"version":3,"file":"generate-config.d.ts","sourceRoot":"","sources":["../../src/helpers/generate-config.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAAE,EACpB,YAAY,UAAQ,GACnB,IAAI,CAkDN"}
@@ -1 +1 @@
1
- {"version":3,"file":"generate-config.js","sourceRoot":"","sources":["../../src/helpers/generate-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,UAAU,cAAc,CAC5B,WAAmB,EACnB,UAAoB,EACpB,YAAY,GAAG,KAAK;IAEpB,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE9C,IAAI,aAAa,GAAG;;;;;;KAMjB,CAAC;IAEJ,0CAA0C;IAC1C,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,aAAa,IAAI;;;;;;KAMhB,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,aAAa,IAAI;;;cAGP,CAAC;IACb,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,aAAa,IAAI;;;eAGN,CAAC;IACd,CAAC;IAED,aAAa,IAAI;;;;CAIlB,CAAC;IAEA,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC5D,yCAAyC;IACzC,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9B,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAE5C,8DAA8D;IAC9D,qBAAqB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,WAAmB,EAAE,YAAqB;IACvE,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiD9B,CAAC;IAEA,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAClF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;IAChD,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;AAC5D,CAAC"}
1
+ {"version":3,"file":"generate-config.js","sourceRoot":"","sources":["../../src/helpers/generate-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,UAAU,cAAc,CAC5B,WAAmB,EACnB,UAAoB,EACpB,YAAY,GAAG,KAAK;IAEpB,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE9C,IAAI,aAAa,GAAG;;;;;;KAMjB,CAAC;IAEJ,0CAA0C;IAC1C,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,aAAa,IAAI;;;;;;KAMhB,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,aAAa,IAAI;;;cAGP,CAAC;IACb,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,aAAa,IAAI;;;eAGN,CAAC;IACd,CAAC;IAED,aAAa,IAAI;;;;CAIlB,CAAC;IAEA,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC5D,yCAAyC;IACzC,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9B,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAE5C,8DAA8D;IAC9D,qBAAqB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,WAAmB,EAAE,YAAqB;IACvE,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiD9B,CAAC;IAEA,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAClF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;IAChD,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Remote Configuration Fetching
3
+ *
4
+ * Service for fetching configuration from remote APIs (AgentShield dashboard)
5
+ * with caching support for performance optimization.
6
+ *
7
+ * NOTE: This implementation is extracted from @kya-os/mcp-i-core/src/config/remote-config.ts
8
+ * to avoid runtime dependency on the entire mcp-i-core package.
9
+ *
10
+ * Source: packages/mcp-i-core/src/config/remote-config.ts
11
+ *
12
+ * @module @kya-os/create-mcpi-app/utils/fetch-remote-config
13
+ */
14
+ import type { MCPIConfig } from '@kya-os/contracts/config';
15
+ /**
16
+ * Options for fetching remote configuration
17
+ */
18
+ export interface RemoteConfigOptions {
19
+ /**
20
+ * API base URL
21
+ * @example 'https://kya.vouched.id'
22
+ */
23
+ apiUrl: string;
24
+ /**
25
+ * API key for authentication
26
+ */
27
+ apiKey: string;
28
+ /**
29
+ * Project ID (optional, preferred over agentDid)
30
+ * Used for project-scoped configuration
31
+ */
32
+ projectId?: string;
33
+ /**
34
+ * Agent DID (optional, used when projectId not available)
35
+ * Used for agent-scoped configuration
36
+ */
37
+ agentDid?: string;
38
+ /**
39
+ * Cache TTL in milliseconds
40
+ * @default 300000 (5 minutes)
41
+ */
42
+ cacheTtl?: number;
43
+ /**
44
+ * Fetch provider function
45
+ * Platform-agnostic fetch implementation
46
+ */
47
+ fetchProvider: (url: string, options: RequestInit) => Promise<Response>;
48
+ }
49
+ /**
50
+ * Cache interface for remote configuration
51
+ * Abstracts platform-specific caching (KV, Redis, Memory, etc.)
52
+ */
53
+ export interface RemoteConfigCache {
54
+ /**
55
+ * Get a cached value
56
+ */
57
+ get(key: string): Promise<string | null>;
58
+ /**
59
+ * Set a cached value with TTL
60
+ */
61
+ set(key: string, value: string, ttl: number): Promise<void>;
62
+ }
63
+ /**
64
+ * Fetch configuration from remote API (AgentShield dashboard)
65
+ *
66
+ * Attempts to fetch configuration from the AgentShield API with caching support.
67
+ * Falls back gracefully if remote fetch fails.
68
+ *
69
+ * @param options - Remote config options
70
+ * @param cache - Optional cache implementation
71
+ * @returns Configuration object or null if fetch fails
72
+ */
73
+ export declare function fetchRemoteConfig(options: RemoteConfigOptions, cache?: RemoteConfigCache): Promise<MCPIConfig | null>;
74
+ //# sourceMappingURL=fetch-remote-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-remote-config.d.ts","sourceRoot":"","sources":["../../src/utils/fetch-remote-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAG3D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CACzE;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEzC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,mBAAmB,EAC5B,KAAK,CAAC,EAAE,iBAAiB,GACxB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA2F5B"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Remote Configuration Fetching
3
+ *
4
+ * Service for fetching configuration from remote APIs (AgentShield dashboard)
5
+ * with caching support for performance optimization.
6
+ *
7
+ * NOTE: This implementation is extracted from @kya-os/mcp-i-core/src/config/remote-config.ts
8
+ * to avoid runtime dependency on the entire mcp-i-core package.
9
+ *
10
+ * Source: packages/mcp-i-core/src/config/remote-config.ts
11
+ *
12
+ * @module @kya-os/create-mcpi-app/utils/fetch-remote-config
13
+ */
14
+ import { AGENTSHIELD_ENDPOINTS } from '@kya-os/contracts/agentshield-api';
15
+ /**
16
+ * Fetch configuration from remote API (AgentShield dashboard)
17
+ *
18
+ * Attempts to fetch configuration from the AgentShield API with caching support.
19
+ * Falls back gracefully if remote fetch fails.
20
+ *
21
+ * @param options - Remote config options
22
+ * @param cache - Optional cache implementation
23
+ * @returns Configuration object or null if fetch fails
24
+ */
25
+ export async function fetchRemoteConfig(options, cache) {
26
+ const { apiUrl, apiKey, projectId, agentDid, cacheTtl = 300000, fetchProvider } = options;
27
+ // Generate cache key
28
+ const cacheKey = projectId
29
+ ? `config:project:${projectId}`
30
+ : agentDid
31
+ ? `config:agent:${agentDid}`
32
+ : null;
33
+ // Try cache first
34
+ if (cache && cacheKey) {
35
+ try {
36
+ const cached = await cache.get(cacheKey);
37
+ if (cached) {
38
+ try {
39
+ const parsed = JSON.parse(cached);
40
+ if (parsed.expiresAt > Date.now()) {
41
+ return parsed.config;
42
+ }
43
+ }
44
+ catch {
45
+ // Invalid cache entry, continue to fetch
46
+ }
47
+ }
48
+ }
49
+ catch (error) {
50
+ // Cache read failed, continue to fetch
51
+ console.warn('[RemoteConfig] Cache read failed:', error);
52
+ }
53
+ }
54
+ // Fetch from API
55
+ try {
56
+ // Build API URL
57
+ let url;
58
+ if (projectId) {
59
+ // Use project-scoped endpoint (preferred)
60
+ url = `${apiUrl}${AGENTSHIELD_ENDPOINTS.CONFIG(projectId)}`;
61
+ }
62
+ else if (agentDid) {
63
+ // Use agent-scoped endpoint
64
+ url = `${apiUrl}/api/v1/bouncer/config?agent_did=${encodeURIComponent(agentDid)}`;
65
+ }
66
+ else {
67
+ console.warn('[RemoteConfig] Neither projectId nor agentDid provided');
68
+ return null;
69
+ }
70
+ const response = await fetchProvider(url, {
71
+ headers: {
72
+ 'Authorization': `Bearer ${apiKey}`,
73
+ 'Content-Type': 'application/json'
74
+ }
75
+ });
76
+ if (!response.ok) {
77
+ console.warn(`[RemoteConfig] API returned ${response.status}: ${response.statusText}`);
78
+ return null;
79
+ }
80
+ const data = await response.json();
81
+ // Extract config from API response
82
+ // API response format: { success: boolean, data: { config: MCPIConfig } }
83
+ const responseData = data;
84
+ const config = responseData.config || responseData.data?.config || (responseData.success ? responseData.data : null);
85
+ if (!config) {
86
+ console.warn('[RemoteConfig] No config found in API response');
87
+ return null;
88
+ }
89
+ // Cache the result
90
+ if (cache && cacheKey) {
91
+ try {
92
+ await cache.set(cacheKey, JSON.stringify({
93
+ config,
94
+ expiresAt: Date.now() + cacheTtl
95
+ }), cacheTtl);
96
+ }
97
+ catch (error) {
98
+ // Cache write failed, but we got the config so continue
99
+ console.warn('[RemoteConfig] Cache write failed:', error);
100
+ }
101
+ }
102
+ return config;
103
+ }
104
+ catch (error) {
105
+ console.warn('[RemoteConfig] Failed to fetch config:', error);
106
+ return null;
107
+ }
108
+ }
109
+ //# sourceMappingURL=fetch-remote-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-remote-config.js","sourceRoot":"","sources":["../../src/utils/fetch-remote-config.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kya-os/create-mcpi-app",
3
- "version": "1.7.37",
3
+ "version": "1.7.38-canary.0",
4
4
  "description": "Bootstrap MCP applications with identity features",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -30,25 +30,17 @@
30
30
  "dependencies": {
31
31
  "@kya-os/cli": "^1.3.3",
32
32
  "@kya-os/cli-effects": "^1.0.19",
33
- "@kya-os/contracts": "^1.5.1",
34
- "@kya-os/mcp-i": "^1.5.5",
35
- "@kya-os/mcp-i-core": "^1.1.12",
36
- "@noble/ed25519": "^2.1.0",
37
- "axios": "^1.12.0",
38
33
  "base-x": "^5.0.0",
39
34
  "chalk": "^5.3.0",
40
35
  "commander": "^11.1.0",
41
- "dotenv-cli": "^7.4.4",
42
36
  "fs-extra": "^11.2.0",
43
37
  "inquirer": "^12.9.4",
44
- "jose": "^6.0.12",
45
- "node-fetch": "^3.3.2",
46
38
  "ora": "^8.0.1",
47
- "swc-loader": "^0.2.6",
48
- "tsx": "^4.20.4",
49
39
  "zod": "^3.25.76"
50
40
  },
51
41
  "devDependencies": {
42
+ "@kya-os/contracts": "^1.5.1",
43
+ "@kya-os/mcp-i": "^1.5.5",
52
44
  "@types/fs-extra": "^11.0.4",
53
45
  "@types/inquirer": "^9.0.7",
54
46
  "@types/node": "^20.19.19",
@@ -57,6 +49,9 @@
57
49
  "typescript": "^5.3.0",
58
50
  "vitest": "^4.0.5"
59
51
  },
52
+ "peerDependencies": {
53
+ "@kya-os/mcp-i": ">=1.5.0"
54
+ },
60
55
  "keywords": [
61
56
  "mcp",
62
57
  "mcp-i",
@@ -22,7 +22,7 @@ import {
22
22
  fetchRemoteConfig,
23
23
  type RemoteConfigOptions,
24
24
  type RemoteConfigCache
25
- } from '@kya-os/mcp-i-core';
25
+ } from '../utils/fetch-remote-config.js';
26
26
 
27
27
  /**
28
28
  * Options for building configuration with remote fetching support
@@ -10,7 +10,7 @@ import {
10
10
  validateProjectStructure,
11
11
  ensureLockfile,
12
12
  } from "./validate-project-structure.js";
13
- import { ScaffolderResult } from "@kya-os/contracts";
13
+ import type { ScaffolderResult } from "@kya-os/contracts";
14
14
  import chalk from "chalk";
15
15
  import crypto from "crypto";
16
16
 
@@ -1,6 +1,5 @@
1
1
  import fs from "fs-extra";
2
2
  import path from "path";
3
- import type { NodeRuntimeConfig } from "@kya-os/mcp-i";
4
3
 
5
4
  export function generateConfig(
6
5
  projectPath: string,
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Tests for Remote Configuration Fetching
3
+ *
4
+ * Validates that remote config fetching works correctly with caching
5
+ * and fallback behavior.
6
+ *
7
+ * These tests mirror the tests in @kya-os/mcp-i-core to ensure
8
+ * behavior matches the original implementation.
9
+ */
10
+
11
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
12
+ import {
13
+ fetchRemoteConfig,
14
+ type RemoteConfigOptions,
15
+ type RemoteConfigCache
16
+ } from '../fetch-remote-config.js';
17
+ import type { MCPIConfig } from '@kya-os/contracts/config';
18
+
19
+ describe('fetchRemoteConfig', () => {
20
+ let mockFetch: ReturnType<typeof vi.fn>;
21
+ let mockCache: RemoteConfigCache;
22
+
23
+ beforeEach(() => {
24
+ mockFetch = vi.fn();
25
+ mockCache = {
26
+ get: vi.fn(),
27
+ set: vi.fn()
28
+ };
29
+ });
30
+
31
+ describe('Cache hit scenario', () => {
32
+ it('should return cached config if available and not expired', async () => {
33
+ const cachedConfig: MCPIConfig = {
34
+ environment: 'production',
35
+ identity: { enabled: true, environment: 'production' }
36
+ };
37
+
38
+ vi.mocked(mockCache.get).mockResolvedValue(
39
+ JSON.stringify({
40
+ config: cachedConfig,
41
+ expiresAt: Date.now() + 60000 // 1 minute in future
42
+ })
43
+ );
44
+
45
+ const options: RemoteConfigOptions = {
46
+ apiUrl: 'https://kya.vouched.id',
47
+ apiKey: 'test-key',
48
+ projectId: 'test-project',
49
+ fetchProvider: mockFetch
50
+ };
51
+
52
+ const result = await fetchRemoteConfig(options, mockCache);
53
+
54
+ expect(result).toEqual(cachedConfig);
55
+ expect(mockCache.get).toHaveBeenCalledWith('config:project:test-project');
56
+ expect(mockFetch).not.toHaveBeenCalled();
57
+ });
58
+
59
+ it('should fetch fresh config if cache expired', async () => {
60
+ const cachedConfig: MCPIConfig = {
61
+ environment: 'production'
62
+ };
63
+
64
+ vi.mocked(mockCache.get).mockResolvedValue(
65
+ JSON.stringify({
66
+ config: cachedConfig,
67
+ expiresAt: Date.now() - 1000 // Expired
68
+ })
69
+ );
70
+
71
+ const freshConfig: MCPIConfig = {
72
+ environment: 'production',
73
+ identity: { enabled: true, environment: 'production' }
74
+ };
75
+
76
+ mockFetch.mockResolvedValue({
77
+ ok: true,
78
+ json: async () => ({ success: true, data: freshConfig })
79
+ } as Response);
80
+
81
+ const options: RemoteConfigOptions = {
82
+ apiUrl: 'https://kya.vouched.id',
83
+ apiKey: 'test-key',
84
+ projectId: 'test-project',
85
+ fetchProvider: mockFetch
86
+ };
87
+
88
+ const result = await fetchRemoteConfig(options, mockCache);
89
+
90
+ expect(result).toEqual(freshConfig);
91
+ expect(mockFetch).toHaveBeenCalled();
92
+ });
93
+ });
94
+
95
+ describe('Cache miss scenario', () => {
96
+ it('should fetch from API when cache is empty', async () => {
97
+ vi.mocked(mockCache.get).mockResolvedValue(null);
98
+
99
+ const config: MCPIConfig = {
100
+ environment: 'production',
101
+ identity: { enabled: true, environment: 'production' }
102
+ };
103
+
104
+ mockFetch.mockResolvedValue({
105
+ ok: true,
106
+ json: async () => ({ success: true, data: config })
107
+ } as Response);
108
+
109
+ const options: RemoteConfigOptions = {
110
+ apiUrl: 'https://kya.vouched.id',
111
+ apiKey: 'test-key',
112
+ projectId: 'test-project',
113
+ fetchProvider: mockFetch
114
+ };
115
+
116
+ const result = await fetchRemoteConfig(options, mockCache);
117
+
118
+ expect(result).toEqual(config);
119
+ expect(mockCache.set).toHaveBeenCalled();
120
+ });
121
+
122
+ it('should use agentDid when projectId not available', async () => {
123
+ vi.mocked(mockCache.get).mockResolvedValue(null);
124
+
125
+ const config: MCPIConfig = {
126
+ environment: 'production'
127
+ };
128
+
129
+ mockFetch.mockResolvedValue({
130
+ ok: true,
131
+ json: async () => ({ success: true, data: config })
132
+ } as Response);
133
+
134
+ const options: RemoteConfigOptions = {
135
+ apiUrl: 'https://kya.vouched.id',
136
+ apiKey: 'test-key',
137
+ agentDid: 'did:key:test',
138
+ fetchProvider: mockFetch
139
+ };
140
+
141
+ const result = await fetchRemoteConfig(options, mockCache);
142
+
143
+ expect(result).toEqual(config);
144
+ expect(mockCache.get).toHaveBeenCalledWith('config:agent:did:key:test');
145
+ });
146
+ });
147
+
148
+ describe('Error handling', () => {
149
+ it('should return null if API request fails', async () => {
150
+ vi.mocked(mockCache.get).mockResolvedValue(null);
151
+
152
+ mockFetch.mockResolvedValue({
153
+ ok: false,
154
+ status: 404,
155
+ statusText: 'Not Found'
156
+ } as Response);
157
+
158
+ const options: RemoteConfigOptions = {
159
+ apiUrl: 'https://kya.vouched.id',
160
+ apiKey: 'test-key',
161
+ projectId: 'test-project',
162
+ fetchProvider: mockFetch
163
+ };
164
+
165
+ const result = await fetchRemoteConfig(options, mockCache);
166
+
167
+ expect(result).toBeNull();
168
+ });
169
+
170
+ it('should return null if API throws error', async () => {
171
+ vi.mocked(mockCache.get).mockResolvedValue(null);
172
+
173
+ mockFetch.mockRejectedValue(new Error('Network error'));
174
+
175
+ const options: RemoteConfigOptions = {
176
+ apiUrl: 'https://kya.vouched.id',
177
+ apiKey: 'test-key',
178
+ projectId: 'test-project',
179
+ fetchProvider: mockFetch
180
+ };
181
+
182
+ const result = await fetchRemoteConfig(options, mockCache);
183
+
184
+ expect(result).toBeNull();
185
+ });
186
+
187
+ it('should return null if neither projectId nor agentDid provided', async () => {
188
+ const options: RemoteConfigOptions = {
189
+ apiUrl: 'https://kya.vouched.id',
190
+ apiKey: 'test-key',
191
+ fetchProvider: mockFetch
192
+ };
193
+
194
+ const result = await fetchRemoteConfig(options, mockCache);
195
+
196
+ expect(result).toBeNull();
197
+ expect(mockFetch).not.toHaveBeenCalled();
198
+ });
199
+
200
+ it('should handle cache read errors gracefully', async () => {
201
+ vi.mocked(mockCache.get).mockRejectedValue(new Error('Cache error'));
202
+
203
+ const config: MCPIConfig = {
204
+ environment: 'production'
205
+ };
206
+
207
+ mockFetch.mockResolvedValue({
208
+ ok: true,
209
+ json: async () => ({ success: true, data: config })
210
+ } as Response);
211
+
212
+ const options: RemoteConfigOptions = {
213
+ apiUrl: 'https://kya.vouched.id',
214
+ apiKey: 'test-key',
215
+ projectId: 'test-project',
216
+ fetchProvider: mockFetch
217
+ };
218
+
219
+ const result = await fetchRemoteConfig(options, mockCache);
220
+
221
+ expect(result).toEqual(config);
222
+ });
223
+ });
224
+
225
+ describe('Response format handling', () => {
226
+ it('should handle different API response formats', async () => {
227
+ vi.mocked(mockCache.get).mockResolvedValue(null);
228
+
229
+ const config: MCPIConfig = {
230
+ environment: 'production'
231
+ };
232
+
233
+ // Format 1: { config: {...} }
234
+ mockFetch.mockResolvedValueOnce({
235
+ ok: true,
236
+ json: async () => ({ config })
237
+ } as Response);
238
+
239
+ const options: RemoteConfigOptions = {
240
+ apiUrl: 'https://kya.vouched.id',
241
+ apiKey: 'test-key',
242
+ projectId: 'test-project',
243
+ fetchProvider: mockFetch
244
+ };
245
+
246
+ const result1 = await fetchRemoteConfig(options, mockCache);
247
+ expect(result1).toEqual(config);
248
+
249
+ // Format 2: { data: { config: {...} } }
250
+ vi.mocked(mockCache.get).mockResolvedValue(null);
251
+ mockFetch.mockResolvedValueOnce({
252
+ ok: true,
253
+ json: async () => ({ data: { config } })
254
+ } as Response);
255
+
256
+ const result2 = await fetchRemoteConfig(options, mockCache);
257
+ expect(result2).toEqual(config);
258
+
259
+ // Format 3: { success: true, data: {...} }
260
+ vi.mocked(mockCache.get).mockResolvedValue(null);
261
+ mockFetch.mockResolvedValueOnce({
262
+ ok: true,
263
+ json: async () => ({ success: true, data: config })
264
+ } as Response);
265
+
266
+ const result3 = await fetchRemoteConfig(options, mockCache);
267
+ expect(result3).toEqual(config);
268
+ });
269
+ });
270
+ });
271
+