feat: Complete zCode CLI X with Telegram bot integration

- Add full Telegram bot functionality with Z.AI API integration
- Implement 4 tools: Bash, FileEdit, WebSearch, Git
- Add 3 agents: Code Reviewer, Architect, DevOps Engineer
- Add 6 skills for common coding tasks
- Add systemd service file for 24/7 operation
- Add nginx configuration for HTTPS webhook
- Add comprehensive documentation
- Implement WebSocket server for real-time updates
- Add logging system with Winston
- Add environment validation

🤖 zCode CLI X - Agentic coder with Z.AI + Telegram integration
This commit is contained in:
admin
2026-05-05 09:01:26 +00:00
Unverified
parent 4a7035dd92
commit 875c7f9b91
24688 changed files with 3224957 additions and 221 deletions

View File

@@ -0,0 +1,9 @@
import { OTLPGRPCExporterConfigNode } from '../types';
import { OtlpGrpcConfiguration } from './otlp-grpc-configuration';
/**
* @deprecated
* @param config
* @param signalIdentifier
*/
export declare function convertLegacyOtlpGrpcOptions(config: OTLPGRPCExporterConfigNode, signalIdentifier: string): OtlpGrpcConfiguration;
//# sourceMappingURL=convert-legacy-otlp-grpc-options.d.ts.map

View File

@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertLegacyOtlpGrpcOptions = void 0;
const api_1 = require("@opentelemetry/api");
const otlp_grpc_configuration_1 = require("./otlp-grpc-configuration");
const grpc_exporter_transport_1 = require("../grpc-exporter-transport");
const otlp_grpc_env_configuration_1 = require("./otlp-grpc-env-configuration");
/**
* @deprecated
* @param config
* @param signalIdentifier
*/
function convertLegacyOtlpGrpcOptions(config, signalIdentifier) {
if (config.headers) {
api_1.diag.warn('Headers cannot be set when using grpc');
}
// keep credentials locally in case user updates the reference on the config object
const userProvidedCredentials = config.credentials;
return (0, otlp_grpc_configuration_1.mergeOtlpGrpcConfigurationWithDefaults)({
url: config.url,
metadata: () => {
var _a;
// metadata resolution strategy is merge, so we can return empty here, and it will not override the rest of the settings.
return (_a = config.metadata) !== null && _a !== void 0 ? _a : (0, grpc_exporter_transport_1.createEmptyMetadata)();
},
compression: config.compression,
timeoutMillis: config.timeoutMillis,
concurrencyLimit: config.concurrencyLimit,
credentials: userProvidedCredentials != null
? () => userProvidedCredentials
: undefined,
}, (0, otlp_grpc_env_configuration_1.getOtlpGrpcConfigurationFromEnv)(signalIdentifier), (0, otlp_grpc_configuration_1.getOtlpGrpcDefaultConfiguration)());
}
exports.convertLegacyOtlpGrpcOptions = convertLegacyOtlpGrpcOptions;
//# sourceMappingURL=convert-legacy-otlp-grpc-options.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"convert-legacy-otlp-grpc-options.js","sourceRoot":"","sources":["../../../src/configuration/convert-legacy-otlp-grpc-options.ts"],"names":[],"mappings":";;;AAgBA,4CAA0C;AAC1C,uEAImC;AACnC,wEAAiE;AACjE,+EAAgF;AAEhF;;;;GAIG;AACH,SAAgB,4BAA4B,CAC1C,MAAkC,EAClC,gBAAwB;IAExB,IAAI,MAAM,CAAC,OAAO,EAAE;QAClB,UAAI,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;KACpD;IAED,mFAAmF;IACnF,MAAM,uBAAuB,GAAG,MAAM,CAAC,WAAW,CAAC;IACnD,OAAO,IAAA,gEAAsC,EAC3C;QACE,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,QAAQ,EAAE,GAAG,EAAE;;YACb,yHAAyH;YACzH,OAAO,MAAA,MAAM,CAAC,QAAQ,mCAAI,IAAA,6CAAmB,GAAE,CAAC;QAClD,CAAC;QACD,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,WAAW,EACT,uBAAuB,IAAI,IAAI;YAC7B,CAAC,CAAC,GAAG,EAAE,CAAC,uBAAuB;YAC/B,CAAC,CAAC,SAAS;KAChB,EACD,IAAA,6DAA+B,EAAC,gBAAgB,CAAC,EACjD,IAAA,yDAA+B,GAAE,CAClC,CAAC;AACJ,CAAC;AA5BD,oEA4BC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { OTLPGRPCExporterConfigNode } from '../types';\nimport { diag } from '@opentelemetry/api';\nimport {\n getOtlpGrpcDefaultConfiguration,\n mergeOtlpGrpcConfigurationWithDefaults,\n OtlpGrpcConfiguration,\n} from './otlp-grpc-configuration';\nimport { createEmptyMetadata } from '../grpc-exporter-transport';\nimport { getOtlpGrpcConfigurationFromEnv } from './otlp-grpc-env-configuration';\n\n/**\n * @deprecated\n * @param config\n * @param signalIdentifier\n */\nexport function convertLegacyOtlpGrpcOptions(\n config: OTLPGRPCExporterConfigNode,\n signalIdentifier: string\n): OtlpGrpcConfiguration {\n if (config.headers) {\n diag.warn('Headers cannot be set when using grpc');\n }\n\n // keep credentials locally in case user updates the reference on the config object\n const userProvidedCredentials = config.credentials;\n return mergeOtlpGrpcConfigurationWithDefaults(\n {\n url: config.url,\n metadata: () => {\n // metadata resolution strategy is merge, so we can return empty here, and it will not override the rest of the settings.\n return config.metadata ?? createEmptyMetadata();\n },\n compression: config.compression,\n timeoutMillis: config.timeoutMillis,\n concurrencyLimit: config.concurrencyLimit,\n credentials:\n userProvidedCredentials != null\n ? () => userProvidedCredentials\n : undefined,\n },\n getOtlpGrpcConfigurationFromEnv(signalIdentifier),\n getOtlpGrpcDefaultConfiguration()\n );\n}\n"]}

