@codyswann/lisa 2.117.0 → 2.119.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.
Files changed (42) hide show
  1. package/dist/cli/index.d.ts.map +1 -1
  2. package/dist/cli/index.js +4 -1
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/cli/print-update-warning.d.ts +7 -0
  5. package/dist/cli/print-update-warning.d.ts.map +1 -0
  6. package/dist/cli/print-update-warning.js +15 -0
  7. package/dist/cli/print-update-warning.js.map +1 -0
  8. package/dist/cli/update-check.d.ts +37 -0
  9. package/dist/cli/update-check.d.ts.map +1 -0
  10. package/dist/cli/update-check.js +147 -0
  11. package/dist/cli/update-check.js.map +1 -0
  12. package/dist/cli/version.d.ts +6 -0
  13. package/dist/cli/version.d.ts.map +1 -0
  14. package/dist/cli/version.js +38 -0
  15. package/dist/cli/version.js.map +1 -0
  16. package/dist/index.js +13 -2
  17. package/dist/index.js.map +1 -1
  18. package/package.json +3 -1
  19. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  23. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  25. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  27. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  29. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  31. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  33. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  35. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-wiki/scripts/ensure-gitignore.mjs +131 -0
  38. package/plugins/lisa-wiki/skills/lisa-wiki-setup/SKILL.md +13 -4
  39. package/plugins/lisa-wiki/templates/wrapper-gitignore.txt +19 -0
  40. package/plugins/src/wiki/scripts/ensure-gitignore.mjs +131 -0
  41. package/plugins/src/wiki/skills/lisa-wiki-setup/SKILL.md +13 -4
  42. package/plugins/src/wiki/templates/wrapper-gitignore.txt +19 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAwB,MAAM,WAAW,CAAC;AAiD1D;;;GAGG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAiCvC;AA+ID,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAwB,MAAM,WAAW,CAAC;AAkD1D;;;GAGG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAkCvC;AAiJD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
package/dist/cli/index.js CHANGED
@@ -11,6 +11,7 @@ import { MigrationRegistry } from "../migrations/index.js";
11
11
  import { StrategyRegistry } from "../strategies/index.js";
12
12
  import { BackupService, DryRunBackupService } from "../transaction/index.js";
13
13
  import { toAbsolutePath } from "../utils/path-utils.js";
14
+ import { getPackageVersion } from "./version.js";
14
15
  import { createPrompter } from "./prompts.js";
