gaslighting-engine 0.3.1 → 0.4.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 (194) hide show
  1. package/README.md +133 -18
  2. package/desktop-dist/assets/index-BoI6eWtN.js +44 -0
  3. package/desktop-dist/assets/index-oFTvTTu8.css +1 -0
  4. package/desktop-dist/index.html +13 -0
  5. package/dist/agent-runtimes/permissions.js +34 -0
  6. package/dist/agent-runtimes/prompts.js +30 -0
  7. package/dist/agent-runtimes/registry.js +214 -0
  8. package/dist/agent-runtimes/types.js +1 -0
  9. package/dist/cli.js +142 -4
  10. package/dist/commands/agent.js +11 -0
  11. package/dist/commands/apiRun.js +32 -0
  12. package/dist/commands/cockpit.js +37 -6
  13. package/dist/commands/desktop.js +37 -0
  14. package/dist/commands/doctor.js +8 -1
  15. package/dist/commands/loop.js +64 -0
  16. package/dist/commands/mcp.js +43 -0
  17. package/dist/commands/skill.js +23 -0
  18. package/dist/core/codexRuntime.js +2 -19
  19. package/dist/core/generateDocs.js +16 -10
  20. package/dist/core/generateOtherMarkdown.js +27 -27
  21. package/dist/core/generateStructuredDocs.js +405 -0
  22. package/dist/core/mcpRegistry.js +103 -0
  23. package/dist/core/missionLoop.js +179 -0
  24. package/dist/core/skillRegistry.js +62 -0
  25. package/dist/desktop/main.js +186 -0
  26. package/dist/desktop/preload.js +22 -0
  27. package/dist/utils/logger.js +1 -1
  28. package/dist/version.js +1 -1
  29. package/docs/codex-usage.md +28 -3
  30. package/examples/ecommerce/.agents/config.json +10 -0
  31. package/examples/ecommerce/.agents/mcp/manifest.json +5 -0
  32. package/examples/ecommerce/.agents/runtimes/claude.json +6 -0
  33. package/examples/ecommerce/.agents/runtimes/codex.json +6 -0
  34. package/examples/ecommerce/.agents/runtimes/kimi.json +6 -0
  35. package/examples/ecommerce/.agents/runtimes/local.json +6 -0
  36. package/examples/ecommerce/.agents/runtimes/openai_compatible.json +6 -0
  37. package/examples/ecommerce/.agents/runtimes/opencode.json +6 -0
  38. package/examples/ecommerce/.agents/runtimes/qwen.json +6 -0
  39. package/examples/ecommerce/.codex/prompts/gaslighting.md +9 -9
  40. package/examples/ecommerce/.gaslighting/AGENTS.md +9 -9
  41. package/examples/ecommerce/.gaslighting/AGENT_RUNTIME.md +1 -1
  42. package/examples/ecommerce/.gaslighting/CODEX_PROMPT.md +9 -9
  43. package/examples/ecommerce/.gaslighting/DECISION_LOG.md +1 -1
  44. package/examples/ecommerce/.gaslighting/GASLIGHTING.md +2 -2
  45. package/examples/ecommerce/.gaslighting/INDEX.md +39 -0
  46. package/examples/ecommerce/.gaslighting/MEMORY.md +1 -1
  47. package/examples/ecommerce/.gaslighting/PRD.md +1 -1
  48. package/examples/ecommerce/.gaslighting/PROJECT_CARE.md +1 -1
  49. package/examples/ecommerce/.gaslighting/checkpoints/latest.md +7 -0
  50. package/examples/ecommerce/.gaslighting/config.json +7 -0
  51. package/examples/ecommerce/.gaslighting/decisions/ADR-0001-stack.md +11 -0
  52. package/examples/ecommerce/.gaslighting/decisions/ADR-0002-agent-runtime.md +11 -0
  53. package/examples/ecommerce/.gaslighting/features/core-scope/DECISIONS.md +5 -0
  54. package/examples/ecommerce/.gaslighting/features/core-scope/FEATURE.md +7 -0
  55. package/examples/ecommerce/.gaslighting/features/core-scope/RISKS.md +5 -0
  56. package/examples/ecommerce/.gaslighting/features/core-scope/TASKS.md +18 -0
  57. package/examples/ecommerce/.gaslighting/loops/current-session.json +9 -0
  58. package/examples/ecommerce/.gaslighting/memory/OPEN_QUESTIONS.md +5 -0
  59. package/examples/ecommerce/.gaslighting/memory/PROJECT_MEMORY.md +5 -0
  60. package/examples/ecommerce/.gaslighting/memory/SESSION_LOG.md +3 -0
  61. package/examples/ecommerce/.gaslighting/mission/COMPLETION_STANDARD.md +11 -0
  62. package/examples/ecommerce/.gaslighting/mission/EXECUTION_RULES.md +20 -0
  63. package/examples/ecommerce/.gaslighting/mission/PROJECT_PURPOSE.md +20 -0
  64. package/examples/ecommerce/.gaslighting/operations/DEPLOYMENT.md +6 -0
  65. package/examples/ecommerce/.gaslighting/operations/DOMAIN.md +6 -0
  66. package/examples/ecommerce/.gaslighting/operations/ENV.md +5 -0
  67. package/examples/ecommerce/.gaslighting/operations/GIT.md +7 -0
  68. package/examples/ecommerce/.gaslighting/operations/GITHUB.md +7 -0
  69. package/examples/ecommerce/.gaslighting/operations/PROJECT_CARE.md +76 -0
  70. package/examples/ecommerce/.gaslighting/pages/admin-products/ACCEPTANCE.md +7 -0
  71. package/examples/ecommerce/.gaslighting/pages/admin-products/PAGE_PRD.md +15 -0
  72. package/examples/ecommerce/.gaslighting/pages/cart/ACCEPTANCE.md +7 -0
  73. package/examples/ecommerce/.gaslighting/pages/cart/PAGE_PRD.md +15 -0
  74. package/examples/ecommerce/.gaslighting/pages/checkout/ACCEPTANCE.md +7 -0
  75. package/examples/ecommerce/.gaslighting/pages/checkout/PAGE_PRD.md +15 -0
  76. package/examples/ecommerce/.gaslighting/pages/home/ACCEPTANCE.md +7 -0
  77. package/examples/ecommerce/.gaslighting/pages/home/PAGE_PRD.md +15 -0
  78. package/examples/ecommerce/.gaslighting/pages/my-orders/ACCEPTANCE.md +7 -0
  79. package/examples/ecommerce/.gaslighting/pages/my-orders/PAGE_PRD.md +15 -0
  80. package/examples/ecommerce/.gaslighting/pages/order-complete/ACCEPTANCE.md +7 -0
  81. package/examples/ecommerce/.gaslighting/pages/order-complete/PAGE_PRD.md +15 -0
  82. package/examples/ecommerce/.gaslighting/pages/product-detail/ACCEPTANCE.md +7 -0
  83. package/examples/ecommerce/.gaslighting/pages/product-detail/PAGE_PRD.md +15 -0
  84. package/examples/ecommerce/.gaslighting/pages/product-list/ACCEPTANCE.md +7 -0
  85. package/examples/ecommerce/.gaslighting/pages/product-list/PAGE_PRD.md +15 -0
  86. package/examples/ecommerce/.gaslighting/product/PAGE_MAP.md +11 -0
  87. package/examples/ecommerce/.gaslighting/product/PRD.md +115 -0
  88. package/examples/ecommerce/.gaslighting/product/USER_FLOWS.md +22 -0
  89. package/examples/ecommerce/.gaslighting/tasks/TASK-0001.md +17 -0
  90. package/examples/ecommerce/.gaslighting/verification/latest-report.md +3 -0
  91. package/examples/ecommerce/AGENTS.md +12 -10
  92. package/examples/hospital-homepage/.agents/config.json +10 -0
  93. package/examples/hospital-homepage/.agents/mcp/manifest.json +5 -0
  94. package/examples/hospital-homepage/.agents/runtimes/claude.json +6 -0
  95. package/examples/hospital-homepage/.agents/runtimes/codex.json +6 -0
  96. package/examples/hospital-homepage/.agents/runtimes/kimi.json +6 -0
  97. package/examples/hospital-homepage/.agents/runtimes/local.json +6 -0
  98. package/examples/hospital-homepage/.agents/runtimes/openai_compatible.json +6 -0
  99. package/examples/hospital-homepage/.agents/runtimes/opencode.json +6 -0
  100. package/examples/hospital-homepage/.agents/runtimes/qwen.json +6 -0
  101. package/examples/hospital-homepage/.codex/prompts/gaslighting.md +9 -9
  102. package/examples/hospital-homepage/.gaslighting/AGENTS.md +9 -9
  103. package/examples/hospital-homepage/.gaslighting/CODEX_PROMPT.md +9 -9
  104. package/examples/hospital-homepage/.gaslighting/INDEX.md +37 -0
  105. package/examples/hospital-homepage/.gaslighting/checkpoints/latest.md +7 -0
  106. package/examples/hospital-homepage/.gaslighting/config.json +7 -0
  107. package/examples/hospital-homepage/.gaslighting/decisions/ADR-0001-stack.md +11 -0
  108. package/examples/hospital-homepage/.gaslighting/decisions/ADR-0002-agent-runtime.md +11 -0
  109. package/examples/hospital-homepage/.gaslighting/features/core-scope/DECISIONS.md +5 -0
  110. package/examples/hospital-homepage/.gaslighting/features/core-scope/FEATURE.md +7 -0
  111. package/examples/hospital-homepage/.gaslighting/features/core-scope/RISKS.md +5 -0
  112. package/examples/hospital-homepage/.gaslighting/features/core-scope/TASKS.md +17 -0
  113. package/examples/hospital-homepage/.gaslighting/loops/current-session.json +9 -0
  114. package/examples/hospital-homepage/.gaslighting/memory/OPEN_QUESTIONS.md +5 -0
  115. package/examples/hospital-homepage/.gaslighting/memory/PROJECT_MEMORY.md +5 -0
  116. package/examples/hospital-homepage/.gaslighting/memory/SESSION_LOG.md +3 -0
  117. package/examples/hospital-homepage/.gaslighting/mission/COMPLETION_STANDARD.md +11 -0
  118. package/examples/hospital-homepage/.gaslighting/mission/EXECUTION_RULES.md +20 -0
  119. package/examples/hospital-homepage/.gaslighting/mission/PROJECT_PURPOSE.md +20 -0
  120. package/examples/hospital-homepage/.gaslighting/operations/DEPLOYMENT.md +6 -0
  121. package/examples/hospital-homepage/.gaslighting/operations/DOMAIN.md +6 -0
  122. package/examples/hospital-homepage/.gaslighting/operations/ENV.md +5 -0
  123. package/examples/hospital-homepage/.gaslighting/operations/GIT.md +7 -0
  124. package/examples/hospital-homepage/.gaslighting/operations/GITHUB.md +7 -0
  125. package/examples/hospital-homepage/.gaslighting/operations/PROJECT_CARE.md +76 -0
  126. package/examples/hospital-homepage/.gaslighting/pages/consultation-contact/ACCEPTANCE.md +7 -0
  127. package/examples/hospital-homepage/.gaslighting/pages/consultation-contact/PAGE_PRD.md +15 -0
  128. package/examples/hospital-homepage/.gaslighting/pages/departments-treatments/ACCEPTANCE.md +7 -0
  129. package/examples/hospital-homepage/.gaslighting/pages/departments-treatments/PAGE_PRD.md +15 -0
  130. package/examples/hospital-homepage/.gaslighting/pages/doctor-profiles/ACCEPTANCE.md +7 -0
  131. package/examples/hospital-homepage/.gaslighting/pages/doctor-profiles/PAGE_PRD.md +15 -0
  132. package/examples/hospital-homepage/.gaslighting/pages/home/ACCEPTANCE.md +7 -0
  133. package/examples/hospital-homepage/.gaslighting/pages/home/PAGE_PRD.md +15 -0
  134. package/examples/hospital-homepage/.gaslighting/pages/hospital-introduction/ACCEPTANCE.md +7 -0
  135. package/examples/hospital-homepage/.gaslighting/pages/hospital-introduction/PAGE_PRD.md +15 -0
  136. package/examples/hospital-homepage/.gaslighting/pages/location/ACCEPTANCE.md +7 -0
  137. package/examples/hospital-homepage/.gaslighting/pages/location/PAGE_PRD.md +15 -0
  138. package/examples/hospital-homepage/.gaslighting/pages/privacy-policy/ACCEPTANCE.md +7 -0
  139. package/examples/hospital-homepage/.gaslighting/pages/privacy-policy/PAGE_PRD.md +15 -0
  140. package/examples/hospital-homepage/.gaslighting/product/PAGE_MAP.md +9 -0
  141. package/examples/hospital-homepage/.gaslighting/product/PRD.md +119 -0
  142. package/examples/hospital-homepage/.gaslighting/product/USER_FLOWS.md +20 -0
  143. package/examples/hospital-homepage/.gaslighting/tasks/TASK-0001.md +17 -0
  144. package/examples/hospital-homepage/.gaslighting/verification/latest-report.md +3 -0
  145. package/examples/hospital-homepage/AGENTS.md +12 -10
  146. package/examples/landing-page/.agents/config.json +10 -0
  147. package/examples/landing-page/.agents/mcp/manifest.json +5 -0
  148. package/examples/landing-page/.agents/runtimes/claude.json +6 -0
  149. package/examples/landing-page/.agents/runtimes/codex.json +6 -0
  150. package/examples/landing-page/.agents/runtimes/kimi.json +6 -0
  151. package/examples/landing-page/.agents/runtimes/local.json +6 -0
  152. package/examples/landing-page/.agents/runtimes/openai_compatible.json +6 -0
  153. package/examples/landing-page/.agents/runtimes/opencode.json +6 -0
  154. package/examples/landing-page/.agents/runtimes/qwen.json +6 -0
  155. package/examples/landing-page/.codex/prompts/gaslighting.md +9 -9
  156. package/examples/landing-page/.gaslighting/AGENTS.md +9 -9
  157. package/examples/landing-page/.gaslighting/AGENT_RUNTIME.md +1 -1
  158. package/examples/landing-page/.gaslighting/CODEX_PROMPT.md +9 -9
  159. package/examples/landing-page/.gaslighting/DECISION_LOG.md +1 -1
  160. package/examples/landing-page/.gaslighting/GASLIGHTING.md +2 -2
  161. package/examples/landing-page/.gaslighting/INDEX.md +31 -0
  162. package/examples/landing-page/.gaslighting/MEMORY.md +1 -1
  163. package/examples/landing-page/.gaslighting/PRD.md +1 -1
  164. package/examples/landing-page/.gaslighting/PROJECT_CARE.md +1 -1
  165. package/examples/landing-page/.gaslighting/checkpoints/latest.md +7 -0
  166. package/examples/landing-page/.gaslighting/config.json +7 -0
  167. package/examples/landing-page/.gaslighting/decisions/ADR-0001-stack.md +11 -0
  168. package/examples/landing-page/.gaslighting/decisions/ADR-0002-agent-runtime.md +11 -0
  169. package/examples/landing-page/.gaslighting/features/core-scope/DECISIONS.md +5 -0
  170. package/examples/landing-page/.gaslighting/features/core-scope/FEATURE.md +7 -0
  171. package/examples/landing-page/.gaslighting/features/core-scope/RISKS.md +5 -0
  172. package/examples/landing-page/.gaslighting/features/core-scope/TASKS.md +11 -0
  173. package/examples/landing-page/.gaslighting/loops/current-session.json +9 -0
  174. package/examples/landing-page/.gaslighting/memory/OPEN_QUESTIONS.md +5 -0
  175. package/examples/landing-page/.gaslighting/memory/PROJECT_MEMORY.md +5 -0
  176. package/examples/landing-page/.gaslighting/memory/SESSION_LOG.md +3 -0
  177. package/examples/landing-page/.gaslighting/mission/COMPLETION_STANDARD.md +11 -0
  178. package/examples/landing-page/.gaslighting/mission/EXECUTION_RULES.md +20 -0
  179. package/examples/landing-page/.gaslighting/mission/PROJECT_PURPOSE.md +19 -0
  180. package/examples/landing-page/.gaslighting/operations/DEPLOYMENT.md +6 -0
  181. package/examples/landing-page/.gaslighting/operations/DOMAIN.md +6 -0
  182. package/examples/landing-page/.gaslighting/operations/ENV.md +5 -0
  183. package/examples/landing-page/.gaslighting/operations/GIT.md +7 -0
  184. package/examples/landing-page/.gaslighting/operations/GITHUB.md +7 -0
  185. package/examples/landing-page/.gaslighting/operations/PROJECT_CARE.md +75 -0
  186. package/examples/landing-page/.gaslighting/pages/single-landing-page-with-hero-problem-solution-benefits-social-p/ACCEPTANCE.md +7 -0
  187. package/examples/landing-page/.gaslighting/pages/single-landing-page-with-hero-problem-solution-benefits-social-p/PAGE_PRD.md +15 -0
  188. package/examples/landing-page/.gaslighting/product/PAGE_MAP.md +3 -0
  189. package/examples/landing-page/.gaslighting/product/PRD.md +103 -0
  190. package/examples/landing-page/.gaslighting/product/USER_FLOWS.md +14 -0
  191. package/examples/landing-page/.gaslighting/tasks/TASK-0001.md +17 -0
  192. package/examples/landing-page/.gaslighting/verification/latest-report.md +3 -0
  193. package/examples/landing-page/AGENTS.md +12 -10
  194. package/package.json +22 -5