View File

@@ -0,0 +1,22 @@
import { OtlpSharedConfiguration } from '@opentelemetry/otlp-exporter-base';
import type { ChannelCredentials, Metadata } from '@grpc/grpc-js';
export interface OtlpGrpcConfiguration extends OtlpSharedConfiguration {
url: string;
metadata: () => Metadata;
credentials: () => ChannelCredentials;
}
/**
* Unresolved configuration where parts of the config may depend on other config options being resolved first.
*/
export interface UnresolvedOtlpGrpcConfiguration extends OtlpSharedConfiguration {
url: string;
metadata: () => Metadata;
/**
* Credentials are based on the final resolved URL
*/
credentials: (url: string) => () => ChannelCredentials;
}
export declare function validateAndNormalizeUrl(url: string): string;
export declare function mergeOtlpGrpcConfigurationWithDefaults(userProvidedConfiguration: Partial<OtlpGrpcConfiguration>, fallbackConfiguration: Partial<UnresolvedOtlpGrpcConfiguration>, defaultConfiguration: UnresolvedOtlpGrpcConfiguration): OtlpGrpcConfiguration;
export declare function getOtlpGrpcDefaultConfiguration(): UnresolvedOtlpGrpcConfiguration;
//# sourceMappingURL=otlp-grpc-configuration.d.ts.map

View File

