@kici-dev/shared 0.1.15 → 0.1.16

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.
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Shared debug-bundle archive primitives.
3
+ *
4
+ * Allowlist config redaction and windowed log-file archiving, used by the
5
+ * orchestrator's in-process bundle writer, the kici-admin CLI's local bundle,
6
+ * and the agent's fleet mini-bundle assembler. Keeping one copy means a node
7
+ * cannot drift from the redaction posture of its peers.
8
+ */
9
+ import type archiver from 'archiver';
10
+ /** Maximum total log bytes to include in bundle (50MB). */
11
+ export declare const MAX_LOG_BYTES: number;
12
+ /**
13
+ * Redact config values using allowlist approach.
14
+ * Only known-safe fields are preserved; everything else becomes "****".
15
+ */
16
+ export declare function redactConfig(obj: unknown, parentKey?: string): unknown;
17
+ /**
18
+ * Add log files from logDir to the archive, respecting MAX_LOG_BYTES cap
19
+ * and the logWindow time filter. Matches any `*.log` file in the directory,
20
+ * so the per-instance filename pattern produced by
21
+ * `buildLogFilename()` is picked up without additional configuration.
22
+ *
23
+ * Exported for reuse by the `kici-admin debug-bundle` CLI command, which
24
+ * runs outside the orchestrator process but still needs to include the
25
+ * same log files in its locally-assembled bundle.
26
+ */
27
+ export declare function addLogsToArchive(archive: archiver.Archiver, logDir: string, logWindowHours: number): Promise<void>;
28
+ //# sourceMappingURL=bundle-archive.d.ts.map
@@ -0,0 +1,141 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+ //#region src/diagnostics/bundle-archive.ts
5
+ /**
6
+ * Shared debug-bundle archive primitives.
7
+ *
8
+ * Allowlist config redaction and windowed log-file archiving, used by the
9
+ * orchestrator's in-process bundle writer, the kici-admin CLI's local bundle,
10
+ * and the agent's fleet mini-bundle assembler. Keeping one copy means a node
11
+ * cannot drift from the redaction posture of its peers.
12
+ */
13
+ /** Maximum total log bytes to include in bundle (50MB). */
14
+ const MAX_LOG_BYTES = 50 * 1024 * 1024;
15
+ /**
16
+ * Config field names that are safe to include unredacted.
17
+ * Everything else gets replaced with "****".
18
+ */
19
+ const SAFE_CONFIG_KEYS = new Set([
20
+ "mode",
21
+ "host",
22
+ "port",
23
+ "logLevel",
24
+ "region",
25
+ "environment",
26
+ "name",
27
+ "label",
28
+ "labels",
29
+ "enabled",
30
+ "disabled",
31
+ "timeout",
32
+ "interval",
33
+ "maxRetries",
34
+ "retries",
35
+ "workers",
36
+ "concurrency",
37
+ "maxConcurrency",
38
+ "batchSize",
39
+ "bufferSize",
40
+ "warmPool",
41
+ "cooldown",
42
+ "type",
43
+ "provider",
44
+ "scaler",
45
+ "driver",
46
+ "backend",
47
+ "protocol",
48
+ "scheme",
49
+ "path",
50
+ "basePath",
51
+ "metricsPath",
52
+ "healthPath",
53
+ "logFormat",
54
+ "logFile",
55
+ "logDir",
56
+ "dataDir",
57
+ "version",
58
+ "debug",
59
+ "verbose",
60
+ "quiet",
61
+ "tls",
62
+ "cors",
63
+ "rateLimiting",
64
+ "maxConnections",
65
+ "poolSize",
66
+ "minPool",
67
+ "maxPool",
68
+ "idleTimeout",
69
+ "connectTimeout",
70
+ "requestTimeout",
71
+ "shutdownTimeout",
72
+ "gracefulShutdown"
73
+ ]);
74
+ /**
75
+ * Redact config values using allowlist approach.
76
+ * Only known-safe fields are preserved; everything else becomes "****".
77
+ */
78
+ function redactConfig(obj, parentKey) {
79
+ if (obj === null || obj === void 0) return obj;
80
+ if (Array.isArray(obj)) return obj.map((item) => redactConfig(item, parentKey));
81
+ if (typeof obj === "object") {
82
+ const result = {};
83
+ for (const [key, value] of Object.entries(obj)) result[key] = redactConfig(value, key);
84
+ return result;
85
+ }
86
+ if (typeof obj === "string" && parentKey && !SAFE_CONFIG_KEYS.has(parentKey)) return "****";
87
+ if (typeof obj === "number" || typeof obj === "boolean") return obj;
88
+ if (typeof obj === "string" && parentKey && SAFE_CONFIG_KEYS.has(parentKey)) return obj;
89
+ if (typeof obj === "string") return "****";
90
+ return obj;
91
+ }
92
+ /**
93
+ * Add log files from logDir to the archive, respecting MAX_LOG_BYTES cap
94
+ * and the logWindow time filter. Matches any `*.log` file in the directory,
95
+ * so the per-instance filename pattern produced by
96
+ * `buildLogFilename()` is picked up without additional configuration.
97
+ *
98
+ * Exported for reuse by the `kici-admin debug-bundle` CLI command, which
99
+ * runs outside the orchestrator process but still needs to include the
100
+ * same log files in its locally-assembled bundle.
101
+ */
102
+ async function addLogsToArchive(archive, logDir, logWindowHours) {
103
+ const cutoff = Date.now() - logWindowHours * 60 * 60 * 1e3;
104
+ const entries = fs.readdirSync(logDir).filter((f) => {
105
+ if (!f.endsWith(".log")) return false;
106
+ return fs.statSync(path.join(logDir, f)).mtimeMs >= cutoff;
107
+ });
108
+ entries.sort((a, b) => {
109
+ const aStat = fs.statSync(path.join(logDir, a));
110
+ return fs.statSync(path.join(logDir, b)).mtimeMs - aStat.mtimeMs;
111
+ });
112
+ let totalBytes = 0;
113
+ let totalLines = 0;
114
+ let errors = 0;
115
+ let warnings = 0;
116
+ for (const entry of entries) {
117
+ const filePath = path.join(logDir, entry);
118
+ const stat = fs.statSync(filePath);
119
+ if (totalBytes + stat.size > 52428800) break;
120
+ const content = fs.readFileSync(filePath, "utf-8");
121
+ archive.append(content, { name: `logs/${entry}` });
122
+ totalBytes += stat.size;
123
+ const lines = content.split("\n");
124
+ totalLines += lines.length;
125
+ for (const line of lines) {
126
+ if (/\berror\b/i.test(line)) errors++;
127
+ if (/\bwarn(ing)?\b/i.test(line)) warnings++;
128
+ }
129
+ }
130
+ const summary = {
131
+ totalLines,
132
+ errors,
133
+ warnings,
134
+ totalBytes
135
+ };
136
+ archive.append(JSON.stringify(summary, null, 2), { name: "logs/summary.json" });
137
+ }
138
+ //#endregion
139
+ export { MAX_LOG_BYTES, addLogsToArchive, redactConfig };
140
+
141
+ //# sourceMappingURL=bundle-archive.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bundle-archive.test.d.ts.map
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Channel-agnostic chunked transfer for fleet bundle ZIPs.
3
+ *
4
+ * The WS frame cap (WS_MAX_PAYLOAD_BYTES = 25 MiB) forbids shipping a whole
5
+ * bundle in one frame, so a bundle Buffer is split into ordered base64 frames
6
+ * (~85 KiB raw each, matching the webhook-relay frame size) and reassembled by
7
+ * the receiver. Used on both the orchestrator-agent and peer channels.
8
+ */
9
+ /** Raw bytes per chunk before base64 (matches webhook-relay's ~85 KiB frames). */
10
+ export declare const FLEET_CHUNK_BYTES: number;
11
+ export interface BundleChunkFrame {
12
+ seq: number;
13
+ dataB64: string;
14
+ isLast: boolean;
15
+ }
16
+ /** Split a Buffer into ordered base64 frames. An empty buffer yields one final frame. */
17
+ export declare function chunkBuffer(buf: Buffer, chunkBytes?: number): BundleChunkFrame[];
18
+ /**
19
+ * Correlation core for any "send a request, await a chunked response" channel.
20
+ *
21
+ * Key-agnostic so both the orchestrator-agent channel (keyed by requestId) and
22
+ * the peer channel (keyed by messageId) share one implementation. Pending
23
+ * requests reject on timeout, on an error frame, or on disconnect. No
24
+ * orchestrator-initiated request/response primitive existed before fleet
25
+ * collection; this is it.
26
+ */
27
+ export declare class ChunkRequestWaiter {
28
+ private pending;
29
+ /** Register a pending request `id` that rejects after `timeoutMs`. */
30
+ add(id: string, timeoutMs: number): Promise<Buffer>;
31
+ /** Accumulate a chunk; resolves the pending request on the final frame. */
32
+ onChunk(id: string, seq: number, dataB64: string, isLast: boolean): void;
33
+ /** Reject the pending request `id` with `message`. */
34
+ onError(id: string, message: string): void;
35
+ /** Reject every pending request — used when the underlying connection drops. */
36
+ rejectAll(reason: string): void;
37
+ }
38
+ /** Reassembles ordered frames into a Buffer. Throws on gaps/reordering. */
39
+ export declare class BundleChunkAssembler {
40
+ private parts;
41
+ private next;
42
+ private done;
43
+ /** Returns the assembled Buffer on the final frame, otherwise undefined. */
44
+ accept(seq: number, dataB64: string, isLast: boolean): Buffer | undefined;
45
+ }
46
+ //# sourceMappingURL=bundle-chunks.d.ts.map
@@ -0,0 +1,111 @@
1
+ import "../chunk-gOLHoazu.js";
2
+ //#region src/diagnostics/bundle-chunks.ts
3
+ /**
4
+ * Channel-agnostic chunked transfer for fleet bundle ZIPs.
5
+ *
6
+ * The WS frame cap (WS_MAX_PAYLOAD_BYTES = 25 MiB) forbids shipping a whole
7
+ * bundle in one frame, so a bundle Buffer is split into ordered base64 frames
8
+ * (~85 KiB raw each, matching the webhook-relay frame size) and reassembled by
9
+ * the receiver. Used on both the orchestrator-agent and peer channels.
10
+ */
11
+ /** Raw bytes per chunk before base64 (matches webhook-relay's ~85 KiB frames). */
12
+ const FLEET_CHUNK_BYTES = 85 * 1024;
13
+ /** Split a Buffer into ordered base64 frames. An empty buffer yields one final frame. */
14
+ function chunkBuffer(buf, chunkBytes = FLEET_CHUNK_BYTES) {
15
+ const frames = [];
16
+ if (buf.length === 0) return [{
17
+ seq: 0,
18
+ dataB64: "",
19
+ isLast: true
20
+ }];
21
+ for (let offset = 0, seq = 0; offset < buf.length; offset += chunkBytes, seq++) {
22
+ const slice = buf.subarray(offset, Math.min(offset + chunkBytes, buf.length));
23
+ frames.push({
24
+ seq,
25
+ dataB64: slice.toString("base64"),
26
+ isLast: offset + chunkBytes >= buf.length
27
+ });
28
+ }
29
+ return frames;
30
+ }
31
+ /**
32
+ * Correlation core for any "send a request, await a chunked response" channel.
33
+ *
34
+ * Key-agnostic so both the orchestrator-agent channel (keyed by requestId) and
35
+ * the peer channel (keyed by messageId) share one implementation. Pending
36
+ * requests reject on timeout, on an error frame, or on disconnect. No
37
+ * orchestrator-initiated request/response primitive existed before fleet
38
+ * collection; this is it.
39
+ */
40
+ var ChunkRequestWaiter = class {
41
+ pending = /* @__PURE__ */ new Map();
42
+ /** Register a pending request `id` that rejects after `timeoutMs`. */
43
+ add(id, timeoutMs) {
44
+ return new Promise((resolve, reject) => {
45
+ const timer = setTimeout(() => {
46
+ this.pending.delete(id);
47
+ reject(/* @__PURE__ */ new Error(`chunk request ${id} timed out after ${timeoutMs}ms`));
48
+ }, timeoutMs);
49
+ this.pending.set(id, {
50
+ asm: new BundleChunkAssembler(),
51
+ resolve,
52
+ reject,
53
+ timer
54
+ });
55
+ });
56
+ }
57
+ /** Accumulate a chunk; resolves the pending request on the final frame. */
58
+ onChunk(id, seq, dataB64, isLast) {
59
+ const p = this.pending.get(id);
60
+ if (!p) return;
61
+ try {
62
+ const done = p.asm.accept(seq, dataB64, isLast);
63
+ if (done) {
64
+ clearTimeout(p.timer);
65
+ this.pending.delete(id);
66
+ p.resolve(done);
67
+ }
68
+ } catch (err) {
69
+ clearTimeout(p.timer);
70
+ this.pending.delete(id);
71
+ p.reject(err instanceof Error ? err : new Error(String(err)));
72
+ }
73
+ }
74
+ /** Reject the pending request `id` with `message`. */
75
+ onError(id, message) {
76
+ const p = this.pending.get(id);
77
+ if (!p) return;
78
+ clearTimeout(p.timer);
79
+ this.pending.delete(id);
80
+ p.reject(new Error(message));
81
+ }
82
+ /** Reject every pending request — used when the underlying connection drops. */
83
+ rejectAll(reason) {
84
+ for (const [, p] of this.pending) {
85
+ clearTimeout(p.timer);
86
+ p.reject(new Error(reason));
87
+ }
88
+ this.pending.clear();
89
+ }
90
+ };
91
+ /** Reassembles ordered frames into a Buffer. Throws on gaps/reordering. */
92
+ var BundleChunkAssembler = class {
93
+ parts = [];
94
+ next = 0;
95
+ done = false;
96
+ /** Returns the assembled Buffer on the final frame, otherwise undefined. */
97
+ accept(seq, dataB64, isLast) {
98
+ if (this.done) throw new Error("bundle chunk received after final frame");
99
+ if (seq !== this.next) throw new Error(`out-of-order bundle chunk: expected ${this.next}, got ${seq}`);
100
+ this.next++;
101
+ this.parts.push(Buffer.from(dataB64, "base64"));
102
+ if (isLast) {
103
+ this.done = true;
104
+ return Buffer.concat(this.parts);
105
+ }
106
+ }
107
+ };
108
+ //#endregion
109
+ export { BundleChunkAssembler, ChunkRequestWaiter, FLEET_CHUNK_BYTES, chunkBuffer };
110
+
111
+ //# sourceMappingURL=bundle-chunks.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bundle-chunks.test.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from '@kici-dev/core';
2
2
  export { RingBuffer } from './ring-buffer.js';
