@codyswann/lisa 3.26.0 → 3.26.2

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 (161) hide show
  1. package/all/copy-overwrite/scripts/check-state-classification.mjs +31 -0
  2. package/all/copy-overwrite/scripts/lisa-gates.mjs +10 -1
  3. package/all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh +136 -15
  4. package/dist/cli/doctor-lisa-owned-artifacts.d.ts.map +1 -1
  5. package/dist/cli/doctor-lisa-owned-artifacts.js +13 -2
  6. package/dist/cli/doctor-lisa-owned-artifacts.js.map +1 -1
  7. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  8. package/dist/core/lisa-owned-hash-ledger.js +6 -0
  9. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  10. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  11. package/dist/core/upstream-evidence-manifest.js +24 -23
  12. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  13. package/package.json +1 -1
  14. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  15. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  16. package/plugins/lisa/.codex-plugin/skills/lisa-atlassian-access/scripts/markdown-to-adf.mjs +23 -1
  17. package/plugins/lisa/.codex-plugin/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +31 -2
  18. package/plugins/lisa/.codex-plugin/skills/lisa-remote-dispatch/scripts/dispatch.mjs +30 -2
  19. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/doctor-secrets.mjs +25 -1
  20. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/inspect-vault.mjs +23 -1
  21. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +24 -1
  22. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/read-secret-note.mjs +25 -2
  23. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/resolve-secret.mjs +25 -2
  24. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/rotate-secret.mjs +25 -2
  25. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/sync-secret-to-ci.mjs +25 -1
  26. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/validate-config.mjs +25 -2
  27. package/plugins/lisa/.codex-plugin/skills/lisa-setup-automations/scripts/generate-workflow.mjs +31 -2
  28. package/plugins/lisa/.codex-plugin/skills/lisa-setup-local-env/scripts/local-env.mjs +24 -2
  29. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +23 -1
  30. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/verify-remote-env.mjs +25 -2
  31. package/plugins/lisa/hooks/block-managed-file-edits.sh +136 -15
  32. package/plugins/lisa/skills/lisa-atlassian-access/scripts/markdown-to-adf.mjs +23 -1
  33. package/plugins/lisa/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +31 -2
  34. package/plugins/lisa/skills/lisa-remote-dispatch/scripts/dispatch.mjs +30 -2
  35. package/plugins/lisa/skills/lisa-secrets-access/scripts/doctor-secrets.mjs +25 -1
  36. package/plugins/lisa/skills/lisa-secrets-access/scripts/inspect-vault.mjs +23 -1
  37. package/plugins/lisa/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +24 -1
  38. package/plugins/lisa/skills/lisa-secrets-access/scripts/read-secret-note.mjs +25 -2
  39. package/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs +25 -2
  40. package/plugins/lisa/skills/lisa-secrets-access/scripts/rotate-secret.mjs +25 -2
  41. package/plugins/lisa/skills/lisa-secrets-access/scripts/sync-secret-to-ci.mjs +25 -1
  42. package/plugins/lisa/skills/lisa-secrets-access/scripts/validate-config.mjs +25 -2
  43. package/plugins/lisa/skills/lisa-setup-automations/scripts/generate-workflow.mjs +31 -2
  44. package/plugins/lisa/skills/lisa-setup-local-env/scripts/local-env.mjs +24 -2
  45. package/plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +23 -1
  46. package/plugins/lisa/skills/lisa-setup-remote-env/scripts/verify-remote-env.mjs +25 -2
  47. package/plugins/lisa-agy/plugin.json +1 -1
  48. package/plugins/lisa-agy/skills/lisa-atlassian-access/scripts/markdown-to-adf.mjs +23 -1
  49. package/plugins/lisa-agy/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +31 -2
  50. package/plugins/lisa-agy/skills/lisa-remote-dispatch/scripts/dispatch.mjs +30 -2
  51. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/doctor-secrets.mjs +25 -1
  52. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/inspect-vault.mjs +23 -1
  53. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +24 -1
  54. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/read-secret-note.mjs +25 -2
  55. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/resolve-secret.mjs +25 -2
  56. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/rotate-secret.mjs +25 -2
  57. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/sync-secret-to-ci.mjs +25 -1
  58. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/validate-config.mjs +25 -2
  59. package/plugins/lisa-agy/skills/lisa-setup-automations/scripts/generate-workflow.mjs +31 -2
  60. package/plugins/lisa-agy/skills/lisa-setup-local-env/scripts/local-env.mjs +24 -2
  61. package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +23 -1
  62. package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/verify-remote-env.mjs +25 -2
  63. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  65. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  66. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-copilot/hooks/block-managed-file-edits.sh +136 -15
  70. package/plugins/lisa-copilot/skills/lisa-atlassian-access/scripts/markdown-to-adf.mjs +23 -1
  71. package/plugins/lisa-copilot/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +31 -2
  72. package/plugins/lisa-copilot/skills/lisa-remote-dispatch/scripts/dispatch.mjs +30 -2
  73. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/doctor-secrets.mjs +25 -1
  74. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/inspect-vault.mjs +23 -1
  75. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +24 -1
  76. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/read-secret-note.mjs +25 -2
  77. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/resolve-secret.mjs +25 -2
  78. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/rotate-secret.mjs +25 -2
  79. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/sync-secret-to-ci.mjs +25 -1
  80. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/validate-config.mjs +25 -2
  81. package/plugins/lisa-copilot/skills/lisa-setup-automations/scripts/generate-workflow.mjs +31 -2
  82. package/plugins/lisa-copilot/skills/lisa-setup-local-env/scripts/local-env.mjs +24 -2
  83. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +23 -1
  84. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/verify-remote-env.mjs +25 -2
  85. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-cursor/hooks/block-managed-file-edits.sh +136 -15
  87. package/plugins/lisa-cursor/skills/lisa-atlassian-access/scripts/markdown-to-adf.mjs +23 -1
  88. package/plugins/lisa-cursor/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +31 -2
  89. package/plugins/lisa-cursor/skills/lisa-remote-dispatch/scripts/dispatch.mjs +30 -2
  90. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/doctor-secrets.mjs +25 -1
  91. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/inspect-vault.mjs +23 -1
  92. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +24 -1
  93. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/read-secret-note.mjs +25 -2
  94. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/resolve-secret.mjs +25 -2
  95. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/rotate-secret.mjs +25 -2
  96. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/sync-secret-to-ci.mjs +25 -1
  97. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/validate-config.mjs +25 -2
  98. package/plugins/lisa-cursor/skills/lisa-setup-automations/scripts/generate-workflow.mjs +31 -2
  99. package/plugins/lisa-cursor/skills/lisa-setup-local-env/scripts/local-env.mjs +24 -2
  100. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +23 -1
  101. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/verify-remote-env.mjs +25 -2
  102. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  104. package/plugins/lisa-expo-agy/plugin.json +1 -1
  105. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  106. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  109. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  110. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  111. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  112. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  113. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  114. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  115. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  116. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  117. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  118. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  119. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  120. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  121. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  122. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  123. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  124. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  125. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  126. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  127. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  128. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  129. package/plugins/lisa-rails-agy/plugin.json +1 -1
  130. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  131. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  132. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  133. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  134. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  135. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  136. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  137. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  138. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  139. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  140. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  141. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  142. package/plugins/src/base/hooks/block-managed-file-edits.sh +136 -15
  143. package/plugins/src/base/skills/lisa-atlassian-access/scripts/markdown-to-adf.mjs +23 -1
  144. package/plugins/src/base/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +31 -2
  145. package/plugins/src/base/skills/lisa-remote-dispatch/scripts/dispatch.mjs +30 -2
  146. package/plugins/src/base/skills/lisa-secrets-access/scripts/doctor-secrets.mjs +25 -1
  147. package/plugins/src/base/skills/lisa-secrets-access/scripts/inspect-vault.mjs +23 -1
  148. package/plugins/src/base/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +24 -1
  149. package/plugins/src/base/skills/lisa-secrets-access/scripts/read-secret-note.mjs +25 -2
  150. package/plugins/src/base/skills/lisa-secrets-access/scripts/resolve-secret.mjs +25 -2
  151. package/plugins/src/base/skills/lisa-secrets-access/scripts/rotate-secret.mjs +25 -2
  152. package/plugins/src/base/skills/lisa-secrets-access/scripts/sync-secret-to-ci.mjs +25 -1
  153. package/plugins/src/base/skills/lisa-secrets-access/scripts/validate-config.mjs +25 -2
  154. package/plugins/src/base/skills/lisa-setup-automations/scripts/generate-workflow.mjs +31 -2
  155. package/plugins/src/base/skills/lisa-setup-local-env/scripts/local-env.mjs +24 -2
  156. package/plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +23 -1
  157. package/plugins/src/base/skills/lisa-setup-remote-env/scripts/verify-remote-env.mjs +25 -2
  158. package/scripts/generate-agy-plugin-artifacts.mjs +2 -1
  159. package/scripts/generate-copilot-plugin-artifacts.mjs +2 -1
  160. package/scripts/generate-cursor-plugin-artifacts.mjs +2 -1
  161. package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +14 -3