@@ -0,0 +1,82 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getOtlpGrpcDefaultConfiguration = exports.mergeOtlpGrpcConfigurationWithDefaults = exports.validateAndNormalizeUrl = void 0;
const otlp_exporter_base_1 = require("@opentelemetry/otlp-exporter-base");
const grpc_exporter_transport_1 = require("../grpc-exporter-transport");
const version_1 = require("../version");
const url_1 = require("url");
const api_1 = require("@opentelemetry/api");
function validateAndNormalizeUrl(url) {
var _a;
url = url.trim();
const hasProtocol = url.match(/^([\w]{1,8}):\/\//);
if (!hasProtocol) {
url = `https://${url}`;
}
const target = new url_1.URL(url);
if (target.protocol === 'unix:') {
return url;
}
if (target.pathname && target.pathname !== '/') {
api_1.diag.warn('URL path should not be set when using grpc, the path part of the URL will be ignored.');
}
if (target.protocol !== '' && !((_a = target.protocol) === null || _a === void 0 ? void 0 : _a.match(/^(http)s?:$/))) {
api_1.diag.warn('URL protocol should be http(s)://. Using http://.');
}
return target.host;
}
exports.validateAndNormalizeUrl = validateAndNormalizeUrl;
function overrideMetadataEntriesIfNotPresent(metadata, additionalMetadata) {
for (const [key, value] of Object.entries(additionalMetadata.getMap())) {
// only override with env var data if the key has no values.
// not using Metadata.merge() as it will keep both values.
if (metadata.get(key).length < 1) {
metadata.set(key, value);
}
}
}
function mergeOtlpGrpcConfigurationWithDefaults(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration) {
var _a, _b, _c, _d, _e;
const rawUrl = (_b = (_a = userProvidedConfiguration.url) !== null && _a !== void 0 ? _a : fallbackConfiguration.url) !== null && _b !== void 0 ? _b : defaultConfiguration.url;
return Object.assign(Object.assign({}, (0, otlp_exporter_base_1.mergeOtlpSharedConfigurationWithDefaults)(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration)), { metadata: () => {
var _a, _b, _c, _d;
const metadata = defaultConfiguration.metadata();
overrideMetadataEntriesIfNotPresent(metadata,
// clone to ensure we don't modify what the user gave us in case they hold on to the returned reference
(_b = (_a = userProvidedConfiguration.metadata) === null || _a === void 0 ? void 0 : _a.call(userProvidedConfiguration).clone()) !== null && _b !== void 0 ? _b : (0, grpc_exporter_transport_1.createEmptyMetadata)());
overrideMetadataEntriesIfNotPresent(metadata, (_d = (_c = fallbackConfiguration.metadata) === null || _c === void 0 ? void 0 : _c.call(fallbackConfiguration)) !== null && _d !== void 0 ? _d : (0, grpc_exporter_transport_1.createEmptyMetadata)());
return metadata;
}, url: validateAndNormalizeUrl(rawUrl), credentials: (_e = (_c = userProvidedConfiguration.credentials) !== null && _c !== void 0 ? _c : (_d = fallbackConfiguration.credentials) === null || _d === void 0 ? void 0 : _d.call(fallbackConfiguration, rawUrl)) !== null && _e !== void 0 ? _e : defaultConfiguration.credentials(rawUrl) });
}
exports.mergeOtlpGrpcConfigurationWithDefaults = mergeOtlpGrpcConfigurationWithDefaults;
function getOtlpGrpcDefaultConfiguration() {
return Object.assign(Object.assign({}, (0, otlp_exporter_base_1.getSharedConfigurationDefaults)()), { metadata: () => {
const metadata = (0, grpc_exporter_transport_1.createEmptyMetadata)();
metadata.set('User-Agent', `OTel-OTLP-Exporter-JavaScript/${version_1.VERSION}`);
return metadata;
}, url: 'http://localhost:4317', credentials: (url) => {
if (url.startsWith('http://')) {
return () => (0, grpc_exporter_transport_1.createInsecureCredentials)();
}
else {
return () => (0, grpc_exporter_transport_1.createSslCredentials)();
}
} });
}
exports.getOtlpGrpcDefaultConfiguration = getOtlpGrpcDefaultConfiguration;
//# sourceMappingURL=otlp-grpc-configuration.js.map

View File

@@ -0,0 +1,3 @@
import { UnresolvedOtlpGrpcConfiguration } from './otlp-grpc-configuration';
export declare function getOtlpGrpcConfigurationFromEnv(signalIdentifier: string): Partial<UnresolvedOtlpGrpcConfiguration>;
//# sourceMappingURL=otlp-grpc-env-configuration.d.ts.map

View File

@@ -0,0 +1,154 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getOtlpGrpcConfigurationFromEnv = void 0;
const core_1 = require("@opentelemetry/core");
const grpc_exporter_transport_1 = require("../grpc-exporter-transport");
const node_http_1 = require("@opentelemetry/otlp-exporter-base/node-http");
const fs = require("fs");
const path = require("path");
const api_1 = require("@opentelemetry/api");
function fallbackIfNullishOrBlank(signalSpecific, nonSignalSpecific) {
if (signalSpecific != null && signalSpecific !== '') {
return signalSpecific;
}
if (nonSignalSpecific != null && nonSignalSpecific !== '') {
return nonSignalSpecific;
}
return undefined;
}
function getMetadataFromEnv(signalIdentifier) {
var _a, _b;
const signalSpecificRawHeaders = (_a = process.env[`OTEL_EXPORTER_OTLP_${signalIdentifier}_HEADERS`]) === null || _a === void 0 ? void 0 : _a.trim();
const nonSignalSpecificRawHeaders = (_b = process.env['OTEL_EXPORTER_OTLP_HEADERS']) === null || _b === void 0 ? void 0 : _b.trim();
const signalSpecificHeaders = core_1.baggageUtils.parseKeyPairsIntoRecord(signalSpecificRawHeaders);
const nonSignalSpecificHeaders = core_1.baggageUtils.parseKeyPairsIntoRecord(nonSignalSpecificRawHeaders);
if (Object.keys(signalSpecificHeaders).length === 0 &&
Object.keys(nonSignalSpecificHeaders).length === 0) {
return undefined;
}
const mergeHeaders = Object.assign({}, nonSignalSpecificHeaders, signalSpecificHeaders);
const metadata = (0, grpc_exporter_transport_1.createEmptyMetadata)();
// for this to work, metadata MUST be empty - otherwise `Metadata#set()` will merge items.
for (const [key, value] of Object.entries(mergeHeaders)) {
metadata.set(key, value);
}
return metadata;
}
function getMetadataProviderFromEnv(signalIdentifier) {
const metadata = getMetadataFromEnv(signalIdentifier);
if (metadata == null) {
return undefined;
}
return () => metadata;
}
function getUrlFromEnv(signalIdentifier) {
// This does not change the string beyond trimming on purpose.
// Normally a user would just use a host and port for gRPC, but the OTLP Exporter specification requires us to
// use the raw provided endpoint to derive credential settings. Therefore, we only normalize right when
// we merge user-provided, env-provided and defaults together, and we have determined which credentials to use.
//
// Examples:
// - example.test:4317 -> use secure credentials from environment (or provided via code)
// - http://example.test:4317 -> use insecure credentials if nothing else is provided
// - https://example.test:4317 -> use secure credentials from environment (or provided via code)
var _a, _b;
const specificEndpoint = (_a = process.env[`OTEL_EXPORTER_OTLP_${signalIdentifier}_ENDPOINT`]) === null || _a === void 0 ? void 0 : _a.trim();
const nonSpecificEndpoint = (_b = process.env[`OTEL_EXPORTER_OTLP_ENDPOINT`]) === null || _b === void 0 ? void 0 : _b.trim();
return fallbackIfNullishOrBlank(specificEndpoint, nonSpecificEndpoint);
}
/**
* Determines whether the env var for insecure credentials is set to {@code true}.
*
* It will allow the following values as {@code true}
* - 'true'
* - 'true '
* - ' true'
* - 'TrUE'
* - 'TRUE'
*
* It will not allow:
* - 'true false'
* - 'false true'
* - 'true!'
* - 'true,true'
* - '1'
* - ' '
*
* @param signalIdentifier
*/
function getInsecureSettingFromEnv(signalIdentifier) {
var _a, _b;
const signalSpecificInsecureValue = (_a = process.env[`OTEL_EXPORTER_OTLP_${signalIdentifier}_INSECURE`]) === null || _a === void 0 ? void 0 : _a.toLowerCase().trim();
const nonSignalSpecificInsecureValue = (_b = process.env[`OTEL_EXPORTER_OTLP_INSECURE`]) === null || _b === void 0 ? void 0 : _b.toLowerCase().trim();
return (fallbackIfNullishOrBlank(signalSpecificInsecureValue, nonSignalSpecificInsecureValue) === 'true');
}
function readFileFromEnv(signalSpecificEnvVar, nonSignalSpecificEnvVar, warningMessage) {
var _a, _b;
const signalSpecificPath = (_a = process.env[signalSpecificEnvVar]) === null || _a === void 0 ? void 0 : _a.trim();
const nonSignalSpecificPath = (_b = process.env[nonSignalSpecificEnvVar]) === null || _b === void 0 ? void 0 : _b.trim();
const filePath = fallbackIfNullishOrBlank(signalSpecificPath, nonSignalSpecificPath);
if (filePath != null) {
try {
return fs.readFileSync(path.resolve(process.cwd(), filePath));
}
catch (_c) {
api_1.diag.warn(warningMessage);
return undefined;
}
}
else {
return undefined;
}
}
function getClientCertificateFromEnv(signalIdentifier) {
return readFileFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_CLIENT_CERTIFICATE`, 'OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE', 'Failed to read client certificate chain file');
}
function getClientKeyFromEnv(signalIdentifier) {
return readFileFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_CLIENT_KEY`, 'OTEL_EXPORTER_OTLP_CLIENT_KEY', 'Failed to read client certificate private key file');
}
function getRootCertificateFromEnv(signalIdentifier) {
return readFileFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_CERTIFICATE`, 'OTEL_EXPORTER_OTLP_CERTIFICATE', 'Failed to read root certificate file');
}
function getCredentialsFromEnvIgnoreInsecure(signalIdentifier) {
const clientKey = getClientKeyFromEnv(signalIdentifier);
const clientCertificate = getClientCertificateFromEnv(signalIdentifier);
const rootCertificate = getRootCertificateFromEnv(signalIdentifier);
// if the chain is not intact, @grpc/grpc-js will throw. This is fine when a user provides it in code, but env var
// config is not allowed to throw, so we add this safeguard and try to make the best of it here.
const clientChainIntact = clientKey != null && clientCertificate != null;
if (rootCertificate != null && !clientChainIntact) {
api_1.diag.warn('Client key and certificate must both be provided, but one was missing - attempting to create credentials from just the root certificate');
return (0, grpc_exporter_transport_1.createSslCredentials)(getRootCertificateFromEnv(signalIdentifier));
}
return (0, grpc_exporter_transport_1.createSslCredentials)(rootCertificate, clientKey, clientCertificate);
}
function getCredentialsFromEnv(signalIdentifier) {
if (getInsecureSettingFromEnv(signalIdentifier)) {
return (0, grpc_exporter_transport_1.createInsecureCredentials)();
}
return getCredentialsFromEnvIgnoreInsecure(signalIdentifier);
}
function getOtlpGrpcConfigurationFromEnv(signalIdentifier) {
return Object.assign(Object.assign({}, (0, node_http_1.getSharedConfigurationFromEnvironment)(signalIdentifier)), { metadata: getMetadataProviderFromEnv(signalIdentifier), url: getUrlFromEnv(signalIdentifier), credentials: (finalResolvedUrl) => {
// Always assume insecure on http:// and secure on https://, the protocol always takes precedence over the insecure setting.
// note: the spec does not make any exception for
// - "localhost:4317". If the protocol is omitted, credentials are required unless insecure is set
// - "unix://", as it's neither http:// nor https:// and therefore credentials are required unless insecure is set
if (finalResolvedUrl.startsWith('http://')) {
return () => {
return (0, grpc_exporter_transport_1.createInsecureCredentials)();
};
}
else if (finalResolvedUrl.startsWith('https://')) {
return () => {
return getCredentialsFromEnvIgnoreInsecure(signalIdentifier);
};
}
// defer to env settings in this case
return () => {
return getCredentialsFromEnv(signalIdentifier);
};
} });
}
exports.getOtlpGrpcConfigurationFromEnv = getOtlpGrpcConfigurationFromEnv;
//# sourceMappingURL=otlp-grpc-env-configuration.js.map