@ai-support-agent/cli 0.1.25-beta.2 → 0.1.26-beta.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.
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Dockerfile synchronization to config directory
|
|
3
3
|
*
|
|
4
|
-
* Copies the bundled Dockerfile
|
|
5
|
-
*
|
|
4
|
+
* Copies the bundled Dockerfile and entrypoint.sh as one snapshot to
|
|
5
|
+
* ~/.ai-support-agent/ using hash-based comparison so user customisations
|
|
6
|
+
* are preserved across updates. The Dockerfile COPYs docker/entrypoint.sh
|
|
7
|
+
* at image build time, so both files must always be updated together —
|
|
8
|
+
* a stale entrypoint.sh would otherwise be baked into the next image build.
|
|
6
9
|
*/
|
|
7
10
|
/**
|
|
8
|
-
* Copy the bundled Dockerfile
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
+
* Copy the bundled Dockerfile + entrypoint.sh pair to the config directory.
|
|
12
|
+
* The pair is treated as one sync unit: a combined hash over both files is
|
|
13
|
+
* stored in .dockerfile-sync-hash to detect user customisations:
|
|
14
|
+
* - No hash file or any destination file missing → overwrite the pair
|
|
15
|
+
* unconditionally and record the bundled combined hash
|
|
16
|
+
* - Hash matches current config pair → update if the bundled pair differs
|
|
17
|
+
* - Hash mismatch → user has customised either file, warn and skip
|
|
18
|
+
* entrypoint.sh may be absent from the bundle, in which case the Dockerfile
|
|
19
|
+
* alone forms the sync unit.
|
|
11
20
|
*/
|
|
12
21
|
export declare function syncDockerfileToConfigDir(): void;
|
|
13
22
|
//# sourceMappingURL=dockerfile-sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dockerfile-sync.d.ts","sourceRoot":"","sources":["../../src/docker/dockerfile-sync.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"dockerfile-sync.d.ts","sourceRoot":"","sources":["../../src/docker/dockerfile-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAwCH;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAwDhD"}
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Dockerfile synchronization to config directory
|
|
4
4
|
*
|
|
5
|
-
* Copies the bundled Dockerfile
|
|
6
|
-
*
|
|
5
|
+
* Copies the bundled Dockerfile and entrypoint.sh as one snapshot to
|
|
6
|
+
* ~/.ai-support-agent/ using hash-based comparison so user customisations
|
|
7
|
+
* are preserved across updates. The Dockerfile COPYs docker/entrypoint.sh
|
|
8
|
+
* at image build time, so both files must always be updated together —
|
|
9
|
+
* a stale entrypoint.sh would otherwise be baked into the next image build.
|
|
7
10
|
*/
|
|
8
11
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
12
|
if (k2 === undefined) k2 = k;
|
|
@@ -40,6 +43,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
40
43
|
})();
|
|
41
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
45
|
exports.syncDockerfileToConfigDir = syncDockerfileToConfigDir;
|
|
46
|
+
const crypto = __importStar(require("crypto"));
|
|
43
47
|
const fs = __importStar(require("fs"));
|
|
44
48
|
const path = __importStar(require("path"));
|
|
45
49
|
const config_manager_1 = require("../config-manager");
|
|
@@ -47,28 +51,83 @@ const dockerfile_path_1 = require("./dockerfile-path");
|
|
|
47
51
|
const i18n_1 = require("../i18n");
|
|
48
52
|
const logger_1 = require("../logger");
|
|
49
53
|
const utils_1 = require("../utils");
|
|
54
|
+
/** Combined SHA-256 over the given files, hashed in order. */
|
|
55
|
+
function combinedSha256(filePaths) {
|
|
56
|
+
const hash = crypto.createHash('sha256');
|
|
57
|
+
for (const filePath of filePaths) {
|
|
58
|
+
const content = fs.readFileSync(filePath);
|
|
59
|
+
// Length prefix keeps file boundaries distinct so different splits of the
|
|
60
|
+
// same concatenated bytes cannot collide
|
|
61
|
+
hash.update(`${content.length}\n`);
|
|
62
|
+
hash.update(content);
|
|
63
|
+
}
|
|
64
|
+
return hash.digest('hex');
|
|
65
|
+
}
|
|
66
|
+
/** Copy every pair, creating the destination directories as needed. */
|
|
67
|
+
function copyPairs(configDir, pairs) {
|
|
68
|
+
fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
|
|
69
|
+
for (const pair of pairs) {
|
|
70
|
+
fs.mkdirSync(path.dirname(pair.dest), { recursive: true });
|
|
71
|
+
fs.copyFileSync(pair.src, pair.dest);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
50
74
|
/**
|
|
51
|
-
* Copy the bundled Dockerfile
|
|
52
|
-
*
|
|
53
|
-
*
|
|
75
|
+
* Copy the bundled Dockerfile + entrypoint.sh pair to the config directory.
|
|
76
|
+
* The pair is treated as one sync unit: a combined hash over both files is
|
|
77
|
+
* stored in .dockerfile-sync-hash to detect user customisations:
|
|
78
|
+
* - No hash file or any destination file missing → overwrite the pair
|
|
79
|
+
* unconditionally and record the bundled combined hash
|
|
80
|
+
* - Hash matches current config pair → update if the bundled pair differs
|
|
81
|
+
* - Hash mismatch → user has customised either file, warn and skip
|
|
82
|
+
* entrypoint.sh may be absent from the bundle, in which case the Dockerfile
|
|
83
|
+
* alone forms the sync unit.
|
|
54
84
|
*/
|
|
55
85
|
function syncDockerfileToConfigDir() {
|
|
56
86
|
const configDir = (0, config_manager_1.getConfigDir)();
|
|
57
87
|
const destDockerfile = path.join(configDir, 'Dockerfile');
|
|
58
|
-
|
|
59
|
-
return; // preserve existing file
|
|
88
|
+
const hashFile = path.join(configDir, '.dockerfile-sync-hash');
|
|
60
89
|
try {
|
|
90
|
+
// getDockerfilePath throws when the bundled Dockerfile is missing —
|
|
91
|
+
// keep it inside the try so a broken bundle degrades to a warning
|
|
61
92
|
const srcDockerfile = (0, dockerfile_path_1.getDockerfilePath)();
|
|
62
|
-
fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
|
|
63
|
-
fs.copyFileSync(srcDockerfile, destDockerfile);
|
|
64
|
-
// Also copy entrypoint.sh which the bundled Dockerfile references via COPY
|
|
65
93
|
const srcEntrypoint = path.join((0, dockerfile_path_1.getDockerContextDir)(), 'docker', 'entrypoint.sh');
|
|
66
|
-
const
|
|
94
|
+
const pairs = [{ src: srcDockerfile, dest: destDockerfile }];
|
|
67
95
|
if (fs.existsSync(srcEntrypoint)) {
|
|
68
|
-
|
|
69
|
-
|
|
96
|
+
pairs.push({ src: srcEntrypoint, dest: path.join(configDir, 'docker', 'entrypoint.sh') });
|
|
97
|
+
}
|
|
98
|
+
const destMissing = pairs.some((pair) => !fs.existsSync(pair.dest));
|
|
99
|
+
if (!fs.existsSync(hashFile) || destMissing) {
|
|
100
|
+
// First run, existing user without hash file, or part of the config
|
|
101
|
+
// pair was deleted — overwrite the pair unconditionally.
|
|
102
|
+
// Remove the hash file before copying: if any copy fails midway, the
|
|
103
|
+
// next run sees no hash file and retries this branch (self-heal)
|
|
104
|
+
fs.rmSync(hashFile, { force: true });
|
|
105
|
+
copyPairs(configDir, pairs);
|
|
106
|
+
(0, utils_1.atomicWriteFile)(hashFile, combinedSha256(pairs.map((pair) => pair.src)));
|
|
107
|
+
logger_1.logger.info((0, i18n_1.t)('docker.dockerfileSynced', { path: destDockerfile }));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// trim() guards against a stray trailing newline in the hash file
|
|
111
|
+
const savedHash = fs.readFileSync(hashFile, 'utf-8').trim();
|
|
112
|
+
const currentConfigHash = combinedSha256(pairs.map((pair) => pair.dest));
|
|
113
|
+
if (savedHash !== currentConfigHash) {
|
|
114
|
+
// User has customised the Dockerfile or entrypoint.sh — warn and skip
|
|
115
|
+
// (no need to hash the bundled pair on this path)
|
|
116
|
+
logger_1.logger.warn((0, i18n_1.t)('docker.dockerfileCustomized', { path: destDockerfile }));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Not customised
|
|
120
|
+
const bundledHash = combinedSha256(pairs.map((pair) => pair.src));
|
|
121
|
+
if (bundledHash === currentConfigHash) {
|
|
122
|
+
// Already up to date — no-op
|
|
123
|
+
return;
|
|
70
124
|
}
|
|
71
|
-
|
|
125
|
+
// Bundled pair is newer — update. Remove the hash file first so a
|
|
126
|
+
// partial copy is retried (not misjudged as customised) on the next run
|
|
127
|
+
fs.rmSync(hashFile, { force: true });
|
|
128
|
+
copyPairs(configDir, pairs);
|
|
129
|
+
(0, utils_1.atomicWriteFile)(hashFile, bundledHash);
|
|
130
|
+
logger_1.logger.info((0, i18n_1.t)('docker.dockerfileUpdated', { path: destDockerfile }));
|
|
72
131
|
}
|
|
73
132
|
catch (err) {
|
|
74
133
|
logger_1.logger.warn((0, i18n_1.t)('docker.dockerfileSyncFailed', { message: (0, utils_1.getErrorMessage)(err) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dockerfile-sync.js","sourceRoot":"","sources":["../../src/docker/dockerfile-sync.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"dockerfile-sync.js","sourceRoot":"","sources":["../../src/docker/dockerfile-sync.ts"],"names":[],"mappings":"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"}
|
package/dist/locales/en.json
CHANGED
|
@@ -164,6 +164,8 @@
|
|
|
164
164
|
"docker.loginStep3": "The token is long-lived. Add the export to .bashrc or .zshrc to persist it.",
|
|
165
165
|
"docker.usingCustomDockerfile": "Using custom Dockerfile: {{path}}",
|
|
166
166
|
"docker.dockerfileSynced": "Default Dockerfile written to: {{path}}",
|
|
167
|
+
"docker.dockerfileUpdated": "Bundled Dockerfile changed — updated config: {{path}}",
|
|
168
|
+
"docker.dockerfileCustomized": "Skipped Dockerfile update (customised). To apply the latest bundled version manually: {{path}}",
|
|
167
169
|
"docker.dockerfileSyncFailed": "Failed to write Dockerfile to config dir: {{message}}",
|
|
168
170
|
"docker.diffNoTarget": "No Dockerfile to diff. Specify a path or set dockerfilePath in config.",
|
|
169
171
|
"docker.diffTargetNotFound": "Dockerfile not found: {{path}}",
|
package/dist/locales/ja.json
CHANGED
|
@@ -164,6 +164,8 @@
|
|
|
164
164
|
"docker.loginStep3": "トークンは長期間有効です。毎回設定が必要な場合は .bashrc や .zshrc に export を追加してください。",
|
|
165
165
|
"docker.usingCustomDockerfile": "カスタムDockerfileを使用: {{path}}",
|
|
166
166
|
"docker.dockerfileSynced": "デフォルトDockerfileを書き出しました: {{path}}",
|
|
167
|
+
"docker.dockerfileUpdated": "バンドル版Dockerfileが変更されたため設定ファイルを更新しました: {{path}}",
|
|
168
|
+
"docker.dockerfileCustomized": "Dockerfileがカスタマイズされているため自動更新をスキップしました。最新版を手動で反映してください: {{path}}",
|
|
167
169
|
"docker.dockerfileSyncFailed": "Dockerfileの書き出しに失敗しました: {{message}}",
|
|
168
170
|
"docker.diffNoTarget": "比較対象のDockerfileがありません。パスを指定するか設定にdockerfilePathを設定してください。",
|
|
169
171
|
"docker.diffTargetNotFound": "Dockerfileが見つかりません: {{path}}",
|