Compare commits

..

6 Commits

Author SHA1 Message Date
3a4d510304 v2.2.2
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-03-24 16:12:35 +00:00
b1f135a5f4 fix(config): rename npmextra configuration file to .smartconfig.json 2026-03-24 16:12:35 +00:00
30a5749fab v2.2.1
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-03-24 15:07:15 +00:00
100f37b857 fix(config): switch configuration loading from npmextra to smartconfig 2026-03-24 15:07:15 +00:00
93cf2ee7bf v2.2.0
Some checks failed
Default (tags) / security (push) Failing after 1s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-03-19 10:18:10 +00:00
8cf8e43e59 feat(cli/buildx): add pull control for builds and isolate buildx builders per project 2026-03-19 10:18:10 +00:00
12 changed files with 81 additions and 26 deletions

View File

@@ -1,5 +1,25 @@
# Changelog # Changelog
## 2026-03-24 - 2.2.2 - fix(config)
rename npmextra configuration file to .smartconfig.json
- Moves the existing project metadata and release configuration from npmextra.json to .smartconfig.json without changing its contents.
## 2026-03-24 - 2.2.1 - fix(config)
switch configuration loading from npmextra to smartconfig
- replace the @push.rocks/npmextra dependency with @push.rocks/smartconfig
- update config initialization to use Smartconfig for the @git.zone/tsdocker settings
- refresh CLI help text to reference smartconfig.json instead of npmextra.json
## 2026-03-19 - 2.2.0 - feat(cli/buildx)
add pull control for builds and isolate buildx builders per project
- adds a new pull build option with --no-pull CLI support and defaults builds to refreshing base images with --pull
- passes the selected buildx builder explicitly into build commands instead of relying on global docker buildx use state
- generates project-hashed builder suffixes so concurrent runs from different project directories do not share the same local builder
- updates session logging to include project hash and builder suffix for easier build diagnostics
## 2026-03-15 - 2.1.0 - feat(cli) ## 2026-03-15 - 2.1.0 - feat(cli)
add global remote builder configuration and native SSH buildx nodes for multi-platform builds add global remote builder configuration and native SSH buildx nodes for multi-platform builds

View File