3
+ export { redactConfig, addLogsToArchive, MAX_LOG_BYTES } from './diagnostics/bundle-archive.js';
4
+ export { chunkBuffer, BundleChunkAssembler, ChunkRequestWaiter, FLEET_CHUNK_BYTES, type BundleChunkFrame, } from './diagnostics/bundle-chunks.js';
3
5
  export { createPool, createDb, type CreatePoolOptions, type PgPoolErrorSource } from './db.js';
4
6
  export { parseDatabaseUrl, maskDatabaseUrl, dropAndCreateDatabase, dropDatabaseDirect, ensureDatabase, type EnsureDatabaseOpts, createDbRole, createReadOnlyDbUser, computeMigrationsHash, storeMigrationContentHash, readStoredMigrationContentHash, isSchemaCurrent, clearDispatchQueueDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, purgeScopedSecretsDirect, seedEnvironmentDirect, deleteEnvironmentDirect, seedEnvironmentBindingDirect, setEnvironmentPolicyDirect, listEnvironmentsDirect, showEnvironmentDirect, createEnvironmentTemplateDirect, setEnvironmentSecretDirect, listQueueDirect, showQueueEntryDirect, listExecutionRunsDirect, showExecutionRunDirect, listExecutionJobsDirect, listRegistrationsDirect, showRegistrationDirect, registerWorkflowManualDirect, resetRaftStateDirect, emitKiciEventDirect, seedGenericWebhookSourceDirect, purgeSecretBackendsDirect, apiKeyExistsDirect, seedApiKeyInlineDirect, platformConnectionExistsDirect, countWebhookSourcesByConnectionIdDirect, getWebhookSourceByRoutingKeyDirect, findAnyUserApiKeyIdDirect, seedSyntheticGithubSourceDirect, seedWebhookSecretDirect, seedSourcePrivateKeyDirect, bumpRegistryVersionDirect, pollKiciEventsDirect, waitForPostgresDirect, waitForRunCompletionDirect, cleanupExecutionRowsDirect, isSchemaCurrentFromFilesDirect, storeMigrationContentHashInTableDirect, createJoinTokenDirect, updateSourceRoutingKeyDirect, prunePeerCredentialsDirect, waitForPlatformRegistrationsDirect, seedUniversalGitSourceDirect, seedCiSecurityFixturesDirect, waitForExecutionRunStatusSinceDirect, latestExecutionRunByStatusDirect, waitForLatestExecutionJobStatusDirect, describeTableColumnsDirect, tableExistsDirect, insertKiciEventRawDirect, showKiciEventDirect, listKiciEventsDirect, deleteKiciEventsDirect, verifyKiciEventNotifyDirect, seedCrossRepoTrustDirect, listCrossRepoTrustBySourceRoutingKeyDirect, deleteCrossRepoTrustDirect, insertCrossRepoTrustStrictDirect, deleteWorkflowRegistrationsDirect, getWorkflowRegistrationByIdDirect, listRegistrationsByRoutingKeyDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, updateWorkflowRegistrationCommitShaDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, getRegistryVersionDirect, bumpRegistryVersionSimpleDirect, upsertCronLastFiredDirect, countCronLastFiredDirect, insertCronLastFiredNowDirect, deleteCronLastFiredDirect, deleteExecutionRunsByWorkflowNameDirect, getGenericWebhookSourceByRoutingKeyDirect, listActiveGenericWebhookSourcesDirect, updateGenericWebhookVerificationConfigDirect, deleteGenericWebhookSourcesByNameDirect, restoreSoftDeletedGenericWebhookSourceDirect, upsertOrgSettingsGlobalWorkflowsDirect, updateOrgSettingsDeniedReposDirect, deleteOrgSettingsByCustomerIdDirect, getExecutionRunSecurityDirect, getHeldRunByIdDirect, countHeldRunsByRunIdDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForEventLogRowByDeliveryIdDirect, resolvePlatformWebhookSourceRoutingKeyDirect, ensureOrgOwnerMemberDirect, deletePeerCredentialsByInstanceIdLikeDirect, insertPeerCredentialExpiredDirect, getPeerCredentialRevokedAtDirect, listActivePeerCredentialsExcludingDirect, clearPeerCredentialsRevokedAtByIdsDirect, countActivePeerCredentialsByInstanceDirect, terminateIdleDbBackendsDirect, type ColumnInfo, type KiciEventRow, type CrossRepoTrustRow, type WorkflowRegistrationFullRow, type RegistrationsScopedResult, type LatestExecutionRunResult, type WaitForLatestJobResult, type ExecutionRunSecurityRow, type HeldRunSecurityRow, type EventLogRow as PlatformEventLogRow, type UpsertOrgSettingsOpts, type OrgSettingsRepoPatternEntry, type InsertKiciEventRawOpts, type EmitKiciEventOpts, type SeedGenericWebhookSourceOpts, REGISTERABLE_TRIGGER_TYPES, MIGRATION_HASH_TABLE, type PurgeStaleExecutionResult, type PurgeStaleSourcesResult, type SeedEnvironmentOpts, type SeedEnvironmentResult, type SeedEnvironmentBindingOpts, type SetEnvironmentPolicyOpts, type EnvironmentRow, type EnvironmentVariableRow, type EnvironmentBindingRow, type ShowEnvironmentResult, type CreateEnvironmentTemplateOpts, type SetEnvironmentSecretOpts, type DispatchQueueRow, type ListQueueOpts, type ExecutionRunRow, type ExecutionJobRow, type ListExecutionRunsOpts, type WorkflowRegistrationRow, type ListRegistrationsOpts, type ListRegistrationsResult, type ShowRegistrationResult, type RegisterWorkflowManualOpts, type RegisterWorkflowManualResult, } from './db-admin.js';
