@kntic/kntic 0.4.4 → 0.4.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kntic/kntic",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "author": "Thomas Robak <contact@kntic.ai> (https://kntic.ai)",
5
5
  "description": "KNTIC CLI — bootstrap and manage KNTIC projects",
6
6
  "main": "src/index.js",
@@ -189,6 +189,7 @@ function extractLibOnly(tarball, destDir) {
189
189
  * - .kntic/lib and .kntic/adrs are **replaced** (cleared first, then extracted).
190
190
  * - .kntic/hooks/gdr is **updated** (existing files are overwritten or new files
191
191
  * added, but files not present in the archive are preserved).
192
+ * - .kntic/gia/weights.json is **replaced** if present in the archive.
192
193
  *
193
194
  * @param {string} tarball – path to the .tar.gz file
194
195
  * @param {string} destDir – target directory (usually ".")
@@ -197,17 +198,20 @@ function extractUpdate(tarball, destDir) {
197
198
  const libDir = path.join(destDir, ".kntic", "lib");
198
199
  const adrsDir = path.join(destDir, ".kntic", "adrs");
199
200
  const gdrDir = path.join(destDir, ".kntic", "hooks", "gdr");
201
+ const giaDir = path.join(destDir, ".kntic", "gia");
200
202
 
201
203
  // Ensure target directories exist
202
204
  fs.mkdirSync(libDir, { recursive: true });
203
205
  fs.mkdirSync(adrsDir, { recursive: true });
204
206
  fs.mkdirSync(gdrDir, { recursive: true });
207
+ fs.mkdirSync(giaDir, { recursive: true });
205
208
 
206
209
  // Clear lib and adrs (full replacement)
207
210
  clearDirectory(libDir);
208
211
  clearDirectory(adrsDir);
209
212
 
210
213
  // Note: gdr is NOT cleared — update semantics (overwrite/add, preserve others)
214
+ // Note: gia is NOT cleared — only weights.json is replaced
211
215
 
212
216
  // Extract .kntic/lib/ and .kntic/adrs/ (guaranteed to be in the archive)
213
217
  execSync(
@@ -224,6 +228,16 @@ function extractUpdate(tarball, destDir) {
224
228
  } catch (_) {
225
229
  // No .kntic/hooks/gdr/ in the archive — that's fine
226
230
  }
231
+
232
+ // Extract .kntic/gia/weights.json separately — archive may not contain it
233
+ try {
234
+ execSync(
235
+ `tar xzf "${tarball}" -C "${destDir}" "./.kntic/gia/weights.json"`,
236
+ { stdio: "pipe" }
237
+ );
238
+ } catch (_) {
239
+ // No .kntic/gia/weights.json in the archive — that's fine
240
+ }
227
241
  }
228
242
 
229
243
  async function update(options = {}) {
@@ -242,7 +256,7 @@ async function update(options = {}) {
242
256
  console.log("Updating .kntic/lib …");
243
257
  extractLibOnly(tmpFile, ".");
244
258
  } else {
245
- console.log("Updating .kntic/lib, .kntic/adrs, and .kntic/hooks/gdr …");
259
+ console.log("Updating .kntic/lib, .kntic/adrs, .kntic/hooks/gdr, and .kntic/gia/weights.json …");
246
260
  extractUpdate(tmpFile, ".");
247
261
  }
248
262
 
@@ -256,7 +270,7 @@ async function update(options = {}) {
256
270
  if (libOnly) {
257
271
  console.log("Done. .kntic/lib updated successfully.");
258
272
  } else {
259
- console.log("Done. .kntic/lib, .kntic/adrs, and .kntic/hooks/gdr updated successfully.");
273
+ console.log("Done. .kntic/lib, .kntic/adrs, .kntic/hooks/gdr, and .kntic/gia/weights.json updated successfully.");
260
274
  }
261
275
  }
262
276
 
@@ -358,6 +358,56 @@ describe("extractUpdate", () => {
358
358
  assert.ok(fs.existsSync(path.join(destDir, ".kntic", "adrs", "ADR-001.md")));
359
359
  });
360
360
 
361
+ it("replaces .kntic/gia/weights.json from the archive", () => {
362
+ const giaDir = path.join(destDir, ".kntic", "gia");
363
+ fs.mkdirSync(giaDir, { recursive: true });
364
+ fs.writeFileSync(path.join(giaDir, "weights.json"), '{"old": true}\n');
365
+ fs.writeFileSync(path.join(giaDir, "state.json"), '{"keep": true}\n');
366
+
367
+ const tarball = createTarball(tmpDir, {
368
+ ".kntic/lib/orchestrator.py": "# orchestrator\n",
369
+ ".kntic/adrs/ADR-001.md": "# ADR 001\n",
370
+ ".kntic/gia/weights.json": '{"new": true}\n',
371
+ });
372
+
373
+ extractUpdate(tarball, destDir);
374
+
375
+ // weights.json must be replaced
376
+ assert.equal(
377
+ fs.readFileSync(path.join(giaDir, "weights.json"), "utf8"),
378
+ '{"new": true}\n',
379
+ "weights.json must be replaced with archive version"
380
+ );
381
+
382
+ // Other files in gia must be preserved
383
+ assert.equal(
384
+ fs.readFileSync(path.join(giaDir, "state.json"), "utf8"),
385
+ '{"keep": true}\n',
386
+ "state.json must not be touched"
387
+ );
388
+ });
389
+
390
+ it("works when archive has no .kntic/gia/weights.json", () => {
391
+ const giaDir = path.join(destDir, ".kntic", "gia");
392
+ fs.mkdirSync(giaDir, { recursive: true });
393
+ fs.writeFileSync(path.join(giaDir, "weights.json"), '{"existing": true}\n');
394
+
395
+ const tarball = createTarball(tmpDir, {
396
+ ".kntic/lib/orchestrator.py": "# orchestrator\n",
397
+ ".kntic/adrs/ADR-001.md": "# ADR 001\n",
398
+ });
399
+
400
+ // Should not throw
401
+ extractUpdate(tarball, destDir);
402
+
403
+ // Existing weights.json must be preserved when not in archive
404
+ assert.equal(
405
+ fs.readFileSync(path.join(giaDir, "weights.json"), "utf8"),
406
+ '{"existing": true}\n',
407
+ "existing weights.json must be preserved when archive has none"
408
+ );
409
+ });
410
+
361
411
  it("preserves files outside .kntic/lib, .kntic/adrs, and .kntic/hooks/gdr", () => {
362
412
  const knticDir = path.join(destDir, ".kntic");
363
413
  fs.mkdirSync(knticDir, { recursive: true });
@@ -9,8 +9,8 @@ function usage() {
9
9
  console.log(" start Build and start KNTIC services via docker compose (uses kntic.yml + .kntic.env)");
10
10
  console.log(" --screen Run inside a GNU screen session");
11
11
  console.log(" stop Stop KNTIC services via docker compose");
12
- console.log(" update Download the latest KNTIC bootstrap and update .kntic/lib, .kntic/adrs, and .kntic/hooks/gdr");
13
- console.log(" --lib-only Update only .kntic/lib (skip .kntic/adrs and .kntic/hooks/gdr)");
12
+ console.log(" update Download the latest KNTIC bootstrap and update .kntic/lib, .kntic/adrs, .kntic/hooks/gdr, and .kntic/gia/weights.json");
13
+ console.log(" --lib-only Update only .kntic/lib (skip .kntic/adrs, .kntic/hooks/gdr, and .kntic/gia/weights.json)");
14
14
  console.log("");
15
15
  }
16
16