@@ -1,6 +1,6 @@
{ {
"name": "@git.zone/tsdocker", "name": "@git.zone/tsdocker",
"version": "2.1.0", "version": "2.2.2",
"private": false, "private": false,
"description": "develop npm modules cross platform with docker", "description": "develop npm modules cross platform with docker",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
@@ -34,7 +34,7 @@
}, },
"dependencies": { "dependencies": {
"@push.rocks/lik": "^6.3.1", "@push.rocks/lik": "^6.3.1",
"@push.rocks/npmextra": "^5.3.3", "@push.rocks/smartconfig": "^6.0.0",
"@push.rocks/projectinfo": "^5.0.2", "@push.rocks/projectinfo": "^5.0.2",
"@push.rocks/smartcli": "^4.0.20", "@push.rocks/smartcli": "^4.0.20",
"@push.rocks/smartfs": "^1.5.0", "@push.rocks/smartfs": "^1.5.0",

26
pnpm-lock.yaml generated
View File

@@ -11,15 +11,15 @@ importers:
'@push.rocks/lik': '@push.rocks/lik':
specifier: ^6.3.1 specifier: ^6.3.1
version: 6.3.1 version: 6.3.1
'@push.rocks/npmextra':
specifier: ^5.3.3
version: 5.3.3
'@push.rocks/projectinfo': '@push.rocks/projectinfo':
specifier: ^5.0.2 specifier: ^5.0.2
version: 5.0.2 version: 5.0.2
'@push.rocks/smartcli': '@push.rocks/smartcli':
specifier: ^4.0.20 specifier: ^4.0.20
version: 4.0.20 version: 4.0.20
'@push.rocks/smartconfig':
specifier: ^6.0.0
version: 6.0.0
'@push.rocks/smartfs': '@push.rocks/smartfs':
specifier: ^1.5.0 specifier: ^1.5.0
version: 1.5.0 version: 1.5.0
@@ -897,6 +897,9 @@ packages:
'@push.rocks/smartclickhouse@2.2.0': '@push.rocks/smartclickhouse@2.2.0':
resolution: {integrity: sha512-eTzKiREIPSzL1kPkVyD6vEbn+WV/DvQqDjP67VlhNlQGbRcemnJG/eLrUUR1ytmdIqnsZGEK6UYBgyj5nhzLNQ==} resolution: {integrity: sha512-eTzKiREIPSzL1kPkVyD6vEbn+WV/DvQqDjP67VlhNlQGbRcemnJG/eLrUUR1ytmdIqnsZGEK6UYBgyj5nhzLNQ==}
'@push.rocks/smartconfig@6.0.0':
resolution: {integrity: sha512-ohXwJdbDXV2budErnZKWBOz01YkjP6gJsZ7QM9+6Wsh+r7O1CVT3JpV+mD8xJWy5tZRHI+3B9L8z0+WkIDtKzw==}
'@push.rocks/smartcrypto@2.0.4': '@push.rocks/smartcrypto@2.0.4':
resolution: {integrity: sha512-1+/5bsjyataf5uUkUNnnVXGRAt+gHVk1KDzozjTqgqJxHvQk1d9fVDohL6CxUhUucTPtu5VR5xNBiV8YCDuGyw==} resolution: {integrity: sha512-1+/5bsjyataf5uUkUNnnVXGRAt+gHVk1KDzozjTqgqJxHvQk1d9fVDohL6CxUhUucTPtu5VR5xNBiV8YCDuGyw==}
@@ -4970,6 +4973,23 @@ snapshots:
'@push.rocks/smarturl': 3.1.0 '@push.rocks/smarturl': 3.1.0
'@push.rocks/webrequest': 4.0.5 '@push.rocks/webrequest': 4.0.5
'@push.rocks/smartconfig@6.0.0':
dependencies:
'@push.rocks/qenv': 6.1.3
'@push.rocks/smartfile': 11.2.7
'@push.rocks/smartjson': 5.2.0
'@push.rocks/smartlog': 3.2.1
'@push.rocks/smartpath': 6.0.0
'@push.rocks/smartpromise': 4.2.3
'@push.rocks/smartrx': 3.0.10
'@push.rocks/taskbuffer': 3.5.0
'@tsclass/tsclass': 9.3.0
transitivePeerDependencies:
- '@nuxt/kit'
- react
- supports-color
- vue
'@push.rocks/smartcrypto@2.0.4': '@push.rocks/smartcrypto@2.0.4':
dependencies: dependencies:
'@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartpromise': 4.2.3

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@git.zone/tsdocker', name: '@git.zone/tsdocker',
version: '2.1.0', version: '2.2.2',
description: 'develop npm modules cross platform with docker' description: 'develop npm modules cross platform with docker'
} }

View File

