@amsterdamdatalabs/enact-extensions 0.1.12 → 0.1.24

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 (147) hide show
  1. package/README.md +11 -12
  2. package/dist/create/enact.js +1 -1
  3. package/dist/create/enact.js.map +1 -1
  4. package/dist/create/index.d.ts +4 -3
  5. package/dist/create/index.d.ts.map +1 -1
  6. package/dist/create/index.js +9 -2
  7. package/dist/create/index.js.map +1 -1
  8. package/dist/index.d.ts +8 -6
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +4 -3
  11. package/dist/index.js.map +1 -1
  12. package/dist/install.d.ts +5 -0
  13. package/dist/install.d.ts.map +1 -1
  14. package/dist/install.js +10 -3
  15. package/dist/install.js.map +1 -1
  16. package/dist/internal/agents.d.ts +6 -1
  17. package/dist/internal/agents.d.ts.map +1 -1
  18. package/dist/internal/agents.js +8 -4
  19. package/dist/internal/agents.js.map +1 -1
  20. package/dist/internal/claude.d.ts +24 -0
  21. package/dist/internal/claude.d.ts.map +1 -1
  22. package/dist/internal/claude.js +99 -0
  23. package/dist/internal/claude.js.map +1 -1
  24. package/dist/internal/platform.d.ts +3 -1
  25. package/dist/internal/platform.d.ts.map +1 -1
  26. package/dist/internal/platform.js +7 -1
  27. package/dist/internal/platform.js.map +1 -1
  28. package/dist/internal/types.d.ts +2 -1
  29. package/dist/internal/types.d.ts.map +1 -1
  30. package/dist/principles.d.ts +28 -0
  31. package/dist/principles.d.ts.map +1 -0
  32. package/dist/principles.js +159 -0
  33. package/dist/principles.js.map +1 -0
  34. package/extensions/dev-state/.agents/plugin.json +2 -1
  35. package/extensions/enact-context/.agents/plugin.json +2 -1
  36. package/extensions/enact-context/hooks/hooks.json +0 -10
  37. package/extensions/enact-context/skills/enact-context/SKILL.md +14 -12
  38. package/extensions/enact-context/skills/enact-context/scripts/install.sh +7 -7
  39. package/extensions/enact-core/.agents/plugin.json +2 -1
  40. package/extensions/enact-core/OPERATING-PRINCIPLES.md +7 -0
  41. package/extensions/enact-core/hooks/hooks.json +12 -0
  42. package/extensions/enact-evolve/.agents/plugin.json +47 -0
  43. package/extensions/enact-evolve/agents/evolve-session-analyst.toml +37 -0
  44. package/extensions/enact-evolve/skills/session-analysis/SKILL.md +98 -0
  45. package/extensions/enact-evolve/skills/session-analysis/scripts/run-evolve-analysis.sh +343 -0
  46. package/extensions/enact-factory/.agents/plugin.json +2 -2
  47. package/extensions/enact-factory/agents/architect.toml +9 -5
  48. package/extensions/enact-factory/agents/code-reviewer.toml +9 -5
  49. package/extensions/enact-factory/agents/critic.toml +9 -5
  50. package/extensions/enact-factory/agents/executor.toml +4 -1
  51. package/extensions/enact-factory/agents/explore.toml +4 -1
  52. package/extensions/enact-factory/agents/planner.toml +4 -1
  53. package/extensions/enact-factory/agents/verifier.toml +9 -5
  54. package/extensions/enact-factory/skills/advisor/SKILL.md +82 -0
  55. package/extensions/enact-factory/skills/ai-slop-cleaner/SKILL.md +6 -1
  56. package/extensions/enact-factory/skills/autonomous-runner/SKILL.md +347 -0
  57. package/extensions/enact-factory/skills/azdo-ci-strategy/SKILL.md +42 -15
  58. package/extensions/enact-factory/skills/committee/SKILL.md +80 -0
  59. package/extensions/enact-factory/skills/deep-interview/SKILL.md +9 -13
  60. package/extensions/enact-factory/skills/drive-loop/SKILL.md +161 -31
  61. package/extensions/enact-factory/skills/drive-loop/references/contract-schema.md +26 -6
  62. package/extensions/enact-factory/skills/handoff/SKILL.md +72 -0
  63. package/extensions/enact-factory/skills/hyperplan/SKILL.md +11 -3
  64. package/extensions/enact-factory/skills/looplan/SKILL.md +34 -17
  65. package/extensions/enact-factory/skills/plan/SKILL.md +40 -8
  66. package/extensions/enact-factory/skills/remove-deadcode/SKILL.md +6 -1
  67. package/extensions/enact-factory/skills/research/SKILL.md +14 -4
  68. package/extensions/enact-factory/skills/review/SKILL.md +21 -2
  69. package/extensions/enact-factory/skills/security-research/SKILL.md +5 -2
  70. package/extensions/enact-factory/skills/tdd/SKILL.md +7 -1
  71. package/extensions/enact-factory/skills/testing-strategy/SKILL.md +5 -0
  72. package/extensions/enact-factory/skills/trace/SKILL.md +5 -0
  73. package/extensions/enact-factory/skills/ultraqa/SKILL.md +21 -15
  74. package/extensions/enact-factory/skills/work-with-workitem/SKILL.md +5 -0
  75. package/extensions/enact-factory/skills/workitem-triage/SKILL.md +5 -0
  76. package/extensions/enact-loop/.agents/plugin.json +5 -4
  77. package/extensions/enact-loop/scripts/validate.mjs +123 -0
  78. package/extensions/enact-loop/skills/enact-loop/SKILL.md +189 -30
  79. package/extensions/enact-wiki/.agents/plugin.json +2 -1
  80. package/extensions/net-revenue-management/.agents/plugin.json +2 -1
  81. package/extensions/plugin-dev/.agents/plugin.json +2 -1
  82. package/extensions/plugin-dev/skills/start/SKILL.md +3 -3
  83. package/package.json +1 -1
  84. package/scripts/check-hooks.mjs +5 -5
  85. package/scripts/check-principles.mjs +19 -4
  86. package/scripts/enact-extensions.mjs +237 -90
  87. package/scripts/lib/hooks.mjs +61 -217
  88. package/scripts/lib/migrate-artifacts.mjs +144 -0
  89. package/scripts/lib/principles.mjs +109 -0
  90. package/scripts/lib/provision-mcp.mjs +1 -1
  91. package/scripts/lib/run-install.mjs +72 -2
  92. package/scripts/lib/run-prune.mjs +23 -2
  93. package/scripts/lib/run-sync.mjs +4 -1
  94. package/scripts/postinstall.mjs +6 -6
  95. package/scripts/setup-enact-context.sh +20 -15
  96. package/spec/codex.json +5 -0
  97. package/spec/enact.json +3 -3
  98. package/spec/enact.md +1 -4
  99. package/spec/index.json +1 -1
  100. package/extensions/enact-factory/hooks/hooks.json +0 -14
  101. package/extensions/enact-operator/.agents/plugin.json +0 -56
  102. package/extensions/enact-operator/.app.json +0 -3
  103. package/extensions/enact-operator/.mcp.json +0 -10
  104. package/extensions/enact-operator/_taxonomy.md +0 -86
  105. package/extensions/enact-operator/agents/README.md +0 -5
  106. package/extensions/enact-operator/agents/architect.toml +0 -25
  107. package/extensions/enact-operator/agents/code-reviewer.toml +0 -24
  108. package/extensions/enact-operator/agents/critic.toml +0 -30
  109. package/extensions/enact-operator/agents/executor.toml +0 -24
  110. package/extensions/enact-operator/agents/explore.toml +0 -23
  111. package/extensions/enact-operator/agents/planner.toml +0 -24
  112. package/extensions/enact-operator/agents/verifier.toml +0 -24
  113. package/extensions/enact-operator/docs/skill-variants.md +0 -44
  114. package/extensions/enact-operator/hooks/hooks.json +0 -91
  115. package/extensions/enact-operator/skills/ai-slop-cleaner/SKILL.md +0 -50
  116. package/extensions/enact-operator/skills/analyze/SKILL.md +0 -91
  117. package/extensions/enact-operator/skills/ask/SKILL.md +0 -47
  118. package/extensions/enact-operator/skills/autopilot/SKILL.md +0 -170
  119. package/extensions/enact-operator/skills/autoresearch-goal/SKILL.md +0 -79
  120. package/extensions/enact-operator/skills/cancel/SKILL.md +0 -99
  121. package/extensions/enact-operator/skills/configure-notifications/SKILL.md +0 -77
  122. package/extensions/enact-operator/skills/deep-interview/SKILL.md +0 -80
  123. package/extensions/enact-operator/skills/doctor/SKILL.md +0 -48
  124. package/extensions/enact-operator/skills/hud/SKILL.md +0 -49
  125. package/extensions/enact-operator/skills/hyperplan/SKILL.md +0 -47
  126. package/extensions/enact-operator/skills/plan/SKILL.md +0 -78
  127. package/extensions/enact-operator/skills/ralph/SKILL.md +0 -201
  128. package/extensions/enact-operator/skills/ralph/gemini.md +0 -18
  129. package/extensions/enact-operator/skills/ralplan/SKILL.md +0 -151
  130. package/extensions/enact-operator/skills/remove-deadcode/SKILL.md +0 -45
  131. package/extensions/enact-operator/skills/research/SKILL.md +0 -74
  132. package/extensions/enact-operator/skills/review/SKILL.md +0 -58
  133. package/extensions/enact-operator/skills/security-research/SKILL.md +0 -54
  134. package/extensions/enact-operator/skills/setup/SKILL.md +0 -91
  135. package/extensions/enact-operator/skills/setup/scripts/install.sh +0 -50
  136. package/extensions/enact-operator/skills/skill/SKILL.md +0 -82
  137. package/extensions/enact-operator/skills/tdd/SKILL.md +0 -59
  138. package/extensions/enact-operator/skills/team/SKILL.md +0 -199
  139. package/extensions/enact-operator/skills/trace/SKILL.md +0 -41
  140. package/extensions/enact-operator/skills/ultragoal/SKILL.md +0 -99
  141. package/extensions/enact-operator/skills/ultraqa/SKILL.md +0 -113
  142. package/extensions/enact-operator/skills/ultrawork/SKILL.md +0 -145
  143. package/extensions/enact-operator/skills/ultrawork/planner.md +0 -28
  144. package/extensions/enact-operator/skills/wiki/SKILL.md +0 -41
  145. package/extensions/enact-operator/skills/work-with-workitem/SKILL.md +0 -51
  146. /package/extensions/{enact-operator → enact-evolve}/assets/icon.png +0 -0
  147. /package/extensions/{enact-operator → enact-evolve}/assets/logo.png +0 -0
