dank-ai 1.0.31 → 1.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/docker/manager.js +26 -16
- package/package.json +1 -1
package/lib/docker/manager.js
CHANGED
|
@@ -1140,11 +1140,29 @@ class DockerManager {
|
|
|
1140
1140
|
}
|
|
1141
1141
|
}
|
|
1142
1142
|
|
|
1143
|
+
/**
|
|
1144
|
+
* Normalize Docker image name/tag components
|
|
1145
|
+
* Docker allows: lowercase letters, digits, underscores, periods, and hyphens
|
|
1146
|
+
* Cannot start or end with period or hyphen, max 128 chars for tags
|
|
1147
|
+
*/
|
|
1148
|
+
normalizeDockerName(name) {
|
|
1149
|
+
if (!name || typeof name !== 'string') return 'invalid';
|
|
1150
|
+
const lower = String(name).toLowerCase();
|
|
1151
|
+
let sanitized = lower.replace(/[^a-z0-9_.-]/g, '-');
|
|
1152
|
+
sanitized = sanitized.replace(/\.{2,}/g, '.'); // Replace multiple periods with single
|
|
1153
|
+
sanitized = sanitized.replace(/-{2,}/g, '-'); // Replace multiple hyphens with single
|
|
1154
|
+
sanitized = sanitized.replace(/^[.-]+/, '').replace(/[.-]+$/, ''); // Remove leading/trailing . or -
|
|
1155
|
+
if (!sanitized || !/^[a-z0-9]/.test(sanitized)) sanitized = `a${sanitized || ''}`;
|
|
1156
|
+
if (sanitized.length > 128) sanitized = sanitized.slice(0, 128);
|
|
1157
|
+
return sanitized;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1143
1160
|
/**
|
|
1144
1161
|
* Build agent-specific image
|
|
1145
1162
|
*/
|
|
1146
1163
|
async buildAgentImage(agent, options = {}) {
|
|
1147
|
-
const
|
|
1164
|
+
const normalizedName = this.normalizeDockerName(agent.name);
|
|
1165
|
+
const imageName = `dank-agent-${normalizedName}`;
|
|
1148
1166
|
this.logger.info(`Building image for agent: ${agent.name}`);
|
|
1149
1167
|
|
|
1150
1168
|
try {
|
|
@@ -1189,32 +1207,24 @@ class DockerManager {
|
|
|
1189
1207
|
push = false,
|
|
1190
1208
|
} = options;
|
|
1191
1209
|
|
|
1192
|
-
// Normalize
|
|
1193
|
-
const
|
|
1194
|
-
|
|
1195
|
-
let sanitized = lower.replace(/[^a-z0-9_.-]/g, '-');
|
|
1196
|
-
sanitized = sanitized.replace(/^-+/, '').replace(/-+$/, '');
|
|
1197
|
-
if (!sanitized || !/^[a-z0-9]/.test(sanitized)) sanitized = `a${sanitized || ''}`;
|
|
1198
|
-
if (sanitized.length > 128) sanitized = sanitized.slice(0, 128);
|
|
1199
|
-
return sanitized;
|
|
1200
|
-
};
|
|
1210
|
+
// Normalize all components
|
|
1211
|
+
const normalizedAgentName = this.normalizeDockerName(agent.name);
|
|
1212
|
+
const normalizedTag = this.normalizeDockerName(tag);
|
|
1201
1213
|
|
|
1202
1214
|
//construct full repo name
|
|
1203
1215
|
let repoName;
|
|
1204
1216
|
if(!tagByAgent){
|
|
1205
1217
|
// Per-agent repository: {registry}/{namespace}/{agent-name}
|
|
1206
|
-
|
|
1207
|
-
repoName = `${registry?`${registry}/`:''}${namespace?`${namespace}/`:''}${agentRepoName}`;
|
|
1218
|
+
repoName = `${registry?`${registry}/`:''}${namespace?`${namespace}/`:''}${normalizedAgentName}`;
|
|
1208
1219
|
}else{
|
|
1209
|
-
// Common repository: {registry}/{namespace}
|
|
1220
|
+
// Common repository: {registry}/{namespace}
|
|
1210
1221
|
repoName = `${registry?`${registry}/`:''}${namespace?`${namespace}/`:''}`;
|
|
1211
1222
|
}
|
|
1212
1223
|
|
|
1213
1224
|
repoName = repoName.replace(/\/+$/, '');
|
|
1214
1225
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
const finalTag = tagByAgent ? normalizeTag(agent.name) : tag;
|
|
1226
|
+
// Final tag selection - normalize both agent name tags and user-provided tags
|
|
1227
|
+
const finalTag = tagByAgent ? normalizedAgentName : normalizedTag;
|
|
1218
1228
|
const imageName = `${repoName}:${finalTag}`;
|
|
1219
1229
|
|
|
1220
1230
|
this.logger.info(
|