15
16
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
17
  /**
@@ -44,8 +45,9 @@ export function createProgram() {
44
45
  program
45
46
  .name("lisa")
46
47
  .description("Claude Code / Codex CLI governance framework - apply guardrails and guidance to projects")
47
- .version("1.0.0")
48
+ .version(getPackageVersion())
48
49
  .argument("[destination]", "Path to the project directory")
50
+ .option("--no-update-check", "Skip the npm latest-version check")
49
51
  .option("-n, --dry-run", "Show what would be done without making changes")
50
52
  .option("-y, --yes", "Non-interactive mode (auto-accept defaults, overwrite on conflict)")
51
53
  .option("-v, --validate", "Validate project compatibility without applying changes")
@@ -69,6 +71,7 @@ function printUsageAndExit() {
69
71
  console.log(" -y, --yes Non-interactive mode (auto-accept defaults, overwrite on conflict)");
70
72
  console.log(" -v, --validate Validate project compatibility without applying changes");
71
73
  console.log(" --skip-git-check Skip dirty git working directory check (for postinstall use)");
74
+ console.log(" --no-update-check Skip the npm latest-version check");
72
75
  console.log(` --harness <h> Target harness for emitted artifacts: ${HARNESS_VALUES.join(" | ")} (persisted in .lisa.config.json)`);
73
76
  console.log(" -h, --help Show this help message");
74
77
  console.log("");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAyB,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D;;;GAGG;AACH,SAAS,UAAU;IACjB,sCAAsC;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,IAAI,oBAAoB,CAC5B,YAAY,OAAO,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CACpD,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CACV,0FAA0F,CAC3F;SACA,OAAO,CAAC,iBAAiB,EAAE,CAAC;SAC5B,QAAQ,CAAC,eAAe,EAAE,+BAA+B,CAAC;SAC1D,MAAM,CAAC,mBAAmB,EAAE,mCAAmC,CAAC;SAChE,MAAM,CAAC,eAAe,EAAE,gDAAgD,CAAC;SACzE,MAAM,CACL,WAAW,EACX,oEAAoE,CACrE;SACA,MAAM,CACL,gBAAgB,EAChB,yDAAyD,CAC1D;SACA,MAAM,CACL,kBAAkB,EAClB,8DAA8D,CAC/D;SACA,MAAM,CACL,qBAAqB,EACrB,yCAAyC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,qDAAqD,EACxH,eAAe,CAChB;SACA,MAAM,CAAC,KAAK,EAAE,WAA+B,EAAE,OAAmB,EAAE,EAAE;QACrE,MAAM,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC;AAcD;;GAEG;AACH,SAAS,iBAAiB;IACxB,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxB,OAAO,CAAC,GAAG,CACT,oEAAoE,CACrE,CAAC;IACF,OAAO,CAAC,GAAG,CACT,wFAAwF,CACzF,CAAC;IACF,OAAO,CAAC,GAAG,CACT,6EAA6E,CAC9E,CAAC;IACF,OAAO,CAAC,GAAG,CACT,kFAAkF,CACnF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CACT,6DAA6D,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,mCAAmC,CAC3H,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CACT,mEAAmE,CACpE,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CACT,+EAA+E,CAChF,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CACzB,MAAe,EACf,OAAgB,EAChB,MAAqB;IAErB,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC;QACjC,aAAa,EAAE,MAAM;YACnB,CAAC,CAAC,IAAI,mBAAmB,EAAE;YAC3B,CAAC,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC;QAC7B,gBAAgB,EAAE,IAAI,gBAAgB,EAAE;QACxC,gBAAgB,EAAE,IAAI,gBAAgB,EAAE;QACxC,UAAU,EAAE,IAAI,UAAU,EAAE;QAC5B,iBAAiB,EAAE,IAAI,iBAAiB,EAAE;KAC3C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,OAAO,CACpB,WAA+B,EAC/B,OAAmB;IAEnB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,iBAAiB,EAAE,CAAC;IACtB,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,IAAI,KAAK,CAAC;IACrC,MAAM,OAAO,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAE5C,0EAA0E;IAC1E,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAE/D,MAAM,MAAM,GAAe;QACzB,OAAO,EAAE,UAAU,EAAE;QACrB,OAAO;QACP,MAAM;QACN,OAAO;QACP,YAAY,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;QACvC,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,KAAK;QAC3C,OAAO;KACR,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ;YAC7B,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE;YACvB,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEvB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,uEAAuE;QACvE,yEAAyE;QACzE,oEAAoE;QACpE,kEAAkE;QAClE,6CAA6C;QAC7C,IACE,CAAC,OAAO,CAAC,QAAQ;YACjB,CAAC,MAAM;YACP,OAAO,CAAC,OAAO,KAAK,SAAS;YAC7B,aAAa,CAAC,OAAO,KAAK,OAAO,EACjC,CAAC;YACD,MAAM,kBAAkB,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { UpdateCheckResult } from "./update-check.js";
2
+ /**
3
+ * Print the user-facing npm update warning for outdated Lisa installs.
4
+ * @param result - Completed update-check result
5
+ */
6
+ export declare function printUpdateWarning(result: UpdateCheckResult): void;
7
+ //# sourceMappingURL=print-update-warning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print-update-warning.d.ts","sourceRoot":"","sources":["../../src/cli/print-update-warning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAYlE"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Print the user-facing npm update warning for outdated Lisa installs.
3
+ * @param result - Completed update-check result
4
+ */
5
+ export function printUpdateWarning(result) {
6
+ if (!result.isOutdated || result.latest === null) {
7
+ return;
8
+ }
9
+ console.error([
10
+ `Lisa ${result.latest} is available; you are running ${result.current}.`,
11
+ "Update with: npm install -g @codyswann/lisa@latest",
12
+ "Continuing with the installed version.",
13
+ ].join("\n"));
14
+ }
15
+ //# sourceMappingURL=print-update-warning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print-update-warning.js","sourceRoot":"","sources":["../../src/cli/print-update-warning.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAyB;IAC1D,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QACjD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,KAAK,CACX;QACE,QAAQ,MAAM,CAAC,MAAM,kCAAkC,MAAM,CAAC,OAAO,GAAG;QACxE,oDAAoD;QACpD,wCAAwC;KACzC,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ /** Runtime options for Lisa's non-fatal update check. */
2
+ export interface UpdateCheckOptions {
3
+ /** Process arguments used to detect --no-update-check. */
4
+ argv?: readonly string[];
5
+ /** Override cache path for tests and controlled runs. */
6
+ cachePath?: string;
7
+ /** Override current package version. */
8
+ currentVersion?: string;
9
+ /** Environment map used to detect LISA_SKIP_UPDATE_CHECK. */
10
+ env?: NodeJS.ProcessEnv;
11
+ /** Fetch implementation override. */
12
+ fetchImpl?: typeof fetch;
13
+ /** Clock override. */
14
+ now?: () => Date;
15
+ /** Registry timeout in milliseconds. */
16
+ timeoutMs?: number;
17
+ /** Cache TTL in milliseconds. */
18
+ ttlMs?: number;
19
+ }
20
+ /** Result from a non-fatal npm latest-version check. */
21
+ export interface UpdateCheckResult {
22
+ /** Installed Lisa version. */
23
+ current: string;
24
+ /** Latest npm version, or null when unavailable/skipped. */
25
+ latest: string | null;
26
+ /** True when latest is a valid semver greater than current. */
27
+ isOutdated: boolean;
28
+ /** Machine-readable non-fatal outcome reason. */
29
+ reason?: string;
30
+ }
31
+ /**
32
+ * Check npm for the latest Lisa version without ever failing the caller.
33
+ * @param opts - Runtime overrides for tests or controlled CLI execution
34
+ * @returns Update-check result with current/latest/outdated metadata
35
+ */
36
+ export declare function runUpdateCheck(opts?: UpdateCheckOptions): Promise<UpdateCheckResult>;
37
+ //# sourceMappingURL=update-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/cli/update-check.ts"],"names":[],"mappings":"AAUA,yDAAyD;AACzD,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,sBAAsB;IACtB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wDAAwD;AACxD,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+DAA+D;IAC/D,UAAU,EAAE,OAAO,CAAC;IACpB,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAyID;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CA+D5B"}
@@ -0,0 +1,147 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ import { gt, valid } from "semver";
5
+ import { getPackageVersion } from "./version.js";
6
+ const DEFAULT_CACHE_TTL_MS = 6 * 60 * 60 * 1000;
7
+ const DEFAULT_TIMEOUT_MS = 2500;
8
+ const NPM_LATEST_URL = "https://registry.npmjs.org/@codyswann/lisa/latest";
9
+ /**
10
+ * Resolve the default Lisa update-check cache path.
11
+ * @returns Absolute cache file path
12
+ */
13
+ function getDefaultCachePath() {
14
+ return path.join(os.homedir(), ".lisa", "update-check.json");
15
+ }
16
+ /**
17
+ * Read process.env through one explicit, reviewable exception to the app-template
18
+ * env rule. The CLI needs externally supplied process env for this root opt-out.
19
+ * @returns Current process environment
20
+ */
21
+ function getProcessEnv() {
22
+ // eslint-disable-next-line no-restricted-syntax -- CLI root option must read externally supplied process env once
23
+ return process.env;
24
+ }
25
+ /**
26
+ * Determine whether the update check is disabled for this invocation.
27
+ * @param argv - Process arguments
28
+ * @param env - Process environment
29
+ * @returns True when a flag or env opt-out is present
30
+ */
31
+ function isUpdateCheckDisabled(argv, env) {
32
+ return (argv.includes("--no-update-check") || env.LISA_SKIP_UPDATE_CHECK === "1");
33
+ }
34
+ /**
35
+ * Return a fresh cached latest version when the cache is usable.
36
+ * @param raw - Raw cache JSON
37
+ * @param now - Current wall-clock time
38
+ * @param ttlMs - Freshness TTL in milliseconds
39
+ * @returns Cached latest version, or null when missing/stale/malformed
40
+ */
41
+ function readCachedLatest(raw, now, ttlMs) {
42
+ const parsed = JSON.parse(raw);
43
+ if (typeof parsed.latest !== "string" ||
44
+ typeof parsed.fetchedAt !== "string") {
45
+ return null;
46
+ }
47
+ if (valid(parsed.latest) === null) {
48
+ return null;
49
+ }
50
+ const fetchedAt = Date.parse(parsed.fetchedAt);
51
+ if (!Number.isFinite(fetchedAt)) {
52
+ return null;
53
+ }
54
+ if (now.getTime() - fetchedAt > ttlMs) {
55
+ return null;
56
+ }
57
+ return parsed.latest;
58
+ }
59
+ /**
60
+ * Convert current/latest values into the public result shape.
61
+ * @param current - Installed version
62
+ * @param latest - Latest version or null
63
+ * @param reason - Optional non-fatal reason
64
+ * @returns Normalized update-check result
65
+ */
66
+ function toResult(current, latest, reason) {
67
+ const isOutdated = typeof latest === "string" &&
68
+ valid(current) !== null &&
69
+ valid(latest) !== null &&
70
+ gt(latest, current);
71
+ return {
72
+ current,
73
+ latest,
74
+ isOutdated,
75
+ ...(reason ? { reason } : {}),
76
+ };
77
+ }
78
+ /**
79
+ * Persist the latest-version cache used by later CLI invocations.
80
+ * @param cachePath - Absolute cache path
81
+ * @param latest - Latest version or null on failure
82
+ * @param fetchedAt - Fetch completion timestamp
83
+ * @param reason - Optional non-fatal reason
84
+ * @returns Promise that resolves after the cache is written
85
+ */
86
+ async function writeCache(cachePath, latest, fetchedAt, reason) {
87
+ await mkdir(path.dirname(cachePath), { recursive: true });
88
+ await writeFile(cachePath, `${JSON.stringify({
89
+ latest,
90
+ fetchedAt: fetchedAt.toISOString(),
91
+ ...(reason ? { reason } : {}),
92
+ }, null, 2)}\n`, "utf8");
93
+ }
94
+ /**
95
+ * Check npm for the latest Lisa version without ever failing the caller.
96
+ * @param opts - Runtime overrides for tests or controlled CLI execution
97
+ * @returns Update-check result with current/latest/outdated metadata
98
+ */
99
+ export async function runUpdateCheck(opts = {}) {
100
+ const current = opts.currentVersion ?? getPackageVersion();
101
+ const argv = opts.argv ?? process.argv;
102
+ const env = opts.env ?? getProcessEnv();
103
+ if (isUpdateCheckDisabled(argv, env)) {
104
+ return toResult(current, null, "skipped");
105
+ }
106
+ const cachePath = opts.cachePath ?? getDefaultCachePath();
107
+ const now = opts.now ?? (() => new Date());
108
+ const ttlMs = opts.ttlMs ?? DEFAULT_CACHE_TTL_MS;
109
+ try {
110
+ const cached = readCachedLatest(await readFile(cachePath, "utf8"), now(), ttlMs);
111
+ if (cached) {
112
+ return toResult(current, cached, "cached");
113
+ }
114
+ }
115
+ catch {
116
+ // Missing or malformed cache should not prevent a fresh check.
117
+ }
118
+ const controller = new AbortController();
119
+ const timeout = setTimeout(() => controller.abort(), opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
120
+ try {
121
+ const response = await (opts.fetchImpl ?? fetch)(NPM_LATEST_URL, {
122
+ signal: controller.signal,
123
+ });
124
+ if (!response.ok) {
125
+ await writeCache(cachePath, null, now(), `http-${response.status}`).catch(() => undefined);
126
+ return toResult(current, null, `http-${response.status}`);
127
+ }
128
+ const body = (await response.json());
129
+ if (typeof body.version !== "string" || valid(body.version) === null) {
130
+ await writeCache(cachePath, null, now(), "invalid-response").catch(() => undefined);
131
+ return toResult(current, null, "invalid-response");
132
+ }
133
+ await writeCache(cachePath, body.version, now()).catch(() => undefined);
134
+ return toResult(current, body.version);
135
+ }
136
+ catch (error) {
137
+ const reason = error instanceof Error && error.name === "AbortError"
138
+ ? "timeout"
139
+ : "network-error";
140
+ await writeCache(cachePath, null, now(), reason).catch(() => undefined);
141
+ return toResult(current, null, reason);
142
+ }
143
+ finally {
144
+ clearTimeout(timeout);
145
+ }
146
+ }
147
+ //# sourceMappingURL=update-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/cli/update-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Read Lisa's package version from package.json and cache it for this process.
3
+ * @returns Package version string
4
+ */
5
+ export declare function getPackageVersion(): string;
6
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/cli/version.ts"],"names":[],"mappings":"AAqBA;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAoB1C"}
@@ -0,0 +1,38 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import * as path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const versionCache = {};
5
+ /**
6
+ * Find the nearest package.json by walking from a compiled/source module path.
7
+ * @param startDir - Directory to start searching from
8
+ * @returns Absolute package.json path, or null when no package file exists above
9
+ */
10
+ function findPackageJson(startDir) {
11
+ const candidate = path.join(startDir, "package.json");
12
+ if (existsSync(candidate)) {
13
+ return candidate;
14
+ }
15
+ const parent = path.dirname(startDir);
16
+ return parent === startDir ? null : findPackageJson(parent);
17
+ }
18
+ /**
19
+ * Read Lisa's package version from package.json and cache it for this process.
20
+ * @returns Package version string
21
+ */
22
+ export function getPackageVersion() {
23
+ if (versionCache.value) {
24
+ return versionCache.value;
25
+ }
26
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
27
+ const packageJsonPath = findPackageJson(moduleDir);
28
+ if (!packageJsonPath) {
29
+ throw new Error("Unable to locate package.json for Lisa CLI version");
30
+ }
31
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
32
+ if (typeof packageJson.version !== "string" || packageJson.version === "") {
33
+ throw new Error("package.json is missing a string version field");
34
+ }
35
+ versionCache.value = packageJson.version;
36
+ return versionCache.value;
37
+ }
38
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/cli/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,YAAY,GAAuB,EAAE,CAAC;AAE5C;;;;GAIG;AACH,SAAS,eAAe,CAAC,QAAgB;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACtD,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;QACvB,OAAO,YAAY,CAAC,KAAK,CAAC;IAC5B,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,MAAM,eAAe,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAEnE,CAAC;IACF,IAAI,OAAO,WAAW,CAAC,OAAO,KAAK,QAAQ,IAAI,WAAW,CAAC,OAAO,KAAK,EAAE,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,YAAY,CAAC,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC;IACzC,OAAO,YAAY,CAAC,KAAK,CAAC;AAC5B,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import { createProgram } from "./cli/index.js";
3
- const program = createProgram();
4
- program.parseAsync().catch(error => {
3
+ import { printUpdateWarning } from "./cli/print-update-warning.js";
4
+ import { runUpdateCheck } from "./cli/update-check.js";
5
+ /**
6
+ * Run the Lisa CLI entrypoint.
7
+ * @returns Promise that resolves after Commander completes
8
+ */
9
+ async function main() {
10
+ const updateCheck = await runUpdateCheck();
11
+ const program = createProgram();
12
+ printUpdateWarning(updateCheck);
13
+ await program.parseAsync();
14
+ }
15
+ main().catch(error => {
5
16
  console.error("Error:", error instanceof Error ? error.message : String(error));
6
17
  process.exit(1);
7
18
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;AAChC,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACjC,OAAO,CAAC,KAAK,CACX,QAAQ,EACR,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;;GAGG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAEhC,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAChC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;AAC7B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CACX,QAAQ,EACR,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -83,7 +83,7 @@
83
83
  "lodash": ">=4.18.1"
84
84
  },
85
85
  "name": "@codyswann/lisa",
86
- "version": "2.117.0",
86
+ "version": "2.119.0",
87
87
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
88
88
  "main": "dist/index.js",
89
89
  "exports": {
@@ -190,6 +190,7 @@
190
190
  "minimatch": "^3.1.2",
191
191
  "picocolors": "^1.0.0",
192
192
  "prettier": "^3.3.3",
193
+ "semver": "^7.8.1",
193
194
  "smol-toml": "^1.6.1",
194
195
  "standard-version": "^9.5.0",
195
196
  "ts-jest": "^29.4.9",
@@ -202,6 +203,7 @@
202
203
  "devDependencies": {
203
204
  "@codyswann/lisa": "^2.98.0",
204
205
  "@types/js-yaml": "^4.0.9",
206
+ "@types/semver": "^7.7.1",
205
207
  "eslint-plugin-oxlint": "^1.62.0",
206
208
  "js-yaml": "^4.1.1",
207
209
  "oxlint": "^1.62.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.117.0",
3
+ "version": "2.119.0",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ensure-gitignore.mjs — merge the lisa-wiki gitignore block into the project's
4
+ * `.gitignore`, idempotently. Dependency-free.
5
+ *
6
+ * The block is delimited by `# BEGIN: AI GUARDRAILS WIKI` and
7
+ * `# END: AI GUARDRAILS WIKI` markers (see templates/wrapper-gitignore.txt).
8
+ * Behavior matches the base lisa plugin's copy-contents strategy
9
+ * (src/strategies/copy-contents.ts):
10
+ *
11
+ * - If the file is missing, create it with just the block.
12
+ * - If the block markers exist, replace the block in place.
13
+ * - If the markers don't exist, append the block to the end (preserving a
14
+ * trailing newline).
15
+ *
16
+ * Patterns outside the marker block are NEVER touched. Re-running produces no
17
+ * spurious diff once the file is in sync.
18
+ *
19
+ * Usage: node ensure-gitignore.mjs [--cwd <project-dir>] [--dry-run]
20
+ * default cwd: process.cwd()
21
+ * --dry-run prints the proposed merge result to stdout instead of writing
22
+ *
23
+ * Exit code 0 = ok (file was created, updated, or already in sync).
24
+ * Exit code 1 = error (e.g. template missing).
25
+ */
26
+ import fs from "node:fs";
27
+ import path from "node:path";
28
+ import { fileURLToPath } from "node:url";
29
+
30
+ const BEGIN_MARKER = "# BEGIN: AI GUARDRAILS WIKI";
31
+ const END_MARKER = "# END: AI GUARDRAILS WIKI";
32
+
33
+ function fail(msg) {
34
+ console.error(`✗ ${msg}`);
35
+ process.exit(1);
36
+ }
37
+
38
+ const scriptDir = path.dirname(fileURLToPath(import.meta.url));
39
+ const pluginRoot = path.dirname(scriptDir);
40
+ const templatePath = path.join(
41
+ pluginRoot,
42
+ "templates",
43
+ "wrapper-gitignore.txt"
44
+ );
45
+
46
+ const argv = process.argv.slice(2);
47
+ const cwdIndex = argv.indexOf("--cwd");
48
+ const projectDir =
49
+ cwdIndex !== -1 && argv[cwdIndex + 1]
50
+ ? path.resolve(argv[cwdIndex + 1])
51
+ : process.cwd();
52
+ const dryRun = argv.includes("--dry-run");
53
+
54
+ if (!fs.existsSync(templatePath)) {
55
+ fail(`template not found: ${templatePath}`);
56
+ }
57
+
58
+ const templateRaw = fs.readFileSync(templatePath, "utf8");
59
+ const block = extractBlock(templateRaw);
60
+ if (!block) {
61
+ fail(
62
+ `template at ${templatePath} does not contain the expected marker pair (${BEGIN_MARKER} / ${END_MARKER})`
63
+ );
64
+ }
65
+
66
+ const gitignorePath = path.join(projectDir, ".gitignore");
67
+ const existing = fs.existsSync(gitignorePath)
68
+ ? fs.readFileSync(gitignorePath, "utf8")
69
+ : null;
70
+
71
+ const merged = mergeBlock(existing, block);
72
+
73
+ if (existing !== null && merged === existing) {
74
+ console.log(`✓ .gitignore already in sync (${gitignorePath})`);
75
+ process.exit(0);
76
+ }
77
+
78
+ if (dryRun) {
79
+ process.stdout.write(merged);
80
+ process.exit(0);
81
+ }
82
+
83
+ fs.writeFileSync(gitignorePath, merged);
84
+ const verb = existing === null ? "created" : "updated";
85
+ console.log(`✓ ${verb} ${gitignorePath}`);
86
+ process.exit(0);
87
+
88
+ /**
89
+ * Pull the block (markers included) out of arbitrary text. Returns null when
90
+ * the marker pair is missing or out of order.
91
+ */
92
+ function extractBlock(text) {
93
+ const startIdx = text.indexOf(BEGIN_MARKER);
94
+ if (startIdx === -1) return null;
95
+ const endStart = text.indexOf(END_MARKER, startIdx + BEGIN_MARKER.length);
96
+ if (endStart === -1) return null;
97
+ const endIdx = endStart + END_MARKER.length;
98
+ return text.slice(startIdx, endIdx);
99
+ }
100
+
101
+ /**
102
+ * Merge a freshly-rendered block into the destination file content.
103
+ * - existing === null → return the block alone (file will be created)
104
+ * - existing has the markers → replace the block in place
105
+ * - existing lacks the markers → append the block at the end
106
+ * Always normalizes to exactly one trailing newline.
107
+ */
108
+ function mergeBlock(existing, freshBlock) {
109
+ if (existing === null) {
110
+ return `${freshBlock.trimEnd()}\n`;
111
+ }
112
+
113
+ const startIdx = existing.indexOf(BEGIN_MARKER);
114
+ if (startIdx !== -1) {
115
+ const endStart = existing.indexOf(
116
+ END_MARKER,
117
+ startIdx + BEGIN_MARKER.length
118
+ );
119
+ if (endStart !== -1) {
120
+ const endIdx = endStart + END_MARKER.length;
121
+ const before = existing.slice(0, startIdx);
122
+ const after = existing.slice(endIdx);
123
+ const trimmedAfter = after.startsWith("\n") ? after : `\n${after}`;
124
+ return `${before}${freshBlock.trimEnd()}${trimmedAfter}`;
125
+ }
126
+ }
127
+
128
+ // No marker pair in the destination — append.
129
+ const base = existing.endsWith("\n") ? existing : `${existing}\n`;
130
+ return `${base}\n${freshBlock.trimEnd()}\n`;
131
+ }
@@ -30,13 +30,22 @@ never overwrites human-authored content.
30
30
  3. **Contract.** Render `wiki/schema/llm-wiki-contract.md` from the plugin templates + config via
31
31
  `scripts/render-contract.mjs`, stamping the `kernelVersion`. This snapshot keeps the wiki
32
32
  self-describing without the plugin installed.
33
- 4. **Pointers.** Ensure `AGENTS.md` / `CLAUDE.md` point at the contract + plugin (thin pointers only).
34
- 5. **Staff.** For each `config.staff[]` entry (the standard roster by default), generate the role's
33
+ 4. **Gitignore.** Merge the lisa-wiki gitignore block into the project's `.gitignore` via
34
+ `scripts/ensure-gitignore.mjs`. The block (delimited by `# BEGIN: AI GUARDRAILS WIKI` /
35
+ `# END: AI GUARDRAILS WIKI`) covers transient per-session worktrees and Lisa backup snapshots
36
+ (`.claude/worktrees/`, `.codex/worktrees/`, `.lisabak/`). Idempotent: re-running produces no
37
+ diff once the block is present. The block coexists with the base lisa plugin's
38
+ `# BEGIN: AI GUARDRAILS` block — both can be installed without overwriting each other because
39
+ the copy-contents strategy keys on the marker suffix. Wiki-wrapper repos (mode `wrapper` /
40
+ `standalone`) typically don't enable the base lisa plugin, so this step is the only path by
41
+ which they get the worktree-ignore patterns.
42
+ 5. **Pointers.** Ensure `AGENTS.md` / `CLAUDE.md` point at the contract + plugin (thin pointers only).
43
+ 6. **Staff.** For each `config.staff[]` entry (the standard roster by default), generate the role's
35
44
  `wiki/staff/<role>.md` page and its dual-runtime subagents by delegating to `lisa-wiki-add-role`
36
45
  (running the subagents is out of scope).
37
- 6. **README.** Apply the chosen README mode (ingest the old README first; `rich` keeps install/usage +
46
+ 7. **README.** Apply the chosen README mode (ingest the old README first; `rich` keeps install/usage +
38
47
  adds the onboarding line; `stub` is the minimal pointer; `preserve` leaves it).
39
- 7. **Verify.** Run `lisa-wiki-doctor` and report the verdict + any blocking items.
48
+ 8. **Verify.** Run `lisa-wiki-doctor` and report the verdict + any blocking items.
40
49
 
41
50
  ## Standard roster
42
51
  The default operating team seeded into `config.staff[]` for every new wiki (Chief of Staff plus six
@@ -0,0 +1,19 @@
1
+ # BEGIN: AI GUARDRAILS WIKI
2
+ # Managed by the lisa-wiki kernel. Do not edit between these markers — re-run
3
+ # /lisa-wiki:setup (or the equivalent script) to update. Patterns outside the
4
+ # block are preserved untouched. The "WIKI" suffix lets this block coexist
5
+ # with the base lisa plugin's "# BEGIN: AI GUARDRAILS" block when both are
6
+ # installed (the copy-contents strategy keys on the marker suffix).
7
+
8
+ # Claude Code per-session git worktrees. Each Claude session that needs an
9
+ # isolated working copy spawns one under .claude/worktrees/ (via
10
+ # `git worktree add`). They are transient, large (often hundreds of MB each),
11
+ # and per-developer; they must never be committed.
12
+ /.claude/worktrees/
13
+
14
+ # Codex CLI per-session worktrees (Codex equivalent of the above).
15
+ /.codex/worktrees/
16
+
17
+ # Lisa backup snapshots (created by `lisa` runs).
18
+ /.lisabak/
19
+ # END: AI GUARDRAILS WIKI
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ensure-gitignore.mjs — merge the lisa-wiki gitignore block into the project's
4
+ * `.gitignore`, idempotently. Dependency-free.
5
+ *
6
+ * The block is delimited by `# BEGIN: AI GUARDRAILS WIKI` and
7
+ * `# END: AI GUARDRAILS WIKI` markers (see templates/wrapper-gitignore.txt).
8
+ * Behavior matches the base lisa plugin's copy-contents strategy
9
+ * (src/strategies/copy-contents.ts):
10
+ *
11
+ * - If the file is missing, create it with just the block.
12
+ * - If the block markers exist, replace the block in place.
13
+ * - If the markers don't exist, append the block to the end (preserving a
14
+ * trailing newline).
15
+ *
16
+ * Patterns outside the marker block are NEVER touched. Re-running produces no
17
+ * spurious diff once the file is in sync.
18
+ *
19
+ * Usage: node ensure-gitignore.mjs [--cwd <project-dir>] [--dry-run]
20
+ * default cwd: process.cwd()
21
+ * --dry-run prints the proposed merge result to stdout instead of writing
22
+ *
23
+ * Exit code 0 = ok (file was created, updated, or already in sync).
24
+ * Exit code 1 = error (e.g. template missing).
25
+ */
26
+ import fs from "node:fs";
27
+ import path from "node:path";
28
+ import { fileURLToPath } from "node:url";
29
+
30
+ const BEGIN_MARKER = "# BEGIN: AI GUARDRAILS WIKI";
31
+ const END_MARKER = "# END: AI GUARDRAILS WIKI";
32
+
33
+ function fail(msg) {
34
+ console.error(`✗ ${msg}`);
35
+ process.exit(1);
36
+ }
37
+
38
+ const scriptDir = path.dirname(fileURLToPath(import.meta.url));
39
+ const pluginRoot = path.dirname(scriptDir);
40
+ const templatePath = path.join(
41
+ pluginRoot,
42
+ "templates",
43
+ "wrapper-gitignore.txt"
44
+ );
45
+
46
+ const argv = process.argv.slice(2);
47
+ const cwdIndex = argv.indexOf("--cwd");
48
+ const projectDir =
49
+ cwdIndex !== -1 && argv[cwdIndex + 1]
50
+ ? path.resolve(argv[cwdIndex + 1])
51
+ : process.cwd();
52
+ const dryRun = argv.includes("--dry-run");
53
+
54
+ if (!fs.existsSync(templatePath)) {
55
+ fail(`template not found: ${templatePath}`);
56
+ }
57
+
58
+ const templateRaw = fs.readFileSync(templatePath, "utf8");
59
+ const block = extractBlock(templateRaw);
60
+ if (!block) {
61
+ fail(
62
+ `template at ${templatePath} does not contain the expected marker pair (${BEGIN_MARKER} / ${END_MARKER})`
63
+ );
64
+ }
65
+
66
+ const gitignorePath = path.join(projectDir, ".gitignore");
67
+ const existing = fs.existsSync(gitignorePath)
68
+ ? fs.readFileSync(gitignorePath, "utf8")
69
+ : null;
70
+
71
+ const merged = mergeBlock(existing, block);
72
+
73
+ if (existing !== null && merged === existing) {
74
+ console.log(`✓ .gitignore already in sync (${gitignorePath})`);
75
+ process.exit(0);
76
+ }
77
+
78
+ if (dryRun) {
79
+ process.stdout.write(merged);
80
+ process.exit(0);
81
+ }
82
+
83
+ fs.writeFileSync(gitignorePath, merged);
84
+ const verb = existing === null ? "created" : "updated";
85
+ console.log(`✓ ${verb} ${gitignorePath}`);
86
+ process.exit(0);
87
+
88
+ /**
89
+ * Pull the block (markers included) out of arbitrary text. Returns null when
90
+ * the marker pair is missing or out of order.
91
+ */
92
+ function extractBlock(text) {
93
+ const startIdx = text.indexOf(BEGIN_MARKER);
94
+ if (startIdx === -1) return null;
95
+ const endStart = text.indexOf(END_MARKER, startIdx + BEGIN_MARKER.length);
96
+ if (endStart === -1) return null;
97
+ const endIdx = endStart + END_MARKER.length;
98
+ return text.slice(startIdx, endIdx);
99
+ }
100
+
101
+ /**
102
+ * Merge a freshly-rendered block into the destination file content.
103
+ * - existing === null → return the block alone (file will be created)
104
+ * - existing has the markers → replace the block in place
105
+ * - existing lacks the markers → append the block at the end
106
+ * Always normalizes to exactly one trailing newline.
107
+ */
108
+ function mergeBlock(existing, freshBlock) {
109
+ if (existing === null) {
110
+ return `${freshBlock.trimEnd()}\n`;
111
+ }
112
+
113
+ const startIdx = existing.indexOf(BEGIN_MARKER);
114
+ if (startIdx !== -1) {
115
+ const endStart = existing.indexOf(
116
+ END_MARKER,
117
+ startIdx + BEGIN_MARKER.length
118
+ );
119
+ if (endStart !== -1) {
120
+ const endIdx = endStart + END_MARKER.length;
121
+ const before = existing.slice(0, startIdx);
122
+ const after = existing.slice(endIdx);
123
+ const trimmedAfter = after.startsWith("\n") ? after : `\n${after}`;
124
+ return `${before}${freshBlock.trimEnd()}${trimmedAfter}`;
125
+ }
126
+ }
127
+
128
+ // No marker pair in the destination — append.
129
+ const base = existing.endsWith("\n") ? existing : `${existing}\n`;
130
+ return `${base}\n${freshBlock.trimEnd()}\n`;
131
+ }
@@ -30,13 +30,22 @@ never overwrites human-authored content.
30
30
  3. **Contract.** Render `wiki/schema/llm-wiki-contract.md` from the plugin templates + config via
31
31
  `scripts/render-contract.mjs`, stamping the `kernelVersion`. This snapshot keeps the wiki
32
32
  self-describing without the plugin installed.
33
- 4. **Pointers.** Ensure `AGENTS.md` / `CLAUDE.md` point at the contract + plugin (thin pointers only).
34
- 5. **Staff.** For each `config.staff[]` entry (the standard roster by default), generate the role's
33
+ 4. **Gitignore.** Merge the lisa-wiki gitignore block into the project's `.gitignore` via
34
+ `scripts/ensure-gitignore.mjs`. The block (delimited by `# BEGIN: AI GUARDRAILS WIKI` /
35
+ `# END: AI GUARDRAILS WIKI`) covers transient per-session worktrees and Lisa backup snapshots
36
+ (`.claude/worktrees/`, `.codex/worktrees/`, `.lisabak/`). Idempotent: re-running produces no
37
+ diff once the block is present. The block coexists with the base lisa plugin's
38
+ `# BEGIN: AI GUARDRAILS` block — both can be installed without overwriting each other because
39
+ the copy-contents strategy keys on the marker suffix. Wiki-wrapper repos (mode `wrapper` /
40
+ `standalone`) typically don't enable the base lisa plugin, so this step is the only path by
41
+ which they get the worktree-ignore patterns.
42
+ 5. **Pointers.** Ensure `AGENTS.md` / `CLAUDE.md` point at the contract + plugin (thin pointers only).
43
+ 6. **Staff.** For each `config.staff[]` entry (the standard roster by default), generate the role's
35
44
  `wiki/staff/<role>.md` page and its dual-runtime subagents by delegating to `lisa-wiki-add-role`
36
45
  (running the subagents is out of scope).
37
- 6. **README.** Apply the chosen README mode (ingest the old README first; `rich` keeps install/usage +
46
+ 7. **README.** Apply the chosen README mode (ingest the old README first; `rich` keeps install/usage +
38
47
  adds the onboarding line; `stub` is the minimal pointer; `preserve` leaves it).
39
- 7. **Verify.** Run `lisa-wiki-doctor` and report the verdict + any blocking items.
48
+ 8. **Verify.** Run `lisa-wiki-doctor` and report the verdict + any blocking items.
40
49
 
41
50
  ## Standard roster
42
51
  The default operating team seeded into `config.staff[]` for every new wiki (Chief of Staff plus six
@@ -0,0 +1,19 @@
1
+ # BEGIN: AI GUARDRAILS WIKI
2
+ # Managed by the lisa-wiki kernel. Do not edit between these markers — re-run
3
+ # /lisa-wiki:setup (or the equivalent script) to update. Patterns outside the
4
+ # block are preserved untouched. The "WIKI" suffix lets this block coexist
5
+ # with the base lisa plugin's "# BEGIN: AI GUARDRAILS" block when both are
6
+ # installed (the copy-contents strategy keys on the marker suffix).
7
+
8
+ # Claude Code per-session git worktrees. Each Claude session that needs an
9
+ # isolated working copy spawns one under .claude/worktrees/ (via
10
+ # `git worktree add`). They are transient, large (often hundreds of MB each),
11
+ # and per-developer; they must never be committed.
12
+ /.claude/worktrees/
13
+
14
+ # Codex CLI per-session worktrees (Codex equivalent of the above).
15
+ /.codex/worktrees/
16
+
17
+ # Lisa backup snapshots (created by `lisa` runs).
18
+ /.lisabak/
19
+ # END: AI GUARDRAILS WIKI