package/package.json CHANGED
@@ -129,7 +129,7 @@
129
129
  }
130
130
  },
131
131
  "name": "@codyswann/lisa",
132
- "version": "3.26.0",
132
+ "version": "3.26.2",
133
133
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
134
134
  "main": "dist/index.js",
135
135
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.26.0",
3
+ "version": "3.26.2",
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": "3.26.0",
3
+ "version": "3.26.2",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -202,7 +202,29 @@ function parseInline(text) {
202
202
  return nodes.length > 0 ? nodes : [{ type: "text", text: "" }];
203
203
  }
204
204
 
205
- if (import.meta.url === `file://${process.argv[1]}`) {
205
+ /**
206
+ * Whether this module is the one node was asked to run.
207
+ *
208
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
209
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
210
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
211
+ *
212
+ * A local copy rather than an import: plugin payload scripts ship standalone,
213
+ * with no `lib/` sibling to import from once installed.
214
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
215
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
216
+ * @returns {boolean} Whether the caller should run its CLI body.
217
+ */
218
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
219
+ if (!argv1) return false;
220
+ try {
221
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
222
+ } catch {
223
+ return false;
224
+ }
225
+ }
226
+
227
+ if (invokedAsScript(import.meta.url)) {
206
228
  let input = "";
207
229
  process.stdin.setEncoding("utf8");
208
230
  process.stdin.on("data", chunk => {
@@ -22,7 +22,14 @@
22
22
  * @module detect-tooling
23
23
  */
24
24
 
25
- import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
25
+ import {
26
+ existsSync,
27
+ readFileSync,
28
+ readdirSync,
29
+ statSync,
30
+ realpathSync,
31
+ } from "node:fs";
32
+ import { fileURLToPath } from "node:url";
26
33
  import { join } from "node:path";
27
34
 
28
35
  import { commandsIn } from "./commands.mjs";
@@ -583,7 +590,29 @@ export function proposedEntries(proposal) {
583
590
  };
584
591
  }
585
592
 
586
- if (process.argv[1] && import.meta.url === `file://${process.argv[1]}`) {
593
+ /**
594
+ * Whether this module is the one node was asked to run.
595
+ *
596
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
597
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
598
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
599
+ *
600
+ * A local copy rather than an import: plugin payload scripts ship standalone,
601
+ * with no `lib/` sibling to import from once installed.
602
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
603
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
604
+ * @returns {boolean} Whether the caller should run its CLI body.
605
+ */
606
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
607
+ if (!argv1) return false;
608
+ try {
609
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
610
+ } catch {
611
+ return false;
612
+ }
613
+ }
614
+
615
+ if (invokedAsScript(import.meta.url)) {
587
616
  const proposals = detectTooling();
588
617
  if (process.argv.includes("--json")) {
589
618
  console.log(JSON.stringify(proposals, null, 2));
@@ -20,7 +20,13 @@
20
20
  */
21
21
 
22
22
  import { execFileSync } from "node:child_process";
23
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
23
+ import {
24
+ existsSync,
25
+ mkdirSync,
26
+ readFileSync,
27
+ writeFileSync,
28
+ realpathSync,
29
+ } from "node:fs";
24
30
  import { dirname, join, resolve } from "node:path";
25
31
  import { fileURLToPath } from "node:url";
26
32
 
@@ -495,7 +501,29 @@ async function main() {
495
501
  console.log(`recorded in ${LEDGER}; not polling — this process is done.`);
496
502
  }
497
503
 
498
- if (import.meta.url === `file://${process.argv[1]}`) {
504
+ /**
505
+ * Whether this module is the one node was asked to run.
506
+ *
507
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
508
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
509
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
510
+ *
511
+ * A local copy rather than an import: plugin payload scripts ship standalone,
512
+ * with no `lib/` sibling to import from once installed.
513
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
514
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
515
+ * @returns {boolean} Whether the caller should run its CLI body.
516
+ */
517
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
518
+ if (!argv1) return false;
519
+ try {
520
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
521
+ } catch {
522
+ return false;
523
+ }
524
+ }
525
+
526
+ if (invokedAsScript(import.meta.url)) {
499
527
  // Awaited rather than called bare: one dispatch path is async, so a synchronous
500
528
  // try/catch would let a rejection escape as an unhandled rejection and exit 0 —
501
529
  // reporting dispatched work that was never accepted.
@@ -18,6 +18,8 @@
18
18
  */
19
19
 
20
20
  import { createHash } from "node:crypto";
21
+ import { fileURLToPath } from "node:url";
22
+ import { realpathSync } from "node:fs";
21
23
 
22
24
  import { validateNote } from "./note-format.mjs";
23
25
  import { fetchAll, fetchRotatable } from "./providers.mjs";
@@ -239,7 +241,29 @@ function main() {
239
241
  if (errors) throw new Error(`${errors} secrets configuration error(s)`);
240
242
  }
241
243
 
242
- if (import.meta.url === `file://${process.argv[1]}`) {
244
+ /**
245
+ * Whether this module is the one node was asked to run.
246
+ *
247
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
248
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
249
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
250
+ *
251
+ * A local copy rather than an import: plugin payload scripts ship standalone,
252
+ * with no `lib/` sibling to import from once installed.
253
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
254
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
255
+ * @returns {boolean} Whether the caller should run its CLI body.
256
+ */
257
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
258
+ if (!argv1) return false;
259
+ try {
260
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
261
+ } catch {
262
+ return false;
263
+ }
264
+ }
265
+
266
+ if (invokedAsScript(import.meta.url)) {
243
267
  try {
244
268
  main();
245
269
  } catch (err) {
@@ -115,6 +115,28 @@ function main() {
115
115
  console.log(`\n${rows.length} secret(s). Values are never printed.`);
116
116
  }
117
117
 
118
- if (import.meta.url === `file://${process.argv[1]}`) {
118
+ /**
119
+ * Whether this module is the one node was asked to run.
120
+ *
121
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
122
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
123
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
124
+ *
125
+ * A local copy rather than an import: plugin payload scripts ship standalone,
126
+ * with no `lib/` sibling to import from once installed.
127
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
128
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
129
+ * @returns {boolean} Whether the caller should run its CLI body.
130
+ */
131
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
132
+ if (!argv1) return false;
133
+ try {
134
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
135
+ } catch {
136
+ return false;
137
+ }
138
+ }
139
+
140
+ if (invokedAsScript(import.meta.url)) {
119
141
  main();
120
142
  }
@@ -30,6 +30,7 @@ import {
30
30
  } from "node:fs";
31
31
  import { homedir } from "node:os";
32
32
  import { join } from "node:path";
33
+ import { fileURLToPath } from "node:url";
33
34
 
34
35
  import {
35
36
  BOOTSTRAP_KEY,
@@ -454,7 +455,29 @@ function main() {
454
455
  }
455
456
  }
456
457
 
457
- if (import.meta.url === `file://${process.argv[1]}`) {
458
+ /**
459
+ * Whether this module is the one node was asked to run.
460
+ *
461
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
462
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
463
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
464
+ *
465
+ * A local copy rather than an import: plugin payload scripts ship standalone,
466
+ * with no `lib/` sibling to import from once installed.
467
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
468
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
469
+ * @returns {boolean} Whether the caller should run its CLI body.
470
+ */
471
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
472
+ if (!argv1) return false;
473
+ try {
474
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
475
+ } catch {
476
+ return false;
477
+ }
478
+ }
479
+
480
+ if (invokedAsScript(import.meta.url)) {
458
481
  try {
459
482
  main();
460
483
  } catch (err) {
@@ -13,7 +13,8 @@
13
13
  * @module read-secret-note
14
14
  */
15
15
 
16
- import { existsSync, readFileSync } from "node:fs";
16
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
17
+ import { fileURLToPath } from "node:url";
17
18
 
18
19
  import { materializedPaths, readConfig } from "./surfaces.mjs";
19
20
 
@@ -72,7 +73,29 @@ function main() {
72
73
  console.log(noteFor(name, loadNotes(notesFile)));
73
74
  }
74
75
 
75
- if (import.meta.url === `file://${process.argv[1]}`) {
76
+ /**
77
+ * Whether this module is the one node was asked to run.
78
+ *
79
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
80
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
81
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
82
+ *
83
+ * A local copy rather than an import: plugin payload scripts ship standalone,
84
+ * with no `lib/` sibling to import from once installed.
85
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
86
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
87
+ * @returns {boolean} Whether the caller should run its CLI body.
88
+ */
89
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
90
+ if (!argv1) return false;
91
+ try {
92
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
93
+ } catch {
94
+ return false;
95
+ }
96
+ }
97
+
98
+ if (invokedAsScript(import.meta.url)) {
76
99
  try {
77
100
  main();
78
101
  } catch (err) {
@@ -27,7 +27,8 @@
27
27
  * @module resolve-secret
28
28
  */
29
29
 
30
- import { existsSync, readFileSync } from "node:fs";
30
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
31
+ import { fileURLToPath } from "node:url";
31
32
 
32
33
  import { parseEnv } from "./envfile.mjs";
33
34
  import { validateNote } from "./note-format.mjs";
@@ -252,7 +253,29 @@ function main() {
252
253
  );
253
254
  }
254
255
 
255
- if (import.meta.url === `file://${process.argv[1]}`) {
256
+ /**
257
+ * Whether this module is the one node was asked to run.
258
+ *
259
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
260
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
261
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
262
+ *
263
+ * A local copy rather than an import: plugin payload scripts ship standalone,
264
+ * with no `lib/` sibling to import from once installed.
265
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
266
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
267
+ * @returns {boolean} Whether the caller should run its CLI body.
268
+ */
269
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
270
+ if (!argv1) return false;
271
+ try {
272
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
273
+ } catch {
274
+ return false;
275
+ }
276
+ }
277
+
278
+ if (invokedAsScript(import.meta.url)) {
256
279
  try {
257
280
  main();
258
281
  } catch (err) {
@@ -27,7 +27,8 @@
27
27
  * @module rotate-secret
28
28
  */
29
29
 
30
- import { readFileSync } from "node:fs";
30
+ import { readFileSync, realpathSync } from "node:fs";
31
+ import { fileURLToPath } from "node:url";
31
32
  import { hostname } from "node:os";
32
33
 
33
34
  import {
@@ -264,7 +265,29 @@ function main() {
264
265
  );
265
266
  }
266
267
 
267
- if (import.meta.url === `file://${process.argv[1]}`) {
268
+ /**
269
+ * Whether this module is the one node was asked to run.
270
+ *
271
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
272
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
273
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
274
+ *
275
+ * A local copy rather than an import: plugin payload scripts ship standalone,
276
+ * with no `lib/` sibling to import from once installed.
277
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
278
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
279
+ * @returns {boolean} Whether the caller should run its CLI body.
280
+ */
281
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
282
+ if (!argv1) return false;
283
+ try {
284
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
285
+ } catch {
286
+ return false;
287
+ }
288
+ }
289
+
290
+ if (invokedAsScript(import.meta.url)) {
268
291
  try {
269
292
  main();
270
293
  } catch (err) {
@@ -48,6 +48,8 @@
48
48
  */
49
49
 
50
50
  import { execFileSync } from "node:child_process";
51
+ import { fileURLToPath } from "node:url";
52
+ import { realpathSync } from "node:fs";
51
53
 
52
54
  import { ENV_KEY, fetchAll } from "./providers.mjs";
53
55
  import { readConfig } from "./surfaces.mjs";
@@ -471,7 +473,29 @@ function main() {
471
473
  );
472
474
  }
473
475
 
474
- if (import.meta.url === `file://${process.argv[1]}`) {
476
+ /**
477
+ * Whether this module is the one node was asked to run.
478
+ *
479
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
480
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
481
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
482
+ *
483
+ * A local copy rather than an import: plugin payload scripts ship standalone,
484
+ * with no `lib/` sibling to import from once installed.
485
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
486
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
487
+ * @returns {boolean} Whether the caller should run its CLI body.
488
+ */
489
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
490
+ if (!argv1) return false;
491
+ try {
492
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
493
+ } catch {
494
+ return false;
495
+ }
496
+ }
497
+
498
+ if (invokedAsScript(import.meta.url)) {
475
499
  try {
476
500
  main();
477
501
  } catch (err) {
@@ -16,7 +16,8 @@
16
16
  * @module validate-config
17
17
  */
18
18
 
19
- import { existsSync, readFileSync } from "node:fs";
19
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
20
+ import { fileURLToPath } from "node:url";
20
21
  import { join } from "node:path";
21
22
 
22
23
  import { SURFACES as SURFACE_CAPABILITIES } from "./surfaces.mjs";
@@ -517,7 +518,29 @@ function main() {
517
518
  throw new Error(`${problems.length} configuration problem(s)`);
518
519
  }
519
520
 
520
- if (import.meta.url === `file://${process.argv[1]}`) {
521
+ /**
522
+ * Whether this module is the one node was asked to run.
523
+ *
524
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
525
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
526
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
527
+ *
528
+ * A local copy rather than an import: plugin payload scripts ship standalone,
529
+ * with no `lib/` sibling to import from once installed.
530
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
531
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
532
+ * @returns {boolean} Whether the caller should run its CLI body.
533
+ */
534
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
535
+ if (!argv1) return false;
536
+ try {
537
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
538
+ } catch {
539
+ return false;
540
+ }
541
+ }
542
+
543
+ if (invokedAsScript(import.meta.url)) {
521
544
  try {
522
545
  main();
523
546
  } catch (err) {
@@ -17,7 +17,14 @@
17
17
  * @module generate-workflow
18
18
  */
19
19
 
20
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
20
+ import {
21
+ existsSync,
22
+ mkdirSync,
23
+ readFileSync,
24
+ writeFileSync,
25
+ realpathSync,
26
+ } from "node:fs";
27
+ import { fileURLToPath } from "node:url";
21
28
  import { dirname, join } from "node:path";
22
29
 
23
30
  /** Where a generated loop workflow lands. */
@@ -249,7 +256,29 @@ function main() {
249
256
  }
250
257
  }
251
258
 
252
- if (import.meta.url === `file://${process.argv[1]}`) {
259
+ /**
260
+ * Whether this module is the one node was asked to run.
261
+ *
262
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
263
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
264
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
265
+ *
266
+ * A local copy rather than an import: plugin payload scripts ship standalone,
267
+ * with no `lib/` sibling to import from once installed.
268
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
269
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
270
+ * @returns {boolean} Whether the caller should run its CLI body.
271
+ */
272
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
273
+ if (!argv1) return false;
274
+ try {
275
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
276
+ } catch {
277
+ return false;
278
+ }
279
+ }
280
+
281
+ if (invokedAsScript(import.meta.url)) {
253
282
  try {
254
283
  main();
255
284
  } catch (err) {
@@ -23,7 +23,7 @@
23
23
  * @module local-env
24
24
  */
25
25
 
26
- import { existsSync } from "node:fs";
26
+ import { existsSync, realpathSync } from "node:fs";
27
27
  import { dirname, resolve } from "node:path";
28
28
  import { fileURLToPath, pathToFileURL } from "node:url";
29
29
 
@@ -159,7 +159,29 @@ export async function run(argv) {
159
159
  return 0;
160
160
  }
161
161
 
162
- if (import.meta.url === `file://${process.argv[1]}`) {
162
+ /**
163
+ * Whether this module is the one node was asked to run.
164
+ *
165
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
166
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
167
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
168
+ *
169
+ * A local copy rather than an import: plugin payload scripts ship standalone,
170
+ * with no `lib/` sibling to import from once installed.
171
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
172
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
173
+ * @returns {boolean} Whether the caller should run its CLI body.
174
+ */
175
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
176
+ if (!argv1) return false;
177
+ try {
178
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
179
+ } catch {
180
+ return false;
181
+ }
182
+ }
183
+
184
+ if (invokedAsScript(import.meta.url)) {
163
185
  const argv = {
164
186
  installTools: process.argv.includes("--install-tools"),
165
187
  dryRun: process.argv.includes("--dry-run"),
@@ -1519,7 +1519,29 @@ async function main() {
1519
1519
  console.log(`\nRemote environment ${dryRun ? "plan complete" : "ready"}.`);
1520
1520
  }
1521
1521
 
1522
- if (import.meta.url === `file://${process.argv[1]}`) {
1522
+ /**
1523
+ * Whether this module is the one node was asked to run.
1524
+ *
1525
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
1526
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
1527
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
1528
+ *
1529
+ * A local copy rather than an import: plugin payload scripts ship standalone,
1530
+ * with no `lib/` sibling to import from once installed.
1531
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
1532
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
1533
+ * @returns {boolean} Whether the caller should run its CLI body.
1534
+ */
1535
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
1536
+ if (!argv1) return false;
1537
+ try {
1538
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
1539
+ } catch {
1540
+ return false;
1541
+ }
1542
+ }
1543
+
1544
+ if (invokedAsScript(import.meta.url)) {
1523
1545
  // Awaited rather than called bare: main is async, so a synchronous try/catch
1524
1546
  // would let a rejected promise escape as an unhandled rejection and exit 0 —
1525
1547
  // reporting a prepared environment that was never prepared.
@@ -22,7 +22,8 @@
22
22
  */
23
23
 
24
24
  import { execFileSync } from "node:child_process";
25
- import { existsSync, readFileSync, statSync } from "node:fs";
25
+ import { fileURLToPath } from "node:url";
26
+ import { existsSync, readFileSync, statSync, realpathSync } from "node:fs";
26
27
  import { join } from "node:path";
27
28
 
28
29
  import { probe, readRemoteEnvConfig } from "./setup-remote-env.mjs";
@@ -213,7 +214,29 @@ function main() {
213
214
  console.log("\nRemote environment verified without revealing any value.");
214
215
  }
215
216
 
216
- if (import.meta.url === `file://${process.argv[1]}`) {
217
+ /**
218
+ * Whether this module is the one node was asked to run.
219
+ *
220
+ * Both sides are realpath'd: a raw URL comparison answers "no" through a
221
+ * symlinked checkout, a git worktree, or a /tmp path on macOS, so the module
222
+ * loads, runs nothing and exits 0 — a silent no-op that reads as success.
223
+ *
224
+ * A local copy rather than an import: plugin payload scripts ship standalone,
225
+ * with no `lib/` sibling to import from once installed.
226
+ * @param {string} moduleUrl - The caller's own `import.meta.url`.
227
+ * @param {string | undefined} [argv1] - Entry path; defaults to `process.argv[1]`.
228
+ * @returns {boolean} Whether the caller should run its CLI body.
229
+ */
230
+ function invokedAsScript(moduleUrl, argv1 = process.argv[1]) {
231
+ if (!argv1) return false;
232
+ try {
233
+ return realpathSync(argv1) === realpathSync(fileURLToPath(moduleUrl));
234
+ } catch {
235
+ return false;
236
+ }
237
+ }
238
+
239
+ if (invokedAsScript(import.meta.url)) {
217
240
  try {
218
241
  main();
219
242
  } catch (err) {