@@ -3,6 +3,7 @@ import { existsSync, readFileSync } from "node:fs";
3
3
  import { createServer } from "node:http";
4
4
  import { join, resolve } from "node:path";
5
5
  import { platform } from "node:os";
6
+ import { detectAgentRuntimes, getAgentRuntimeAdapter } from "../agent-runtimes/registry.js";
6
7
  import { analyze } from "../core/analyze.js";
7
8
  import { buildCodexCommand, getDefaultCodexArgs, launchCodexInCurrentTerminal, launchCodexInNewTerminal } from "../core/codexRuntime.js";
8
9
  import { pageList, projectPurpose } from "../core/content.js";
@@ -22,6 +23,12 @@ const docFiles = [
22
23
  ".gaslighting/MEMORY.md",
23
24
  ".gaslighting/AGENT_RUNTIME.md",
24
25
  ".gaslighting/PROJECT_CARE.md",
26
+ ".gaslighting/INDEX.md",
27
+ ".gaslighting/mission/PROJECT_PURPOSE.md",
28
+ ".gaslighting/product/PAGE_MAP.md",
29
+ ".gaslighting/features/core-scope/TASKS.md",
30
+ ".gaslighting/loops/current-session.json",
31
+ ".agents/config.json",
25
32
  ];
26
33
  export async function runCockpit(rawUserRequest = "", options) {
27
34
  await openCockpit(rawUserRequest, { ...options, generate: Boolean(rawUserRequest) && options.generate !== false, force: options.force ?? true });
@@ -34,12 +41,16 @@ export function runCodexRun(rawUserRequest, options) {
34
41
  const input = makeInput(rawUserRequest, options);
35
42
  writeDocs(root, generateDocs(input, root).docs, options.force ?? true, false);
36
43
  writeDocs(root, generateCodexInstallDocs(), true, false);
37
- printBanner("CODEX RUN");
38
- console.log(options.newTerminal ? "Starting Codex in a new terminal." : "Handing this terminal over to Codex.");
39
- console.log(buildCodexCommand({ root, request: rawUserRequest, codexArgs: options.codexArgs }));
40
- const result = options.newTerminal
44
+ const runtime = options.runtime ?? "codex";
45
+ const adapter = getAgentRuntimeAdapter(runtime);
46
+ printBanner(`${adapter.label.toUpperCase()} RUN`);
47
+ console.log(options.newTerminal ? `Starting ${adapter.label} in a new terminal.` : `Handing this terminal over to ${adapter.label}.`);
48
+ console.log(adapter.buildCommand({ root, request: rawUserRequest, runtime, permissionMode: options.permissionMode ?? "auto_review", loopMode: options.loop ?? "off", extraArgs: options.codexArgs }));
49
+ const result = runtime === "codex" && options.newTerminal
41
50
  ? launchCodexInNewTerminal({ root, request: rawUserRequest, codexArgs: options.codexArgs })
42
- : launchCodexInCurrentTerminal({ root, request: rawUserRequest, codexArgs: options.codexArgs });
51
+ : runtime === "codex"
52
+ ? launchCodexInCurrentTerminal({ root, request: rawUserRequest, codexArgs: options.codexArgs })
53
+ : adapter.run({ root, request: rawUserRequest, runtime, permissionMode: options.permissionMode ?? "auto_review", loopMode: options.loop ?? "off", extraArgs: options.codexArgs });
43
54
  if (!result.ok)
44
55
  console.log(result.message);
45
56
  }
@@ -70,10 +81,23 @@ async function openCockpit(rawUserRequest, options) {
70
81
  currentRequest = String(body.request || currentRequest);
71
82
  currentInput = makeInput(currentRequest, options);
72
83
  writeDocs(root, generateDocs(currentInput, root).docs, true, false);
73
- if (options.newTerminal) {
84
+ const runtime = options.runtime ?? "codex";
85
+ if (runtime === "codex" && options.newTerminal) {
74
86
  const result = launchCodexInNewTerminal({ root, request: currentRequest, codexArgs: options.codexArgs });
75
87
  return sendJson(response, { ...result });
76
88
  }
89
+ if (runtime !== "codex") {
90
+ const adapter = getAgentRuntimeAdapter(runtime);
91
+ const result = adapter.run({
92
+ root,
93
+ request: currentRequest,
94
+ runtime,
95
+ permissionMode: options.permissionMode ?? "auto_review",
96
+ loopMode: options.loop ?? "off",
97
+ extraArgs: options.codexArgs,
98
+ });
99
+ return sendJson(response, { ...result });
100
+ }
77
101
  const commandPreview = launchMessageForCurrentTerminal(root, currentRequest, options);
78
102
  sendJson(response, commandPreview);
79
103
  setTimeout(() => {
@@ -123,8 +147,12 @@ function buildState(root, request, input, options) {
123
147
  care: inspectProjectCare(root),
124
148
  docsPresent,
125
149
  codexArgs: options.codexArgs || getDefaultCodexArgs(),
150
+ runtime: options.runtime ?? "codex",
151
+ permissionMode: options.permissionMode ?? "auto_review",
152
+ loopMode: options.loop ?? "off",
126
153
  launchMode: options.newTerminal ? "new_terminal" : "current_terminal",
127
154
  codexAvailable: isCommandAvailable("codex"),
155
+ runtimes: detectAgentRuntimes(),
128
156
  };
129
157
  }
130
158
  function launchMessageForCurrentTerminal(root, request, options) {
@@ -144,6 +172,9 @@ function makeInput(rawUserRequest, options) {
144
172
  noTodo: true,
145
173
  noShortcut: true,
146
174
  force: options.force ?? true,
175
+ runtime: options.runtime ?? "codex",
176
+ permissionMode: options.permissionMode ?? "auto_review",
177
+ loopMode: options.loop ?? "off",
147
178
  };
148
179
  }
149
180
  function readExistingRequest(root) {
@@ -0,0 +1,37 @@
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { spawn } from "node:child_process";
5
+ import { platform } from "node:os";
6
+ import { printBanner } from "../utils/banner.js";
7
+ export async function runDesktop(request = "", options) {
8
+ const root = resolve(options.path ?? process.cwd());
9
+ const mainPath = join(dirname(fileURLToPath(import.meta.url)), "..", "desktop", "main.js");
10
+ printBanner("DESKTOP");
11
+ if (!existsSync(mainPath)) {
12
+ console.log("Desktop main file is missing. Run `npm run build` first.");
13
+ console.log(`Expected: ${mainPath}`);
14
+ return;
15
+ }
16
+ const electronCommand = await resolveElectronCommand(mainPath);
17
+ const child = spawn(electronCommand.file, electronCommand.args, {
18
+ stdio: "inherit",
19
+ env: {
20
+ ...process.env,
21
+ GASLIGHTING_DESKTOP_ROOT: root,
22
+ GASLIGHTING_DESKTOP_REQUEST: request,
23
+ GASLIGHTING_DESKTOP_DEV: options.dev ? "1" : "",
24
+ },
25
+ });
26
+ child.on("exit", (code) => process.exit(code ?? 0));
27
+ }
28
+ async function resolveElectronCommand(mainPath) {
29
+ try {
30
+ const { default: electronPath } = await import("electron");
31
+ return { file: String(electronPath), args: [mainPath] };
32
+ }
33
+ catch {
34
+ const npmFile = platform() === "win32" ? "npm.cmd" : "npm";
35
+ return { file: npmFile, args: ["exec", "--yes", "--package", "electron", "--", "electron", mainPath] };
36
+ }
37
+ }
@@ -20,10 +20,17 @@ export function runDoctor(options) {
20
20
  fileCheck(root, ".gaslighting/MEMORY.md"),
21
21
  fileCheck(root, ".gaslighting/AGENT_RUNTIME.md"),
22
22
  fileCheck(root, ".gaslighting/PROJECT_CARE.md"),
23
+ fileCheck(root, ".gaslighting/INDEX.md"),
24
+ fileCheck(root, ".gaslighting/mission/PROJECT_PURPOSE.md"),
25
+ fileCheck(root, ".gaslighting/mission/EXECUTION_RULES.md"),
26
+ fileCheck(root, ".gaslighting/product/PAGE_MAP.md"),
27
+ fileCheck(root, ".gaslighting/features/core-scope/TASKS.md"),
28
+ fileCheck(root, ".gaslighting/loops/current-session.json"),
29
+ fileCheck(root, ".agents/config.json"),
23
30
  { name: ".gaslighting/GASLIGHTING.md contains project purpose", ok: /Project Purpose/i.test(gaslighting) },
24
31
  { name: ".gaslighting/GASLIGHTING.md contains no-fake-completion rules", ok: /No Fake Completion|Fake completion/i.test(gaslighting) },
25
32
  { name: ".gaslighting/GASLIGHTING.md contains full-scope rules", ok: /Full Scope Enforcement|full requested scope/i.test(gaslighting) },
26
- { name: "AGENTS.md points to .gaslighting/GASLIGHTING.md", ok: /\.gaslighting\/GASLIGHTING\.md|\.gaslighting\\GASLIGHTING\.md/.test(agents) },
33
+ { name: "AGENTS.md points to .gaslighting/INDEX.md", ok: /\.gaslighting\/INDEX\.md|\.gaslighting\\INDEX\.md/.test(agents) },
27
34
  fileCheck(root, ".codex/skills/gaslighting/SKILL.md"),
28
35
  fileCheck(root, ".codex/skills/gaslighting/agents/openai.yaml"),
29
36
  fileCheck(root, ".codex/prompts/gaslighting.md"),
@@ -0,0 +1,64 @@
1
+ import { resolve } from "node:path";
2
+ import { getMissionLoopStatus, resumeMissionLoop, startMissionLoop, stopMissionLoop } from "../core/missionLoop.js";
3
+ import { printBanner } from "../utils/banner.js";
4
+ export function runLoopStart(request = "Continue the current Gaslighting mission.", options) {
5
+ options = normalizeOptions(options);
6
+ const root = resolve(options.path ?? process.cwd());
7
+ const session = startMissionLoop({
8
+ root,
9
+ request,
10
+ runtime: options.runtime,
11
+ permissionMode: options.permissionMode,
12
+ });
13
+ printBanner("MISSION LOOP");
14
+ console.log(`Started: ${session.request}`);
15
+ console.log(`Runtime: ${session.runtime}`);
16
+ console.log(`Permission: ${session.permissionMode}`);
17
+ console.log(`Status: ${session.status}`);
18
+ console.log("Run `gaslighting loop resume` to execute the next iteration.");
19
+ }
20
+ export function runLoopResume(options) {
21
+ options = normalizeOptions(options);
22
+ const root = resolve(options.path ?? process.cwd());
23
+ const session = resumeMissionLoop({
24
+ root,
25
+ runtime: options.runtime,
26
+ permissionMode: options.permissionMode,
27
+ maxIterations: Number.parseInt(options.maxIterations ?? "1", 10),
28
+ approve: options.approve,
29
+ extraArgs: options.extraArgs,
30
+ });
31
+ printBanner("MISSION LOOP RESUME");
32
+ console.log(`Status: ${session.status}`);
33
+ console.log(`Task: ${session.currentTask}`);
34
+ console.log(`Iterations: ${session.iterations}`);
35
+ console.log(`Message: ${session.lastMessage ?? "-"}`);
36
+ }
37
+ export function runLoopStatus(options) {
38
+ options = normalizeOptions(options);
39
+ const root = resolve(options.path ?? process.cwd());
40
+ const session = getMissionLoopStatus(root);
41
+ printBanner("MISSION LOOP STATUS");
42
+ if (!session) {
43
+ console.log("No mission loop session exists.");
44
+ return;
45
+ }
46
+ console.log(`Status: ${session.status}`);
47
+ console.log(`Active: ${session.active}`);
48
+ console.log(`Runtime: ${session.runtime}`);
49
+ console.log(`Permission: ${session.permissionMode}`);
50
+ console.log(`Task: ${session.currentTask}`);
51
+ console.log(`Iterations: ${session.iterations}`);
52
+ console.log(`Message: ${session.lastMessage ?? "-"}`);
53
+ }
54
+ export function runLoopStop(options) {
55
+ options = normalizeOptions(options);
56
+ const root = resolve(options.path ?? process.cwd());
57
+ const session = stopMissionLoop(root);
58
+ printBanner("MISSION LOOP STOP");
59
+ console.log(`Status: ${session.status}`);
60
+ console.log(`Message: ${session.lastMessage ?? "-"}`);
61
+ }
62
+ function normalizeOptions(options) {
63
+ return typeof options.opts === "function" ? options.opts() : options;
64
+ }
@@ -0,0 +1,43 @@
1
+ import { resolve } from "node:path";
2
+ import { doctorMcp, installMcpServer, listInstalledMcpServers, searchMcpServers } from "../core/mcpRegistry.js";
3
+ import { printBanner } from "../utils/banner.js";
4
+ export function runMcpSearch(query) {
5
+ printBanner("MCP SEARCH");
6
+ const results = searchMcpServers(query);
7
+ if (results.length === 0) {
8
+ console.log("No MCP servers matched.");
9
+ return;
10
+ }
11
+ for (const server of results) {
12
+ console.log(`${server.id}: ${server.label} - ${server.description}`);
13
+ }
14
+ }
15
+ export function runMcpInstall(name, options) {
16
+ options = normalizeOptions(options);
17
+ const root = resolve(options.path ?? process.cwd());
18
+ printBanner("MCP INSTALL");
19
+ const result = installMcpServer(root, name, options.runtime ?? "codex");
20
+ console.log(`${result.ok ? "PASS" : "FAIL"} ${result.message}`);
21
+ }
22
+ export function runMcpList(options) {
23
+ options = normalizeOptions(options);
24
+ const root = resolve(options.path ?? process.cwd());
25
+ printBanner("MCP LIST");
26
+ const installed = listInstalledMcpServers(root);
27
+ if (installed.length === 0) {
28
+ console.log("No MCP servers installed.");
29
+ return;
30
+ }
31
+ for (const server of installed)
32
+ console.log(`${server.id}: ${server.label}`);
33
+ }
34
+ export function runMcpDoctor(options) {
35
+ options = normalizeOptions(options);
36
+ const root = resolve(options.path ?? process.cwd());
37
+ printBanner("MCP DOCTOR");
38
+ for (const check of doctorMcp(root))
39
+ console.log(`${check.ok ? "PASS" : "WARN"} ${check.message}`);
40
+ }
41
+ function normalizeOptions(options) {
42
+ return typeof options.opts === "function" ? options.opts() : options;
43
+ }
@@ -1,10 +1,33 @@
1
1
  import { generateOnlySkillDocs } from "../core/generateDocs.js";
2
+ import { createSharedSkill, doctorSkills, installSharedSkill } from "../core/skillRegistry.js";
2
3
  import { printBanner } from "../utils/banner.js";
3
4
  import { writeDocs } from "../utils/file.js";
4
5
  export function runSkill(options) {
6
+ options = normalizeOptions(options);
5
7
  const results = writeDocs(options.path ?? process.cwd(), generateOnlySkillDocs(), options.force, options.dryRun);
6
8
  printBanner("CODEX SKILL INSTALL");
7
9
  console.log("Created:");
8
10
  for (const result of results)
9
11
  console.log(`- ${result.filename}${result.status === "dry_run" ? " (dry run)" : ""}`);
10
12
  }
13
+ export function runSkillCreate(name, options) {
14
+ options = normalizeOptions(options);
15
+ const path = createSharedSkill(options.path ?? process.cwd(), name, options.description);
16
+ printBanner("SKILL CREATE");
17
+ console.log(`Created shared skill: ${path}`);
18
+ }
19
+ export function runSkillInstall(name, options) {
20
+ options = normalizeOptions(options);
21
+ const path = installSharedSkill(options.path ?? process.cwd(), name, options.runtime ?? "codex");
22
+ printBanner("SKILL INSTALL");
23
+ console.log(`Installed skill export: ${path}`);
24
+ }
25
+ export function runSkillDoctor(options) {
26
+ options = normalizeOptions(options);
27
+ printBanner("SKILL DOCTOR");
28
+ for (const check of doctorSkills(options.path ?? process.cwd()))
29
+ console.log(`${check.ok ? "PASS" : "WARN"} ${check.message}`);
30
+ }
31
+ function normalizeOptions(options) {
32
+ return typeof options.opts === "function" ? options.opts() : options;
33
+ }
@@ -1,29 +1,12 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { platform } from "node:os";
3
+ import { buildAgentPrompt } from "../agent-runtimes/prompts.js";
3
4
  const defaultCodexArgs = "--search --dangerously-bypass-approvals-and-sandbox";
4
5
  export function getDefaultCodexArgs() {
5
6
  return process.env.GASLIGHTING_CODEX_ARGS || defaultCodexArgs;
6
7
  }
7
8
  export function buildCodexPrompt(request) {
8
- return [
9
- "Use the gaslighting skill.",
10
- "",
11
- "Read these files before doing any implementation:",
12
- "1. AGENTS.md",
13
- "2. .gaslighting/GASLIGHTING.md",
14
- "3. .gaslighting/PRD.md",
15
- "4. .gaslighting/STACK_POLICY.md",
16
- "5. .gaslighting/MISSING_INFO.md",
17
- "6. .gaslighting/ASSUMPTIONS.md",
18
- "7. .gaslighting/DECISION_LOG.md",
19
- "8. .gaslighting/MEMORY.md",
20
- "9. .gaslighting/AGENT_RUNTIME.md",
21
- "10. .gaslighting/PROJECT_CARE.md",
22
- "",
23
- `Project request: ${request}`,
24
- "",
25
- "Implement the MVP. Preserve full scope. Do not use TODOs as fake implementation. Do not deliver representative examples when full coverage is required. If something is incomplete, declare it explicitly.",
26
- ].join("\n");
9
+ return buildAgentPrompt(request);
27
10
  }
28
11
  export function buildCodexCommand(input) {
29
12
  return buildCodexCommandParts(input).command;
@@ -2,6 +2,7 @@ import { analyze } from "./analyze.js";
2
2
  import { generateGaslightingMarkdown } from "./generateGaslightingMarkdown.js";
3
3
  import { generatePrdMarkdown } from "./generatePrdMarkdown.js";
4
4
  import { generateProjectCareMarkdown } from "./projectCare.js";
5
+ import { generateStructuredDocs } from "./generateStructuredDocs.js";
5
6
  import { generateAgentsMarkdown, generateAgentRuntimeMarkdown, generateAssumptionsMarkdown, generateCodexPromptMarkdown, generateCodexSlashPromptMarkdown, generateDecisionLogMarkdown, generateMemoryMarkdown, generateMissingInfoMarkdown, generateSkillMarkdown, generateSkillOpenAiYaml, generateSkillReferenceDocs, generateStackPolicyMarkdown, } from "./generateOtherMarkdown.js";
6
7
  const disciplineDir = ".gaslighting";
7
8
  export function generateDocs(input, root = process.cwd()) {
@@ -12,6 +13,7 @@ export function generateDocs(input, root = process.cwd()) {
12
13
  };
13
14
  const analysis = analyze(normalized);
14
15
  const docs = [
16
+ ...generateStructuredDocs(normalized, analysis, root),
15
17
  { filename: `${disciplineDir}/GASLIGHTING.md`, content: generateGaslightingMarkdown(normalized, analysis) },
16
18
  { filename: `${disciplineDir}/PRD.md`, content: generatePrdMarkdown(normalized, analysis) },
17
19
  { filename: `${disciplineDir}/ASSUMPTIONS.md`, content: generateAssumptionsMarkdown(analysis) },
@@ -53,6 +55,8 @@ export function generateCodexInstallDocs() {
53
55
  ];
54
56
  return [
55
57
  ...skillDocs,
58
+ { filename: ".agents/config.json", content: `${JSON.stringify({ sourceOfTruth: true, exports: [".codex"], skillRoot: ".agents/skills", mcpRoot: ".agents/mcp" }, null, 2)}\n` },
59
+ { filename: ".agents/mcp/manifest.json", content: `${JSON.stringify({ servers: [], installedAt: null, source: ".agents/mcp" }, null, 2)}\n` },
56
60
  { filename: ".codex/prompts/gaslighting.md", content: generateCodexSlashPromptMarkdown() },
57
61
  { filename: ".agents/prompts/gaslighting.md", content: generateCodexSlashPromptMarkdown() },
58
62
  { filename: ".gaslighting/CODEX_GASLIGHTING.md", content: generateCodexPromptMarkdown() },
@@ -80,18 +84,20 @@ This repository uses Gaslighting-engine.
80
84
 
81
85
  The main discipline documents live under \`.gaslighting/\` to avoid cluttering the project root.
82
86
 
87
+ Start with \`.gaslighting/INDEX.md\`. It points to the mission, product, feature, operation, task, loop, verification, and memory documents.
88
+
83
89
  Before doing any work, read these files in order:
84
90
 
85
- 1. \`.gaslighting/GASLIGHTING.md\`
86
- 2. \`.gaslighting/PRD.md\`
87
- 3. \`.gaslighting/STACK_POLICY.md\`
88
- 4. \`.gaslighting/MISSING_INFO.md\`
89
- 5. \`.gaslighting/ASSUMPTIONS.md\`
90
- 6. \`.gaslighting/DECISION_LOG.md\`
91
- 7. \`.gaslighting/MEMORY.md\`
92
- 8. \`.gaslighting/AGENT_RUNTIME.md\`
93
- 9. \`.gaslighting/PROJECT_CARE.md\`
94
- 10. \`.gaslighting/AGENTS.md\`
91
+ 1. \`.gaslighting/INDEX.md\`
92
+ 2. \`.gaslighting/mission/PROJECT_PURPOSE.md\`
93
+ 3. \`.gaslighting/mission/EXECUTION_RULES.md\`
94
+ 4. \`.gaslighting/mission/COMPLETION_STANDARD.md\`
95
+ 5. \`.gaslighting/product/PRD.md\`
96
+ 6. \`.gaslighting/product/PAGE_MAP.md\`
97
+ 7. \`.gaslighting/features/core-scope/TASKS.md\`
98
+ 8. \`.gaslighting/operations/PROJECT_CARE.md\`
99
+ 9. \`.gaslighting/loops/current-session.json\`
100
+ 10. \`.gaslighting/GASLIGHTING.md\`
95
101
 
96
102
  Do not reduce scope.
97
103
 
@@ -216,15 +216,15 @@ This repository uses Gaslighting-engine.
216
216
 
217
217
  Before doing any work, read these files in order:
218
218
 
219
- 1. \`.gaslighting/GASLIGHTING.md\`
220
- 2. \`.gaslighting/PRD.md\`
221
- 3. \`.gaslighting/STACK_POLICY.md\`
222
- 4. \`.gaslighting/MISSING_INFO.md\`
223
- 5. \`.gaslighting/ASSUMPTIONS.md\`
224
- 6. \`.gaslighting/DECISION_LOG.md\`
225
- 7. \`.gaslighting/MEMORY.md\`
226
- 8. \`.gaslighting/AGENT_RUNTIME.md\`
227
- 9. \`.gaslighting/PROJECT_CARE.md\`
219
+ 1. \`.gaslighting/INDEX.md\`
220
+ 2. \`.gaslighting/mission/PROJECT_PURPOSE.md\`
221
+ 3. \`.gaslighting/mission/EXECUTION_RULES.md\`
222
+ 4. \`.gaslighting/mission/COMPLETION_STANDARD.md\`
223
+ 5. \`.gaslighting/product/PRD.md\`
224
+ 6. \`.gaslighting/features/core-scope/TASKS.md\`
225
+ 7. \`.gaslighting/operations/PROJECT_CARE.md\`
226
+ 8. \`.gaslighting/loops/current-session.json\`
227
+ 9. \`.gaslighting/GASLIGHTING.md\`
228
228
 
229
229
  ## Prime Directive
230
230
 
@@ -516,16 +516,16 @@ Copy and paste this into Codex:
516
516
 
517
517
  Read the following files before doing any work:
518
518
 
519
- 1. \`.gaslighting/GASLIGHTING.md\`
520
- 2. \`.gaslighting/PRD.md\`
521
- 3. \`.gaslighting/STACK_POLICY.md\`
522
- 4. \`.gaslighting/MISSING_INFO.md\`
523
- 5. \`.gaslighting/ASSUMPTIONS.md\`
524
- 6. \`.gaslighting/DECISION_LOG.md\`
519
+ 1. \`.gaslighting/INDEX.md\`
520
+ 2. \`.gaslighting/mission/PROJECT_PURPOSE.md\`
521
+ 3. \`.gaslighting/mission/EXECUTION_RULES.md\`
522
+ 4. \`.gaslighting/product/PRD.md\`
523
+ 5. \`.gaslighting/features/core-scope/TASKS.md\`
524
+ 6. \`.gaslighting/operations/PROJECT_CARE.md\`
525
525
  7. \`AGENTS.md\`
526
- 8. \`.gaslighting/MEMORY.md\`
527
- 9. \`.gaslighting/AGENT_RUNTIME.md\`
528
- 10. \`.gaslighting/PROJECT_CARE.md\`
526
+ 8. \`.gaslighting/GASLIGHTING.md\`
527
+ 9. \`.gaslighting/MISSING_INFO.md\`
528
+ 10. \`.gaslighting/DECISION_LOG.md\`
529
529
 
530
530
  Then implement the project MVP.
531
531
 
@@ -557,16 +557,16 @@ export function generateCodexSlashPromptMarkdown() {
557
557
 
558
558
  Read the Gaslighting-engine project-control files before doing any work:
559
559
 
560
- 1. \`.gaslighting/GASLIGHTING.md\`
561
- 2. \`.gaslighting/PRD.md\`
562
- 3. \`.gaslighting/STACK_POLICY.md\`
563
- 4. \`.gaslighting/MISSING_INFO.md\`
564
- 5. \`.gaslighting/ASSUMPTIONS.md\`
565
- 6. \`.gaslighting/DECISION_LOG.md\`
560
+ 1. \`.gaslighting/INDEX.md\`
561
+ 2. \`.gaslighting/mission/PROJECT_PURPOSE.md\`
562
+ 3. \`.gaslighting/mission/EXECUTION_RULES.md\`
563
+ 4. \`.gaslighting/product/PRD.md\`
564
+ 5. \`.gaslighting/features/core-scope/TASKS.md\`
565
+ 6. \`.gaslighting/operations/PROJECT_CARE.md\`
566
566
  7. \`AGENTS.md\`
567
- 8. \`.gaslighting/MEMORY.md\`
568
- 9. \`.gaslighting/AGENT_RUNTIME.md\`
569
- 10. \`.gaslighting/PROJECT_CARE.md\`
567
+ 8. \`.gaslighting/GASLIGHTING.md\`
568
+ 9. \`.gaslighting/MISSING_INFO.md\`
569
+ 10. \`.gaslighting/DECISION_LOG.md\`
570
570
 
571
571
  Then execute the user's requested implementation.
572
572