5
7
  export { createMetricsRoutes, type MetricsRoutesDeps } from './routes/metrics.js';
package/dist/index.js CHANGED
@@ -3,6 +3,8 @@ import { createDb, createPool } from "./db.js";
3
3
  import { MIGRATION_HASH_TABLE, REGISTERABLE_TRIGGER_TYPES, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createDbRole, createEnvironmentTemplateDirect, createJoinTokenDirect, createReadOnlyDbUser, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteEnvironmentDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listEnvironmentsDirect, listExecutionJobsDirect, listExecutionRunsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, parseDatabaseUrl, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedCrossRepoTrustDirect, seedEnvironmentBindingDirect, seedEnvironmentDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, setEnvironmentPolicyDirect, setEnvironmentSecretDirect, showEnvironmentDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, terminateIdleDbBackendsDirect, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect } from "./db-admin.js";
4
4
  import { setupGracefulShutdown } from "./graceful-shutdown.js";
5
5
  import { RingBuffer } from "./ring-buffer.js";
6
+ import { MAX_LOG_BYTES, addLogsToArchive, redactConfig } from "./diagnostics/bundle-archive.js";
7
+ import { BundleChunkAssembler, ChunkRequestWaiter, FLEET_CHUNK_BYTES, chunkBuffer } from "./diagnostics/bundle-chunks.js";
6
8
  import { createMetricsRoutes } from "./routes/metrics.js";
