@hasna/loops 0.3.18 → 0.3.19
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/README.md +4 -3
- package/dist/cli/index.js +22 -3
- package/dist/daemon/index.js +1 -1
- package/docs/USAGE.md +5 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -318,9 +318,10 @@ them with `no_tmux_dispatch=true` metadata. Use `--dry-run --json` before
|
|
|
318
318
|
turning it into a production loop.
|
|
319
319
|
|
|
320
320
|
`hygiene names` reports canonical `machine-*` or `repo-<name>-*` loop names and
|
|
321
|
-
renames only with `--apply`.
|
|
322
|
-
|
|
323
|
-
|
|
321
|
+
renames only with `--apply`. Apply mode writes a SQLite backup under
|
|
322
|
+
`<LOOPS_DATA_DIR>/backups` before changing loop names. `hygiene duplicates`
|
|
323
|
+
groups loops with the same normalized name, cwd, and schedule. `hygiene scripts`
|
|
324
|
+
inventories loops whose command still references `~/.hasna/loops/scripts`.
|
|
324
325
|
|
|
325
326
|
Archive loops when retiring old automation but preserving history:
|
|
326
327
|
|
package/dist/cli/index.js
CHANGED
|
@@ -2196,8 +2196,10 @@ class Store {
|
|
|
2196
2196
|
|
|
2197
2197
|
// src/cli/index.ts
|
|
2198
2198
|
import { createHash as createHash2 } from "crypto";
|
|
2199
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
2199
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2200
2200
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
2201
|
+
import { join as join3 } from "path";
|
|
2202
|
+
import { Database as Database2 } from "bun:sqlite";
|
|
2201
2203
|
import { Command } from "commander";
|
|
2202
2204
|
|
|
2203
2205
|
// src/lib/format.ts
|
|
@@ -5089,7 +5091,7 @@ function buildScriptInventoryReport(store, opts = {}) {
|
|
|
5089
5091
|
// package.json
|
|
5090
5092
|
var package_default = {
|
|
5091
5093
|
name: "@hasna/loops",
|
|
5092
|
-
version: "0.3.
|
|
5094
|
+
version: "0.3.19",
|
|
5093
5095
|
description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
|
|
5094
5096
|
type: "module",
|
|
5095
5097
|
main: "dist/index.js",
|
|
@@ -5742,6 +5744,19 @@ function ensureTodosTaskList(project, slug, name, description) {
|
|
|
5742
5744
|
throw new Error(`todos task list not found after ensure: ${slug}`);
|
|
5743
5745
|
return found.id;
|
|
5744
5746
|
}
|
|
5747
|
+
function backupLoopsDatabase(reason) {
|
|
5748
|
+
const stamp = new Date().toISOString().replace(/[-:]/g, "").replace(/\..+$/, "Z");
|
|
5749
|
+
const backupDir = join3(dataDir(), "backups");
|
|
5750
|
+
mkdirSync5(backupDir, { recursive: true, mode: 448 });
|
|
5751
|
+
const backupPath = join3(backupDir, `loops.db.bak-${reason}-${stamp}`);
|
|
5752
|
+
const db = new Database2(dbPath(), { readonly: true });
|
|
5753
|
+
try {
|
|
5754
|
+
writeFileSync3(backupPath, db.serialize(), { mode: 384 });
|
|
5755
|
+
} finally {
|
|
5756
|
+
db.close();
|
|
5757
|
+
}
|
|
5758
|
+
return backupPath;
|
|
5759
|
+
}
|
|
5745
5760
|
function eventData(event) {
|
|
5746
5761
|
const data = event.data;
|
|
5747
5762
|
if (data && typeof data === "object" && !Array.isArray(data))
|
|
@@ -6560,16 +6575,20 @@ var hygiene = program.command("hygiene").description("deterministic OpenLoops hy
|
|
|
6560
6575
|
hygiene.command("names").description("check or apply canonical machine-/repo-prefixed loop names").option("--apply", "rename loops in-place").option("--include-stopped", "include stopped loops").option("--include-inactive", "include stopped, expired, and archived loops").option("--limit <n>", "maximum loops to inspect", "1000").option("--json", "print JSON").action((opts) => {
|
|
6561
6576
|
const store = new Store;
|
|
6562
6577
|
try {
|
|
6578
|
+
const backupPath = opts.apply ? backupLoopsDatabase("name-hygiene") : undefined;
|
|
6563
6579
|
const report = buildNameHygieneReport(store, {
|
|
6564
6580
|
apply: Boolean(opts.apply),
|
|
6565
6581
|
includeStopped: Boolean(opts.includeStopped),
|
|
6566
6582
|
includeInactive: Boolean(opts.includeInactive),
|
|
6567
6583
|
limit: Number(opts.limit)
|
|
6568
6584
|
});
|
|
6585
|
+
const output = backupPath ? { ...report, backupPath } : report;
|
|
6569
6586
|
if (isJson() || opts.json)
|
|
6570
|
-
console.log(JSON.stringify(
|
|
6587
|
+
console.log(JSON.stringify(output, null, 2));
|
|
6571
6588
|
else {
|
|
6572
6589
|
console.log(`hygiene_names checked=${report.checked} changed=${report.changed} applied=${report.applied}`);
|
|
6590
|
+
if (backupPath)
|
|
6591
|
+
console.log(`backup=${backupPath}`);
|
|
6573
6592
|
for (const change of report.changes.filter((entry) => entry.changed)) {
|
|
6574
6593
|
console.log(`${report.applied ? "renamed" : "would-rename"} ${change.id} ${change.oldName} -> ${change.newName}`);
|
|
6575
6594
|
}
|
package/dist/daemon/index.js
CHANGED
|
@@ -4419,7 +4419,7 @@ function enableStartup(result) {
|
|
|
4419
4419
|
// package.json
|
|
4420
4420
|
var package_default = {
|
|
4421
4421
|
name: "@hasna/loops",
|
|
4422
|
-
version: "0.3.
|
|
4422
|
+
version: "0.3.19",
|
|
4423
4423
|
description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
|
|
4424
4424
|
type: "module",
|
|
4425
4425
|
main: "dist/index.js",
|
package/docs/USAGE.md
CHANGED
|
@@ -325,10 +325,11 @@ loops hygiene scripts --json
|
|
|
325
325
|
```
|
|
326
326
|
|
|
327
327
|
`hygiene names` reports canonical `machine-*` or `repo-<name>-*` loop names and
|
|
328
|
-
only renames when `--apply` is present.
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
328
|
+
only renames when `--apply` is present. Apply mode writes a SQLite backup under
|
|
329
|
+
`<LOOPS_DATA_DIR>/backups` before changing loop names. `hygiene duplicates`
|
|
330
|
+
groups loops with the same normalized name, cwd, and schedule. `hygiene scripts`
|
|
331
|
+
inventories loops whose command still references `~/.hasna/loops/scripts`; use
|
|
332
|
+
it as a migration gate before deleting local scripts.
|
|
332
333
|
|
|
333
334
|
Archive loops when retiring old automation but preserving history:
|
|
334
335
|
|
package/package.json
CHANGED