@@ -266,7 +266,7 @@ export class Dockerfile {
public static async buildDockerfiles( public static async buildDockerfiles(
sortedArrayArg: Dockerfile[], sortedArrayArg: Dockerfile[],
session: TsDockerSession, session: TsDockerSession,
options?: { platform?: string; timeout?: number; noCache?: boolean; verbose?: boolean; isRootless?: boolean; parallel?: boolean; parallelConcurrency?: number; onRegistryStarted?: () => Promise<void>; onBeforeRegistryStop?: () => Promise<void> }, options?: { platform?: string; timeout?: number; noCache?: boolean; pull?: boolean; verbose?: boolean; isRootless?: boolean; parallel?: boolean; parallelConcurrency?: number; onRegistryStarted?: () => Promise<void>; onBeforeRegistryStop?: () => Promise<void> },
): Promise<Dockerfile[]> { ): Promise<Dockerfile[]> {
const total = sortedArrayArg.length; const total = sortedArrayArg.length;
const overallStart = Date.now(); const overallStart = Date.now();
@@ -668,13 +668,14 @@ export class Dockerfile {
/** /**
* Builds the Dockerfile * Builds the Dockerfile
*/ */
public async build(options?: { platform?: string; timeout?: number; noCache?: boolean; verbose?: boolean }): Promise<number> { public async build(options?: { platform?: string; timeout?: number; noCache?: boolean; pull?: boolean; verbose?: boolean }): Promise<number> {
const startTime = Date.now(); const startTime = Date.now();
const buildArgsString = await Dockerfile.getDockerBuildArgs(this.managerRef); const buildArgsString = await Dockerfile.getDockerBuildArgs(this.managerRef);
const config = this.managerRef.config; const config = this.managerRef.config;
const platformOverride = options?.platform; const platformOverride = options?.platform;
const timeout = options?.timeout; const timeout = options?.timeout;
const noCacheFlag = options?.noCache ? ' --no-cache' : ''; const noCacheFlag = options?.noCache ? ' --no-cache' : '';
const pullFlag = options?.pull !== false ? ' --pull' : '';
const verbose = options?.verbose ?? false; const verbose = options?.verbose ?? false;
let buildContextFlag = ''; let buildContextFlag = '';
@@ -689,23 +690,24 @@ export class Dockerfile {
} }
let buildCommand: string; let buildCommand: string;
const builderFlag = this.managerRef.currentBuilderName ? ` --builder ${this.managerRef.currentBuilderName}` : '';
if (platformOverride) { if (platformOverride) {
// Single platform override via buildx // Single platform override via buildx
buildCommand = `docker buildx build --progress=plain --platform ${platformOverride}${noCacheFlag}${buildContextFlag} --load -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`; buildCommand = `docker buildx build${builderFlag} --progress=plain --platform ${platformOverride}${noCacheFlag}${pullFlag}${buildContextFlag} --load -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`;
logger.log('info', `Build: buildx --platform ${platformOverride} --load`); logger.log('info', `Build: buildx --platform ${platformOverride} --load`);
} else if (config.platforms && config.platforms.length > 1) { } else if (config.platforms && config.platforms.length > 1) {
// Multi-platform build using buildx — always push to local registry // Multi-platform build using buildx — always push to local registry
const platformString = config.platforms.join(','); const platformString = config.platforms.join(',');
const registryHost = this.session?.config.registryHost || 'localhost:5234'; const registryHost = this.session?.config.registryHost || 'localhost:5234';
const localTag = `${registryHost}/${this.buildTag}`; const localTag = `${registryHost}/${this.buildTag}`;
buildCommand = `docker buildx build --progress=plain --platform ${platformString}${noCacheFlag}${buildContextFlag} -t ${localTag} -f ${this.filePath} ${buildArgsString} --push .`; buildCommand = `docker buildx build${builderFlag} --progress=plain --platform ${platformString}${noCacheFlag}${pullFlag}${buildContextFlag} -t ${localTag} -f ${this.filePath} ${buildArgsString} --push .`;
this.localRegistryTag = localTag; this.localRegistryTag = localTag;
logger.log('info', `Build: buildx --platform ${platformString} --push to local registry`); logger.log('info', `Build: buildx --platform ${platformString} --push to local registry`);
} else { } else {
// Standard build // Standard build
const versionLabel = this.managerRef.projectInfo?.npm?.version || 'unknown'; const versionLabel = this.managerRef.projectInfo?.npm?.version || 'unknown';
buildCommand = `docker build --progress=plain --label="version=${versionLabel}"${noCacheFlag} -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`; buildCommand = `docker build --progress=plain --label="version=${versionLabel}"${noCacheFlag}${pullFlag} -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`;
logger.log('info', 'Build: docker build (standard)'); logger.log('info', 'Build: docker build (standard)');
} }

View File

@@ -25,6 +25,7 @@ export class TsDockerManager {
public projectInfo: any; public projectInfo: any;
public dockerContext: DockerContext; public dockerContext: DockerContext;
public session!: TsDockerSession; public session!: TsDockerSession;
public currentBuilderName?: string;
private dockerfiles: Dockerfile[] = []; private dockerfiles: Dockerfile[] = [];
private activeRemoteBuilders: IRemoteBuilder[] = []; private activeRemoteBuilders: IRemoteBuilder[] = [];
private sshTunnelManager?: SshTunnelManager; private sshTunnelManager?: SshTunnelManager;
@@ -266,6 +267,7 @@ export class TsDockerManager {
platform: options?.platform, platform: options?.platform,
timeout: options?.timeout, timeout: options?.timeout,
noCache: options?.noCache, noCache: options?.noCache,
pull: options?.pull,
verbose: options?.verbose, verbose: options?.verbose,
}); });
logger.log('ok', `${progress} Built ${df.cleanTag} in ${formatDuration(elapsed)}`); logger.log('ok', `${progress} Built ${df.cleanTag} in ${formatDuration(elapsed)}`);
@@ -311,6 +313,7 @@ export class TsDockerManager {
platform: options?.platform, platform: options?.platform,
timeout: options?.timeout, timeout: options?.timeout,
noCache: options?.noCache, noCache: options?.noCache,
pull: options?.pull,
verbose: options?.verbose, verbose: options?.verbose,
}); });
logger.log('ok', `${progress} Built ${dockerfileArg.cleanTag} in ${formatDuration(elapsed)}`); logger.log('ok', `${progress} Built ${dockerfileArg.cleanTag} in ${formatDuration(elapsed)}`);
@@ -349,6 +352,7 @@ export class TsDockerManager {
platform: options?.platform, platform: options?.platform,
timeout: options?.timeout, timeout: options?.timeout,
noCache: options?.noCache, noCache: options?.noCache,
pull: options?.pull,
verbose: options?.verbose, verbose: options?.verbose,
isRootless: this.dockerContext.contextInfo?.isRootless, isRootless: this.dockerContext.contextInfo?.isRootless,
parallel: options?.parallel, parallel: options?.parallel,
@@ -401,6 +405,7 @@ export class TsDockerManager {
await this.ensureBuildxLocal(builderName); await this.ensureBuildxLocal(builderName);
} }
this.currentBuilderName = builderName;
logger.log('ok', `Docker buildx ready (builder: ${builderName}, platforms: ${platforms})`); logger.log('ok', `Docker buildx ready (builder: ${builderName}, platforms: ${platforms})`);
} }
@@ -426,7 +431,7 @@ export class TsDockerManager {
// Create the local node // Create the local node
const localPlatformFlag = localPlatforms.length > 0 ? ` --platform ${localPlatforms.join(',')}` : ''; const localPlatformFlag = localPlatforms.length > 0 ? ` --platform ${localPlatforms.join(',')}` : '';
await smartshellInstance.exec( await smartshellInstance.exec(
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host${localPlatformFlag} --use` `docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host${localPlatformFlag}`
); );
// Append remote nodes // Append remote nodes
@@ -441,7 +446,7 @@ export class TsDockerManager {
} }
// Bootstrap all nodes // Bootstrap all nodes
await smartshellInstance.exec('docker buildx inspect --bootstrap'); await smartshellInstance.exec(`docker buildx inspect --builder ${builderName} --bootstrap`);
// Store active remote builders for SSH tunnel setup during build // Store active remote builders for SSH tunnel setup during build
this.activeRemoteBuilders = remoteBuilders; this.activeRemoteBuilders = remoteBuilders;
@@ -456,20 +461,18 @@ export class TsDockerManager {
if (inspectResult.exitCode !== 0) { if (inspectResult.exitCode !== 0) {
logger.log('info', 'Creating new buildx builder with host network...'); logger.log('info', 'Creating new buildx builder with host network...');
await smartshellInstance.exec( await smartshellInstance.exec(
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host --use` `docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host`
); );
await smartshellInstance.exec('docker buildx inspect --bootstrap'); await smartshellInstance.exec(`docker buildx inspect --builder ${builderName} --bootstrap`);
} else { } else {
const inspectOutput = inspectResult.stdout || ''; const inspectOutput = inspectResult.stdout || '';
if (!inspectOutput.includes('network=host')) { if (!inspectOutput.includes('network=host')) {
logger.log('info', 'Recreating buildx builder with host network (migration)...'); logger.log('info', 'Recreating buildx builder with host network (migration)...');
await smartshellInstance.exec(`docker buildx rm ${builderName} 2>/dev/null`); await smartshellInstance.exec(`docker buildx rm ${builderName} 2>/dev/null`);
await smartshellInstance.exec( await smartshellInstance.exec(
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host --use` `docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host`
); );
await smartshellInstance.exec('docker buildx inspect --bootstrap'); await smartshellInstance.exec(`docker buildx inspect --builder ${builderName} --bootstrap`);
} else {
await smartshellInstance.exec(`docker buildx use ${builderName}`);
} }
} }
this.activeRemoteBuilders = []; this.activeRemoteBuilders = [];

View File

@@ -4,6 +4,7 @@ import { logger } from './tsdocker.logging.js';
export interface ISessionConfig { export interface ISessionConfig {
sessionId: string; sessionId: string;
projectHash: string;
registryPort: number; registryPort: number;
registryHost: string; registryHost: string;
registryContainerName: string; registryContainerName: string;
@@ -17,8 +18,8 @@ export interface ISessionConfig {
* Generates unique ports, container names, and builder names so that * Generates unique ports, container names, and builder names so that
* concurrent CI jobs on the same Docker host don't collide. * concurrent CI jobs on the same Docker host don't collide.
* *
* In local (non-CI) dev the builder suffix is empty, preserving the * In local (non-CI) dev the builder suffix contains a project hash so
* persistent builder behavior. * that concurrent runs in different project directories use separate builders.
*/ */
export class TsDockerSession { export class TsDockerSession {
public config: ISessionConfig; public config: ISessionConfig;
@@ -34,16 +35,18 @@ export class TsDockerSession {
public static async create(): Promise<TsDockerSession> { public static async create(): Promise<TsDockerSession> {
const sessionId = const sessionId =
process.env.TSDOCKER_SESSION_ID || crypto.randomBytes(4).toString('hex'); process.env.TSDOCKER_SESSION_ID || crypto.randomBytes(4).toString('hex');
const projectHash = crypto.createHash('sha256').update(process.cwd()).digest('hex').substring(0, 8);
const registryPort = await TsDockerSession.allocatePort(); const registryPort = await TsDockerSession.allocatePort();
const registryHost = `localhost:${registryPort}`; const registryHost = `localhost:${registryPort}`;
const registryContainerName = `tsdocker-registry-${sessionId}`; const registryContainerName = `tsdocker-registry-${sessionId}`;
const { isCI, ciSystem } = TsDockerSession.detectCI(); const { isCI, ciSystem } = TsDockerSession.detectCI();
const builderSuffix = isCI ? `-${sessionId}` : ''; const builderSuffix = isCI ? `-${projectHash}-${sessionId}` : `-${projectHash}`;
const config: ISessionConfig = { const config: ISessionConfig = {
sessionId, sessionId,
projectHash,
registryPort, registryPort,
registryHost, registryHost,
registryContainerName, registryContainerName,
@@ -99,9 +102,10 @@ export class TsDockerSession {
logger.log('info', '=== TSDOCKER SESSION ==='); logger.log('info', '=== TSDOCKER SESSION ===');
logger.log('info', `Session ID: ${c.sessionId}`); logger.log('info', `Session ID: ${c.sessionId}`);
logger.log('info', `Registry: ${c.registryHost} (container: ${c.registryContainerName})`); logger.log('info', `Registry: ${c.registryHost} (container: ${c.registryContainerName})`);
logger.log('info', `Project hash: ${c.projectHash}`);
logger.log('info', `Builder suffix: ${c.builderSuffix}`);
if (c.isCI) { if (c.isCI) {
logger.log('info', `CI detected: ${c.ciSystem}`); logger.log('info', `CI detected: ${c.ciSystem}`);
logger.log('info', `Builder suffix: ${c.builderSuffix}`);
} }
} }
} }

View File

@@ -69,6 +69,7 @@ export interface IBuildCommandOptions {
platform?: string; // Single platform override (e.g., 'linux/arm64') platform?: string; // Single platform override (e.g., 'linux/arm64')
timeout?: number; // Build timeout in seconds timeout?: number; // Build timeout in seconds
noCache?: boolean; // Force rebuild without Docker layer cache (--no-cache) noCache?: boolean; // Force rebuild without Docker layer cache (--no-cache)
pull?: boolean; // Pull fresh base images before building (default: true)
cached?: boolean; // Skip builds when Dockerfile content hasn't changed cached?: boolean; // Skip builds when Dockerfile content hasn't changed
verbose?: boolean; // Stream raw docker build output (default: silent) verbose?: boolean; // Stream raw docker build output (default: silent)
context?: string; // Explicit Docker context name (--context flag) context?: string; // Explicit Docker context name (--context flag)

View File

@@ -41,6 +41,7 @@ BUILD / PUSH OPTIONS
--platform=<p> Target platform (e.g. linux/arm64) --platform=<p> Target platform (e.g. linux/arm64)
--timeout=<s> Build timeout in seconds --timeout=<s> Build timeout in seconds
--no-cache Rebuild without Docker layer cache --no-cache Rebuild without Docker layer cache
--no-pull Skip pulling latest base images (use cached)
--cached Skip builds when Dockerfile is unchanged --cached Skip builds when Dockerfile is unchanged
--verbose Stream raw docker build output --verbose Stream raw docker build output
--parallel[=<n>] Parallel builds (optional concurrency limit) --parallel[=<n>] Parallel builds (optional concurrency limit)
@@ -66,7 +67,7 @@ CONFIG SUBCOMMANDS
show Show full global config show Show full global config
CONFIGURATION CONFIGURATION
Configure via npmextra.json under the "@git.zone/tsdocker" key: Configure via smartconfig.json under the "@git.zone/tsdocker" key:
registries Array of registry URLs to push to registries Array of registry URLs to push to
registryRepoMap Map of registry URL to repo path overrides registryRepoMap Map of registry URL to repo path overrides
@@ -120,6 +121,8 @@ export let run = () => {
if (argvArg.cache === false) { if (argvArg.cache === false) {
buildOptions.noCache = true; buildOptions.noCache = true;
} }
// --pull is default true; --no-pull sets pull=false
buildOptions.pull = argvArg.pull !== false;
if (argvArg.cached) { if (argvArg.cached) {
buildOptions.cached = true; buildOptions.cached = true;
} }
@@ -170,6 +173,7 @@ export let run = () => {
if (argvArg.cache === false) { if (argvArg.cache === false) {
buildOptions.noCache = true; buildOptions.noCache = true;
} }
buildOptions.pull = argvArg.pull !== false;
if (argvArg.verbose) { if (argvArg.verbose) {
buildOptions.verbose = true; buildOptions.verbose = true;
} }
@@ -243,6 +247,7 @@ export let run = () => {
if (argvArg.cache === false) { if (argvArg.cache === false) {
buildOptions.noCache = true; buildOptions.noCache = true;
} }
buildOptions.pull = argvArg.pull !== false;
if (argvArg.cached) { if (argvArg.cached) {
buildOptions.cached = true; buildOptions.cached = true;
} }

View File

@@ -3,7 +3,7 @@ import * as paths from './tsdocker.paths.js';
import type { ITsDockerConfig } from './interfaces/index.js'; import type { ITsDockerConfig } from './interfaces/index.js';
const buildConfig = async (): Promise<ITsDockerConfig> => { const buildConfig = async (): Promise<ITsDockerConfig> => {
const npmextra = new plugins.npmextra.Npmextra(paths.cwd); const npmextra = new plugins.npmextra.Smartconfig(paths.cwd);
const config = npmextra.dataFor<ITsDockerConfig>('@git.zone/tsdocker', { const config = npmextra.dataFor<ITsDockerConfig>('@git.zone/tsdocker', {
registries: [], registries: [],
registryRepoMap: {}, registryRepoMap: {},

View File

@@ -1,6 +1,6 @@
// push.rocks scope // push.rocks scope
import * as lik from '@push.rocks/lik'; import * as lik from '@push.rocks/lik';
import * as npmextra from '@push.rocks/npmextra'; import * as npmextra from '@push.rocks/smartconfig';
import * as path from 'path'; import * as path from 'path';
import * as projectinfo from '@push.rocks/projectinfo'; import * as projectinfo from '@push.rocks/projectinfo';
import * as smartcli from '@push.rocks/smartcli'; import * as smartcli from '@push.rocks/smartcli';