7
9
  import { createHealthRoutes } from "./routes/health.js";
8
10
  import { getReconnectDelay } from "./reconnect-delay.js";
@@ -22,4 +24,4 @@ import { ChunkLru } from "./cold-store/lru.js";
22
24
  import { DEFAULT_TABLE_CONFIG, resolveTableConfig } from "./cold-store/config.js";
23
25
  import "./cold-store/index.js";
24
26
  export * from "@kici-dev/core";
25
- export { BaseColdStore, COLD_BUCKET_NAMES, ChunkLru, DEFAULT_TABLE_CONFIG, MIGRATION_HASH_TABLE, REGISTERABLE_TRIGGER_TYPES, RingBuffer, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, chunkObjectKey, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, coldDaysToBucket, coldStoreArchiveBytesTotal, coldStoreArchiveCyclesTotal, coldStoreArchiveDurationSeconds, coldStoreArchiveRowsTotal, coldStorePurgeBytesTotal, coldStorePurgeChunksTotal, coldStorePurgeDurationSeconds, coldStoreRehydrateBytesTotal, coldStoreRehydrateDurationSeconds, coldStoreRehydrateRequestsTotal, coldStoreReplayDurationSeconds, coldStoreReplayRowsTotal, coldStoreVerifyFailuresTotal, collectRuntimeMetricNames, computeChunkId, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createDb, createDbRole, createEnvironmentTemplateDirect, createHealthRoutes, createJoinTokenDirect, createMeter, createMetricsRoutes, createPool, createReadOnlyDbUser, createS3Client, decodeChunk, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteEnvironmentDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, encodeChunk, encodeKeySegment, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getPrometheusExporter, getReconnectDelay, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, initTelemetry, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isLongerColdRetention, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listEnvironmentsDirect, listExecutionJobsDirect, listExecutionRunsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, parseDatabaseUrl, parseManifest, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, resolveTableConfig, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedCrossRepoTrustDirect, seedEnvironmentBindingDirect, seedEnvironmentDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, serializeManifest, setEnvironmentPolicyDirect, setEnvironmentSecretDirect, setupGracefulShutdown, showEnvironmentDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, tablePrefix, tenantDayBucketPrefix, tenantDayPrefix, terminateIdleDbBackendsDirect, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, validateRequiredTools, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect };
27
+ export { BaseColdStore, BundleChunkAssembler, COLD_BUCKET_NAMES, ChunkLru, ChunkRequestWaiter, DEFAULT_TABLE_CONFIG, FLEET_CHUNK_BYTES, MAX_LOG_BYTES, MIGRATION_HASH_TABLE, REGISTERABLE_TRIGGER_TYPES, RingBuffer, addLogsToArchive, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, chunkBuffer, chunkObjectKey, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, coldDaysToBucket, coldStoreArchiveBytesTotal, coldStoreArchiveCyclesTotal, coldStoreArchiveDurationSeconds, coldStoreArchiveRowsTotal, coldStorePurgeBytesTotal, coldStorePurgeChunksTotal, coldStorePurgeDurationSeconds, coldStoreRehydrateBytesTotal, coldStoreRehydrateDurationSeconds, coldStoreRehydrateRequestsTotal, coldStoreReplayDurationSeconds, coldStoreReplayRowsTotal, coldStoreVerifyFailuresTotal, collectRuntimeMetricNames, computeChunkId, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createDb, createDbRole, createEnvironmentTemplateDirect, createHealthRoutes, createJoinTokenDirect, createMeter, createMetricsRoutes, createPool, createReadOnlyDbUser, createS3Client, decodeChunk, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteEnvironmentDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, encodeChunk, encodeKeySegment, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getPrometheusExporter, getReconnectDelay, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, initTelemetry, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isLongerColdRetention, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listEnvironmentsDirect, listExecutionJobsDirect, listExecutionRunsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, parseDatabaseUrl, parseManifest, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, redactConfig, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, resolveTableConfig, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedCrossRepoTrustDirect, seedEnvironmentBindingDirect, seedEnvironmentDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, serializeManifest, setEnvironmentPolicyDirect, setEnvironmentSecretDirect, setupGracefulShutdown, showEnvironmentDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, tablePrefix, tenantDayBucketPrefix, tenantDayPrefix, terminateIdleDbBackendsDirect, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, validateRequiredTools, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kici-dev/shared",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Shared utilities for the KiCI CI/CD stack — logging, zx setup, crypto, telemetry, health and metrics routes. No business logic.",
5
5
  "keywords": [
6
6
  "ci",
@@ -81,6 +81,7 @@
81
81
  },
82
82
  "dependencies": {
83
83
  "@aws-sdk/client-s3": "^3.1038.0",
84
+ "archiver": "^7.0.1",
84
85
  "@opentelemetry/api": "^1.9.1",
85
86
  "@opentelemetry/exporter-metrics-otlp-http": "^0.217.0",
86
87
  "@opentelemetry/exporter-prometheus": "^0.217.0",
@@ -100,10 +101,11 @@
100
101
  "yaml": "^2.8.3",
101
102
  "zod": "^4.3.6",
102
103
  "zx": "^8.8.5",
103
- "@kici-dev/core": "0.1.15"
104
+ "@kici-dev/core": "0.1.16"
104
105
  },
105
106
  "devDependencies": {
106
107
  "@opentelemetry/sdk-trace-base": "^2.7.0",
108
+ "@types/archiver": "^7.0.0",
107
109
  "@types/diff": "^7.0.0"
108
110
  },
109
111
  "scripts": {