@@ -2,6 +2,7 @@ import { dirname, join } from "node:path";
2
2
  import { homedir } from "node:os";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import {
5
+ activateClaudePlugin,
5
6
  installPluginBundle,
6
7
  installClaudePluginBundle,
7
8
  installCursorPluginBundle,
@@ -13,7 +14,7 @@ import {
13
14
  import { appendEntry } from "./ledger.mjs";
14
15
  import { bundleHash } from "./bundle-hash.mjs";
15
16
  import { provisionMcp, summarizeProvision } from "./provision-mcp.mjs";
16
- import { registerPluginHooks, removePluginHooks } from "./hooks.mjs";
17
+ import { registerPluginHooks, removeHook, removePluginHooks } from "./hooks.mjs";
17
18
  import { assertSupportedHookEvents } from "../../dist/index.js";
18
19
 
19
20
  // scope: "global" (default) -> the agent's default home (~/.codex, ~/.enact/agent, ~/.claude, ~/.cursor, ~/.agents)
@@ -198,6 +199,33 @@ function readJsonIfExists(path) {
198
199
  }
199
200
  }
200
201
 
202
+ function readCanonicalManifest(pluginRoot) {
203
+ return readJsonIfExists(join(pluginRoot, ".agents", "plugin.json"));
204
+ }
205
+
206
+ function supportedHostSurfaces(pluginRoot) {
207
+ const manifest = readCanonicalManifest(pluginRoot);
208
+ const rawTargets = manifest?.targets;
209
+ if (!Array.isArray(rawTargets)) return [...ALL_PLATFORMS];
210
+ return rawTargets.filter((target) => ALL_PLATFORMS.includes(target));
211
+ }
212
+
213
+ function assertRequestedPlatformsSupported(pluginRoot, requestedPlatforms) {
214
+ const supported = supportedHostSurfaces(pluginRoot);
215
+ const unsupported = requestedPlatforms.filter(
216
+ (platform) => ALL_PLATFORMS.includes(platform) && !supported.includes(platform),
217
+ );
218
+ if (unsupported.length === 0) return;
219
+
220
+ const manifest = readCanonicalManifest(pluginRoot);
221
+ const pluginName = typeof manifest?.name === "string" ? manifest.name : pluginRoot.split("/").pop();
222
+ const supportedLabel = supported.length > 0 ? supported.join(", ") : "(none)";
223
+ throw new Error(
224
+ `Plugin ${pluginName} does not target host surface(s): ${unsupported.join(", ")}. ` +
225
+ `Supported host surfaces: ${supportedLabel}`,
226
+ );
227
+ }
228
+
201
229
  function readPluginHookConfig(pluginRoot) {
202
230
  const manifest = readJsonIfExists(join(pluginRoot, ".agents", "plugin.json"));
203
231
  const hooksPath = typeof manifest?.hooks === "string" ? manifest.hooks : null;
@@ -206,9 +234,16 @@ function readPluginHookConfig(pluginRoot) {
206
234
  return readJsonIfExists(join(pluginRoot, normalized));
207
235
  }
208
236
 
237
+ function hookConfigHasEntries(hookConfig) {
238
+ const hooks = hookConfig?.hooks;
239
+ if (!hooks || typeof hooks !== "object" || Array.isArray(hooks)) return false;
240
+ return Object.values(hooks).some((entries) => Array.isArray(entries) && entries.length > 0);
241
+ }
242
+
209
243
  function registerInstalledPluginHooks(pluginRoot, platform, result, homes, options) {
210
244
  // codex reads hooks from the installed plugin bundle (no config.toml
211
- // registration); cursor likewise. claude/enact register into their config.
245
+ // registration); cursor likewise. claude/enact stay in the reconcile path
246
+ // only so removePluginHooks can clean legacy scattered runtime hooks.
212
247
  if (!["claude", "cursor", "enact"].includes(platform)) return;
213
248
  const hookConfig = readPluginHookConfig(pluginRoot);
214
249
  const name = result?.name ?? result?.results?.[0]?.name;
@@ -235,6 +270,20 @@ function registerInstalledPluginHooks(pluginRoot, platform, result, homes, optio
235
270
  }
236
271
  }
237
272
 
273
+ function activateInstalledClaudePlugin(pluginRoot, result, homes, options) {
274
+ const hookConfig = readPluginHookConfig(pluginRoot);
275
+ if (!hookConfigHasEntries(hookConfig)) return;
276
+ const pluginId = `${result.name}@${result.marketplaceName ?? (options.marketplaceName ?? "enact-os-plugins")}`;
277
+ const activation = activateClaudePlugin(
278
+ homes.claudeHome,
279
+ pluginId,
280
+ result.marketplaceDir,
281
+ homes.scope,
282
+ options.claudeExec,
283
+ );
284
+ console.log(`claude plugin ${activation.action} -> ${pluginId}`);
285
+ }
286
+
238
287
  function removeLegacyCodexPluginHooks(name, result, homes, options) {
239
288
  if (!name) return;
240
289
 
@@ -261,6 +310,21 @@ function removeLegacyCodexPluginHooks(name, result, homes, options) {
261
310
  }
262
311
  }
263
312
 
313
+ function removeLegacyStandaloneDriftHook(platform, name, homes, options) {
314
+ if (name !== "enact-core") return;
315
+ const hookResult = removeHook(platform, {
316
+ claudeHome: homes.claudeHome,
317
+ codexHome: homes.codexHome,
318
+ cursorHome: homes.cursorHome,
319
+ enactHome: homes.enactHome,
320
+ local: homes.scope === "local",
321
+ cwd: options.cwd ?? process.cwd(),
322
+ });
323
+ if (hookResult.result === "removed") {
324
+ console.log(`removed legacy drift hook for ${name} on ${platform} -> ${hookResult.location}`);
325
+ }
326
+ }
327
+
264
328
  // Append one install entry per installed target in a single-platform result.
265
329
  // Tolerant of every result shape (single platform, shared, codex multi-home).
266
330
  // `hash` is the pre-computed bundle hash (or null) for this install invocation.
@@ -318,6 +382,10 @@ function runSinglePlatform(pluginRoot, platform, homes, options, hash) {
318
382
  target.log(result);
319
383
  recordInstall(platform, result, homes, options, hash);
320
384
  registerInstalledPluginHooks(pluginRoot, platform, result, homes, options);
385
+ removeLegacyStandaloneDriftHook(platform, result?.name, homes, options);
386
+ if (platform === "claude") {
387
+ activateInstalledClaudePlugin(pluginRoot, result, homes, options);
388
+ }
321
389
  return result;
322
390
  }
323
391
 
@@ -337,6 +405,7 @@ function runSinglePlatform(pluginRoot, platform, homes, options, hash) {
337
405
  }
338
406
  recordInstall("codex", result, homes, options, hash);
339
407
  removeLegacyCodexPluginHooks(result.results[0]?.name, result, homes, options);
408
+ removeLegacyStandaloneDriftHook("codex", result.results[0]?.name, homes, options);
340
409
  return result;
341
410
  }
342
411
 
@@ -375,6 +444,7 @@ export function runInstall(pluginRoot, options = {}) {
375
444
  assertSupportedHookEvents(pluginRoot);
376
445
 
377
446
  const platforms = parsePlatforms(options.platform);
447
+ assertRequestedPlatformsSupported(pluginRoot, platforms);
378
448
  const homes = resolveHomes(options);
379
449
  console.log(`install scope: ${homes.scope}${homes.scope === "local" ? ` (${process.cwd()})` : ""}`);
380
450
 
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
3
3
  import { cwd as processCwd } from "node:process";
4
4
  import { dirname, join, resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
- import { listInstalled } from "./ledger.mjs";
6
+ import { appendEntry, listInstalled } from "./ledger.mjs";
7
7
  import { parsePlatforms, runUninstall } from "./run-uninstall.mjs";
8
8
 
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -21,6 +21,10 @@ function sourceBundleExists(name, sourceRoots) {
21
21
  return sourceRoots.some((root) => existsSync(join(root, name, ".agents", "plugin.json")));
22
22
  }
23
23
 
24
+ function installedSurfaceExists(entry) {
25
+ return Boolean(entry.path) && existsSync(entry.path);
26
+ }
27
+
24
28
  function homeOptionForPlatform(platform) {
25
29
  switch (platform) {
26
30
  case "codex": return "codexHome";
@@ -32,6 +36,22 @@ function homeOptionForPlatform(platform) {
32
36
  }
33
37
  }
34
38
 
39
+ function recordPruneTombstone(entry, ledgerHome, marketplaceName) {
40
+ appendEntry(
41
+ {
42
+ action: "uninstall",
43
+ name: entry.name,
44
+ version: entry.version ?? "0.0.0",
45
+ platform: entry.platform,
46
+ scope: entry.scope,
47
+ home: entry.home,
48
+ path: entry.path,
49
+ marketplaceName: entry.marketplaceName ?? marketplaceName,
50
+ },
51
+ { home: ledgerHome },
52
+ );
53
+ }
54
+
35
55
  export function runPrune(options = {}) {
36
56
  const cwd = options.cwd ?? processCwd();
37
57
  const ledgerHome = options.ledgerHome ?? options.home ?? homedir();
@@ -43,7 +63,7 @@ export function runPrune(options = {}) {
43
63
  const candidates = installed
44
64
  .filter((entry) => platforms.has(entry.platform))
45
65
  .filter((entry) => entry.marketplaceName === marketplaceName)
46
- .filter((entry) => !sourceBundleExists(entry.name, sourceRoots));
66
+ .filter((entry) => !sourceBundleExists(entry.name, sourceRoots) || !installedSurfaceExists(entry));
47
67
 
48
68
  const pruned = [];
49
69
  const failed = [];
@@ -63,6 +83,7 @@ export function runPrune(options = {}) {
63
83
  ledgerHome,
64
84
  version: entry.version,
65
85
  });
86
+ recordPruneTombstone(entry, ledgerHome, marketplaceName);
66
87
  pruned.push(entry);
67
88
  } catch (err) {
68
89
  failed.push({ entry, error: err instanceof Error ? err : new Error(String(err)) });
@@ -26,7 +26,10 @@ export function runSync(pluginRoot, { name } = {}) {
26
26
 
27
27
  const results = syncPlatformManifests(pluginRoot, enact);
28
28
  for (const r of results) {
29
- console.log(`${r.written ? "wrote" : "skip"} ${r.manifestPath}`);
29
+ const generatedProjectionNote = /(^|\/)\.(claude|codex|cursor)-plugin\//.test(r.manifestPath)
30
+ ? " (generated preview only; normal install uses enact-extensions install)"
31
+ : "";
32
+ console.log(`${r.written ? "wrote" : "skip"} ${r.manifestPath}${generatedProjectionNote}`);
30
33
  }
31
34
  return results;
32
35
  }
@@ -6,7 +6,7 @@
6
6
  * - If NOT a TTY → print one-line notice and exit 0. NEVER hang.
7
7
  * - If CI env var is set → print one-line notice and exit 0.
8
8
  * - If ENACT_EXTENSIONS_NO_POSTINSTALL is set → print one-line notice and exit 0.
9
- * - If interactive TTY (and not CI) → run `hooks setup` interactive picker.
9
+ * - If interactive TTY (and not CI) → install `enact-core` across host surfaces.
10
10
  * - Entire script is wrapped in try/catch → ALWAYS process.exit(0).
11
11
  * A postinstall that throws would break `npm ci` in CI.
12
12
  *
@@ -14,7 +14,7 @@
14
14
  * - Docker CI environments (CI=1, no TTY)
15
15
  * - npm ci / npm install in CI pipelines
16
16
  * - Automated install tooling (pipes, scripts)
17
- * - Developer machines with interactive TTY (triggers the interactive picker)
17
+ * - Developer machines with interactive TTY (triggers enact-core install)
18
18
  */
19
19
 
20
20
  try {
@@ -24,7 +24,7 @@ try {
24
24
  const isNoPostinstall = !!(env.ENACT_EXTENSIONS_NO_POSTINSTALL);
25
25
  const isTTY = !!(stdin.isTTY);
26
26
 
27
- const NOTICE = `Run \`enact-extensions hooks setup\` to enable session-start drift checks.\n`;
27
+ const NOTICE = `Run \`enact-extensions install enact-core --platform all\` to enable session-start drift checks.\n`;
28
28
 
29
29
  if (!isTTY || isCI || isNoPostinstall) {
30
30
  // Non-interactive or CI: print notice and exit immediately.
@@ -32,7 +32,7 @@ try {
32
32
  process.exit(0);
33
33
  }
34
34
 
35
- // Interactive TTY (non-CI): run the hooks setup interactive picker via CLI.
35
+ // Interactive TTY (non-CI): install enact-core, which now owns SessionStart.
36
36
  // We spawn a child process rather than importing directly to keep postinstall
37
37
  // isolated from any import-time side-effects in the CLI modules.
38
38
  const { spawnSync } = await import("node:child_process");
@@ -44,7 +44,7 @@ try {
44
44
 
45
45
  // Spawn with stdio inherited so the interactive readline prompt is visible.
46
46
  // We spawn and ignore the exit code — postinstall must always exit 0.
47
- spawnSync(process.execPath, [CLI, "hooks", "setup"], {
47
+ spawnSync(process.execPath, [CLI, "install", "enact-core", "--platform", "all"], {
48
48
  stdio: "inherit",
49
49
  env: { ...process.env },
50
50
  });
@@ -54,7 +54,7 @@ try {
54
54
  // Printing to stderr is best-effort (safe to fail).
55
55
  try {
56
56
  process.stderr.write(
57
- "[enact-extensions postinstall] Non-fatal error during hook setup. Run `enact-extensions hooks setup` manually.\n",
57
+ "[enact-extensions postinstall] Non-fatal error during enact-core install. Run `enact-extensions install enact-core --platform all` manually.\n",
58
58
  );
59
59
  } catch {
60
60
  // Even stderr.write failed — just exit 0.
@@ -1,23 +1,28 @@
1
1
  #!/usr/bin/env bash
2
- # Wire enact-context setup into the enact-extensions workspace.
3
- # Validates the plugin-dev bundle then runs consolidated agent setup.
2
+ # Install enact-context through the enact-extensions plugin system.
3
+ #
4
+ # This intentionally does NOT run `enact-context setup` or `doctor --fix`.
5
+ # Those commands write direct host artifacts such as ~/.codex/AGENTS.md,
6
+ # ~/.codex/hooks.json, and ~/.codex/skills/enact-context, bypassing plugin
7
+ # enable/disable and uninstall semantics.
4
8
  set -euo pipefail
5
9
 
6
10
  ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
7
- REPO_ROOT="$(cd "$ROOT/.." && pwd)"
8
-
9
- if ! command -v enact-context >/dev/null 2>&1; then
10
- if [[ -x "$REPO_ROOT/enact-context/rust/target/release/enact-context" ]]; then
11
- export PATH="$REPO_ROOT/enact-context/rust/target/release:$PATH"
12
- else
13
- echo "enact-context binary not found on PATH" >&2
14
- exit 1
15
- fi
16
- fi
17
11
 
18
12
  cd "$ROOT"
19
- npm run validate
13
+ npm run build
14
+ node scripts/enact-extensions.mjs validate extensions/enact-context
20
15
 
21
16
  echo ""
22
- echo "Running enact-context setup (claude, codex, opencode, enact, zed)..."
23
- enact-context setup "$@"
17
+ echo "Installing enact-context via enact-extensions plugin registration..."
18
+ if [[ " $* " == *" --platform "* ]]; then
19
+ node scripts/enact-extensions.mjs install enact-context "$@"
20
+ else
21
+ node scripts/enact-extensions.mjs install enact-context --platform "${ENACT_CONTEXT_PLATFORM:-codex}" "$@"
22
+ fi
23
+
24
+ if ! command -v enact-context >/dev/null 2>&1; then
25
+ echo ""
26
+ echo "Note: enact-context runtime binary is not on PATH."
27
+ echo "Install the runtime separately; do not use 'enact-context setup' for Codex registration."
28
+ fi
package/spec/codex.json CHANGED
@@ -69,6 +69,11 @@
69
69
  "description": "Relative path to the skills directory.",
70
70
  "default": "./skills/"
71
71
  },
72
+ "agents": {
73
+ "type": "string",
74
+ "description": "Relative path to the canonical TOML agents directory.",
75
+ "default": "./agents/"
76
+ },
72
77
  "mcpServers": {
73
78
  "type": "string",
74
79
  "description": "Relative path to the .mcp.json MCP server configuration file.",
package/spec/enact.json CHANGED
@@ -52,13 +52,13 @@
52
52
  },
53
53
  "targets": {
54
54
  "type": "array",
55
- "description": "Agent platforms this plugin is built for. Drives platform-specific manifest generation.",
55
+ "description": "Supported install surfaces for this plugin. The canonical .agents/plugin.json is the Enact surface; claude/codex/cursor are derived projections.",
56
56
  "items": {
57
57
  "type": "string",
58
- "enum": ["claude", "codex", "cursor"]
58
+ "enum": ["claude", "codex", "cursor", "enact"]
59
59
  },
60
60
  "uniqueItems": true,
61
- "minItems": 1
61
+ "minItems": 0
62
62
  },
63
63
  "skills": {
64
64
  "type": "string",
package/spec/enact.md CHANGED
@@ -10,14 +10,13 @@ Extend what Enact can do, for example:
10
10
  - Install the enact-context plugin to give agents deep code intelligence and semantic search.
11
11
  - Install the enact-wiki plugin to persist knowledge across sessions and projects.
12
12
  - Install the enact-loop plugin to run durable contract-verified work with independent judgment grading.
13
- - Install the enact-operator plugin for the full operator surface (team orchestration, HUD, doctor, and oversight tools).
14
13
 
15
14
  A plugin can contain:
16
15
 
17
16
  - **Skills:** reusable instructions for specific kinds of work. Agents load
18
17
  them on demand so they follow the right steps and use the right references
19
18
  or helper scripts for a task.
20
- - **Slash commands:** named commands invoked directly by the user (e.g. `/enact-operator:setup`)
19
+ - **Slash commands:** named commands invoked directly by the user (e.g. `/plugin-name:command-name`)
21
20
  to trigger specific workflows without relying on automatic skill selection.
22
21
  - **MCP servers:** services that give agents access to additional tools or
23
22
  shared information, often from systems outside the local project.
@@ -90,8 +89,6 @@ If you want to keep a plugin installed but turn it off, set its entry in
90
89
  enabled = false
91
90
  ```
92
91
 
93
- > **Note:** enact-operator is also available in the registry for teams that need the full operator surface (HUD, doctor, team orchestration, oversight). enact-loop is the recommended default for contract-verified loop work.
94
-
95
92
  ## Build your own plugin
96
93
 
97
94
  Plugins live in a directory containing an `.agents/` folder with a `plugin.json`
package/spec/index.json CHANGED
@@ -46,7 +46,7 @@
46
46
  "targets": {
47
47
  "type": "array",
48
48
  "items": { "type": "string" },
49
- "description": "Agent platforms this plugin targets (e.g. claude, codex, cursor)."
49
+ "description": "Supported host surfaces for this plugin (e.g. claude, codex, cursor, enact)."
50
50
  },
51
51
  "path": {
52
52
  "type": "string",
@@ -1,14 +0,0 @@
1
- {
2
- "hooks": {
3
- "UserPromptSubmit": [
4
- {
5
- "hooks": [
6
- {
7
- "type": "command",
8
- "command": "enact-factory hook user-prompt-submit"
9
- }
10
- ]
11
- }
12
- ]
13
- }
14
- }
@@ -1,56 +0,0 @@
1
- {
2
- "name": "enact-operator",
3
- "version": "0.1.0",
4
- "description": "First-party Enact Operator plugin surfaces for skills, commands, agents, MCP, and runtime hook registrations.",
5
- "author": {
6
- "name": "amsterdamdatalabs"
7
- },
8
- "homepage": "https://amsterdamdatalabs.com",
9
- "repository": "https://dev.azure.com/amsterdamdatalabs/Enact/_git/enact-operator",
10
- "license": "UNLICENSED",
11
- "keywords": [
12
- "enact",
13
- "operator",
14
- "orchestration",
15
- "workflow"
16
- ],
17
- "targets": [
18
- "claude",
19
- "codex",
20
- "cursor"
21
- ],
22
- "skills": "./skills/",
23
- "agents": "./agents/",
24
- "mcpServers": "./.mcp.json",
25
- "apps": "./.app.json",
26
- "interface": {
27
- "displayName": "Enact Operator",
28
- "shortDescription": "Installable surfaces for Enact Operator workflows.",
29
- "longDescription": "Bundles the operator-owned Enact catalog. enact-extensions owns install, registration, hook wiring, enable/disable, status, and uninstall. Hook registrations call stable enact-operator runtime commands such as enact-operator hook user-prompt-submit; hook implementations stay in the enact-operator package.",
30
- "developerName": "enact-operator",
31
- "category": "Developer Tools",
32
- "composerIcon": "./assets/icon.png",
33
- "logo": "./assets/logo.png",
34
- "capabilities": [
35
- "skills",
36
- "slash commands",
37
- "operator workflows",
38
- "team orchestration",
39
- "operator setup",
40
- "doctor and readiness audits",
41
- "plan and execution workflows",
42
- "review and QA workflows",
43
- "federated context and memory workflows"
44
- ]
45
- },
46
- "operator": {
47
- "firstParty": true,
48
- "bundledMcpProviders": [
49
- "enact-factory",
50
- "enact-context",
51
- "enact-wiki"
52
- ],
53
- "operatorScope": "project"
54
- },
55
- "hooks": "./hooks/hooks.json"
56
- }
@@ -1,3 +0,0 @@
1
- {
2
- "apps": {}
3
- }
@@ -1,10 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "enact-operator": {
4
- "command": "enact-operator",
5
- "args": [
6
- "mcp"
7
- ]
8
- }
9
- }
10
- }
@@ -1,86 +0,0 @@
1
- # Enact Operator Extension Taxonomy
2
-
3
- `extensions/` has three extension tiers. Each entry belongs to exactly one tier.
4
-
5
- ## Pure skills
6
-
7
- Pure skills live at `extensions/skills/<name>/SKILL.md`.
8
-
9
- - No MCP tool surface
10
- - No persisted lane state
11
- - Prompt/context guidance only
12
-
13
- Current pure skills:
14
-
15
- - `ai-slop-cleaner`
16
- - `analyze`
17
- - `ask`
18
- - `autoresearch-goal`
19
- - `cancel`
20
- - `configure-notifications`
21
- - `deep-interview`
22
- - `doctor`
23
- - `hud`
24
- - `hyperplan`
25
- - `plan`
26
- - `remove-deadcode`
27
- - `research`
28
- - `review`
29
- - `security-research`
30
- - `setup`
31
- - `skill`
32
- - `tdd`
33
- - `trace`
34
- - `wiki`
35
- - `work-with-workitem`
36
-
37
- ## Agents
38
-
39
- Codex subagents live at `extensions/agents/*.toml`.
40
-
41
- - Stateless worker contracts
42
- - Dispatched through Codex subagents
43
- - Installed into the Codex agents directory by setup
44
-
45
- The old exact-name collisions `architect`, `executor`, and `reviewer` were removed from `extensions/skills/` once their Codex agent TOMLs existed. The remaining helper surfaces such as `plan`, `review`, `research`, `trace`, and `analyze` are pure skills, not agent files.
46
-
47
- ## Operator lanes
48
-
49
- Operator lanes remain under `extensions/skills/<name>/SKILL.md`, but they are explicitly tagged with:
50
-
51
- - `lane: true`
52
- - `mcpToolPrefix: operator_<lane>_`
53
-
54
- Lanes add:
55
-
56
- - MCP tool surfaces
57
- - persisted operator state
58
- - runtime lifecycle semantics
59
-
60
- **Classification rule:** an entry is a **root lane** if and only if it has both (a) a durable operator state file under `.enact/operator/state/` AND (b) an `mcpToolPrefix` field in its `SKILL.md` frontmatter. Any entry that satisfies only one criterion, or neither, is a wrapper or continuity overlay, not a root lane.
61
-
62
- ### Root lanes
63
-
64
- Root lanes are the four autonomous runtime execution lanes that the scheduler assigns tasks to. Each has a durable state file and its own `mcpToolPrefix`.
65
-
66
- - `ralph`
67
- - `ultrawork`
68
- - `team`
69
- - `autopilot`
70
-
71
- ### Continuity overlays
72
-
73
- Continuity overlays have an MCP surface and durable state, but serve as multi-session goal artifacts that wrap one or more root lanes rather than acting as independent scheduler candidates.
74
-
75
- - `ultragoal`
76
-
77
- ### Wrappers
78
-
79
- Wrappers delegate execution to a root lane (typically ralph) and carry no independent durable state file of their own.
80
-
81
- - `ralplan`
82
- - `ultraqa`
83
-
84
- ## Disambiguation rule
85
-
86
- No entry may straddle tiers. If a surface needs Codex subagent dispatch, it belongs in `extensions/agents/`. If it needs Operator MCP tools and durable state, it is a lane. Everything else is a pure skill.
@@ -1,5 +0,0 @@
1
- # Enact Operator Agents
2
-
3
- Codex-compatible agent TOMLs live in this directory.
4
-
5
- The taxonomy contract is documented in [`../_taxonomy.md`](../_taxonomy.md). During the active migration, the legacy agent-style skill directories in `../skills/` are the source material for the TOML ports that land here.
@@ -1,25 +0,0 @@
1
- name = "architect"
2
- description = "Architectural review and GO/NO-GO verdict with evidence pointers"
3
- model = "gpt-5.3-codex"
4
- model_reasoning_effort = "high"
5
- sandbox_mode = "danger-full-access"
6
- developer_instructions = """
7
- You are the Enact Operator architect agent.
8
-
9
- Role:
10
- - Read-only architectural reviewer.
11
- - Diagnose root causes from code and docs already on disk.
12
- - Produce a GO or NO-GO verdict with concrete evidence pointers.
13
-
14
- Rules:
15
- - Never edit files.
16
- - Never speculate when you can read the source.
17
- - Cite exact file paths and line references for material claims.
18
- - Call out tradeoffs, not just the favored direction.
19
-
20
- Output contract:
21
- - verdict: GO or NO-GO
22
- - reasons: concise bullet list
23
- - evidencePointers: file references
24
- - tradeoffs: short list
25
- """
@@ -1,24 +0,0 @@
1
- name = "code-reviewer"
2
- description = "Binding code review pass enforcing unconditional approval or actionable findings"
3
- model = "gpt-5.3-codex"
4
- model_reasoning_effort = "high"
5
- sandbox_mode = "danger-full-access"
6
- developer_instructions = """
7
- You are the Enact Operator code-reviewer agent.
8
-
9
- Role:
10
- - Perform the binding review pass after an implementation batch.
11
- - Prioritize correctness, regressions, and missing verification over style.
12
-
13
- Rules:
14
- - Never edit files.
15
- - Review only from the actual diff and surrounding code.
16
- - Every finding must cite a file reference and explain impact.
17
- - If no actionable issues remain, emit the token UNCONDITIONAL_APPROVE.
18
- - Otherwise, return a blocking verdict with the findings ordered by severity.
19
-
20
- Output contract:
21
- - verdict: UNCONDITIONAL_APPROVE or REQUEST_CHANGES
22
- - findings: severity-ordered list with evidence
23
- - residual_risks: optional short list
24
- """
@@ -1,30 +0,0 @@
1
- name = "critic"
2
- description = "Adversarial debate participant for hyperplan and high-risk decision review"
3
- model = "gpt-5.3-codex"
4
- model_reasoning_effort = "high"
5
- sandbox_mode = "danger-full-access"
6
- developer_instructions = """
7
- You are the Enact Operator critic agent.
8
-
9
- Role:
10
- - Attack weak assumptions in plans, proposals, and risky implementation choices.
11
- - Operate as an adversarial reviewer, not a collaborator trying to be agreeable.
12
-
13
- Rules:
14
- - Never edit files.
15
- - Surface the strongest counterargument first.
16
- - Prefer concrete failure modes over vague concern language.
17
- - When a decision looks sound, say that plainly instead of inventing objections.
18
-
19
- Round protocol:
20
- 1. Independent critique.
21
- 2. Cross-attack on the competing argument.
22
- 3. Defend, refine, or concede.
23
-
24
- Output contract:
25
- - position
26
- - strongest_objections
27
- - failure_modes
28
- - concessions
29
- - final_recommendation
30
- """
@@ -1,24 +0,0 @@
1
- name = "executor"
2
- description = "Focused implementation worker for small, reviewable diffs with verification"
3
- model = "gpt-5.3-codex"
4
- model_reasoning_effort = "medium"
5
- sandbox_mode = "danger-full-access"
6
- developer_instructions = """
7
- You are the Enact Operator executor agent.
8
-
9
- Role:
10
- - Implement the requested change with the smallest viable diff.
11
- - Run focused verification before claiming completion.
12
-
13
- Rules:
14
- - Stay inside the stated scope.
15
- - Match existing code patterns.
16
- - Do not add abstractions unless the code clearly needs them.
17
- - Do not stop at code changes; include the verification result.
18
- - If blocked after repeated failed attempts, report the blocker clearly.
19
-
20
- Output contract:
21
- - changes_made
22
- - verification
23
- - blockers_or_followups
24
- """