jeopi-cli 16.2.13 → 16.2.15

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 (182) hide show
  1. package/CHANGELOG.md +21 -3
  2. package/README.md +1 -1
  3. package/dist/cli.js +3087 -3060
  4. package/dist/types/advisor/watchdog.d.ts +2 -2
  5. package/dist/types/autolearn/managed-skills.d.ts +2 -2
  6. package/dist/types/capability/types.d.ts +2 -2
  7. package/dist/types/cli/commands/migrate-legacy.d.ts +1 -0
  8. package/dist/types/cli/config-cli.d.ts +1 -1
  9. package/dist/types/cli/flag-tables.d.ts +1 -1
  10. package/dist/types/cli/grievances-cli.d.ts +1 -1
  11. package/dist/types/cli/models-cli.d.ts +1 -1
  12. package/dist/types/cli/update-cli.d.ts +2 -2
  13. package/dist/types/cli/worktree-cli.d.ts +1 -1
  14. package/dist/types/commit/index.d.ts +1 -1
  15. package/dist/types/commit/pipeline.d.ts +1 -1
  16. package/dist/types/commit/types.d.ts +1 -1
  17. package/dist/types/config/prompt-templates.d.ts +1 -1
  18. package/dist/types/config/settings-schema.d.ts +16 -6
  19. package/dist/types/config.d.ts +7 -7
  20. package/dist/types/discovery/helpers.d.ts +8 -8
  21. package/dist/types/discovery/omp-extension-roots.d.ts +2 -2
  22. package/dist/types/eval/py/runtime.d.ts +1 -1
  23. package/dist/types/extensibility/custom-tools/loader.d.ts +2 -2
  24. package/dist/types/extensibility/extensions/loader.d.ts +1 -1
  25. package/dist/types/extensibility/hooks/loader.d.ts +1 -1
  26. package/dist/types/extensibility/plugins/loader.d.ts +2 -2
  27. package/dist/types/extensibility/plugins/types.d.ts +13 -3
  28. package/dist/types/lsp/config.d.ts +2 -2
  29. package/dist/types/mcp/client.d.ts +1 -1
  30. package/dist/types/mcp/config-writer.d.ts +1 -1
  31. package/dist/types/mcp/oauth-flow.d.ts +1 -1
  32. package/dist/types/mcp/transports/http.d.ts +1 -1
  33. package/dist/types/memories/okf.d.ts +36 -0
  34. package/dist/types/modes/components/__tests__/assistant-agent-label.test.d.ts +1 -0
  35. package/dist/types/modes/components/assistant-message.d.ts +4 -0
  36. package/dist/types/modes/interactive-mode.d.ts +1 -1
  37. package/dist/types/sdk.d.ts +5 -5
  38. package/dist/types/session/agent-session.d.ts +3 -0
  39. package/dist/types/session/auth-broker-config.d.ts +4 -4
  40. package/dist/types/session/snapcompact-savings-journal.d.ts +1 -1
  41. package/dist/types/task/commands.d.ts +1 -1
  42. package/dist/types/task/critic-gate.d.ts +76 -0
  43. package/dist/types/task/critic-gate.test.d.ts +1 -0
  44. package/dist/types/task/discovery.d.ts +1 -1
  45. package/dist/types/task/executor.d.ts +1 -1
  46. package/dist/types/tools/acp-bridge.d.ts +2 -2
  47. package/dist/types/tools/browser/tab-protocol.d.ts +1 -1
  48. package/dist/types/tools/index.d.ts +6 -1
  49. package/dist/types/tools/plan-mode-guard.d.ts +8 -0
  50. package/dist/types/tools/report-tool-issue.d.ts +1 -1
  51. package/dist/types/utils/changelog.d.ts +2 -2
  52. package/dist/types/utils/image-loading.d.ts +4 -4
  53. package/dist/types/utils/image-resize.d.ts +1 -1
  54. package/dist/types/web/search/index.d.ts +1 -1
  55. package/examples/custom-tools/README.md +1 -1
  56. package/examples/extensions/README.md +1 -1
  57. package/examples/extensions/pirate.ts +1 -1
  58. package/examples/extensions/plan-mode.ts +1 -1
  59. package/examples/extensions/tools.ts +1 -1
  60. package/examples/hooks/README.md +1 -1
  61. package/examples/sdk/01-minimal.ts +1 -1
  62. package/examples/sdk/04-skills.ts +1 -1
  63. package/examples/sdk/06-extensions.ts +3 -3
  64. package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
  65. package/examples/sdk/12-redis-sessions.ts +1 -1
  66. package/examples/sdk/13-sql-sessions.ts +1 -1
  67. package/examples/sdk/README.md +1 -1
  68. package/package.json +12 -12
  69. package/scripts/jeopi +1 -1
  70. package/src/advisor/__tests__/config.test.ts +4 -4
  71. package/src/advisor/watchdog.ts +8 -8
  72. package/src/autolearn/managed-skills.ts +4 -4
  73. package/src/autoresearch/storage.ts +2 -2
  74. package/src/capability/types.ts +2 -2
  75. package/src/cli/agents-cli.ts +2 -2
  76. package/src/cli/args.ts +3 -3
  77. package/src/cli/auth-broker-cli.ts +5 -5
  78. package/src/cli/auth-gateway-cli.ts +4 -4
  79. package/src/cli/claude-trace-cli.ts +1 -1
  80. package/src/cli/commands/migrate-legacy.ts +24 -0
  81. package/src/cli/config-cli.ts +20 -5
  82. package/src/cli/flag-tables.ts +1 -1
  83. package/src/cli/gallery-fixtures/misc.ts +7 -7
  84. package/src/cli/gallery-screenshot.ts +2 -2
  85. package/src/cli/grievances-cli.ts +1 -1
  86. package/src/cli/models-cli.ts +1 -1
  87. package/src/cli/plugin-cli.ts +2 -2
  88. package/src/cli/profile-alias.ts +8 -8
  89. package/src/cli/read-cli.ts +1 -1
  90. package/src/cli/ssh-cli.ts +2 -2
  91. package/src/cli/update-cli.ts +27 -27
  92. package/src/cli/worktree-cli.ts +3 -3
  93. package/src/cli.ts +5 -5
  94. package/src/commands/agents.ts +2 -2
  95. package/src/commands/auth-broker.ts +1 -1
  96. package/src/commands/config.ts +1 -1
  97. package/src/commands/dry-balance.ts +6 -6
  98. package/src/commands/launch.ts +2 -2
  99. package/src/commands/models.ts +1 -1
  100. package/src/commands/say.ts +1 -1
  101. package/src/commands/token.ts +5 -5
  102. package/src/commands/ttsr.ts +2 -2
  103. package/src/commands/worktree.ts +3 -3
  104. package/src/commit/agentic/prompts/system.md +1 -1
  105. package/src/commit/cli.ts +1 -1
  106. package/src/commit/index.ts +1 -1
  107. package/src/commit/pipeline.ts +1 -1
  108. package/src/commit/types.ts +1 -1
  109. package/src/config/mcp-schema.json +5 -5
  110. package/src/config/models-config-schema.ts +1 -1
  111. package/src/config/prompt-templates.ts +2 -2
  112. package/src/config/settings-schema.ts +20 -8
  113. package/src/config/settings.ts +1 -1
  114. package/src/config.ts +10 -10
  115. package/src/dap/session.ts +2 -2
  116. package/src/debug/protocol-probe.ts +1 -1
  117. package/src/debug/raw-sse-buffer.ts +3 -3
  118. package/src/debug/raw-sse.ts +2 -2
  119. package/src/discovery/builtin.ts +9 -9
  120. package/src/discovery/helpers.ts +13 -13
  121. package/src/discovery/omp-extension-roots.ts +4 -4
  122. package/src/discovery/omp-plugins.ts +2 -2
  123. package/src/discovery/substitute-plugin-root.ts +3 -3
  124. package/src/eval/py/runtime.ts +1 -1
  125. package/src/eval/rb/runner.rb +6 -6
  126. package/src/export/custom-share.ts +1 -1
  127. package/src/extensibility/custom-tools/loader.ts +3 -3
  128. package/src/extensibility/extensions/loader.ts +4 -4
  129. package/src/extensibility/hooks/loader.ts +1 -1
  130. package/src/extensibility/plugins/loader.ts +16 -10
  131. package/src/extensibility/plugins/manager.ts +10 -9
  132. package/src/extensibility/plugins/types.ts +15 -4
  133. package/src/internal-urls/docs-index.generated.txt +1 -1
  134. package/src/lsp/config.ts +4 -4
  135. package/src/lsp/index.ts +1 -1
  136. package/src/main.ts +1 -1
  137. package/src/mcp/client.ts +1 -1
  138. package/src/mcp/config-writer.ts +2 -2
  139. package/src/mcp/manager.ts +1 -1
  140. package/src/mcp/oauth-flow.ts +1 -1
  141. package/src/mcp/timeout.ts +2 -2
  142. package/src/mcp/transports/http.ts +1 -1
  143. package/src/memories/index.ts +82 -11
  144. package/src/memories/okf.ts +129 -0
  145. package/src/modes/components/__tests__/assistant-agent-label.test.ts +87 -0
  146. package/src/modes/components/assistant-message.ts +27 -0
  147. package/src/modes/components/extensions/extension-dashboard.ts +1 -1
  148. package/src/modes/controllers/mcp-command-controller.ts +2 -2
  149. package/src/modes/controllers/omfg-controller.ts +2 -2
  150. package/src/modes/controllers/ssh-command-controller.ts +2 -2
  151. package/src/modes/interactive-mode.ts +3 -1
  152. package/src/modes/setup-wizard/index.ts +1 -1
  153. package/src/prompts/agents/jeo.md +20 -10
  154. package/src/prompts/system/autolearn-guidance.md +2 -2
  155. package/src/prompts/system/system-prompt.md +10 -1
  156. package/src/prompts/tools/learn.md +1 -1
  157. package/src/prompts/tools/manage-skill.md +1 -1
  158. package/src/sdk.ts +8 -6
  159. package/src/secrets/index.ts +2 -2
  160. package/src/session/agent-session.ts +86 -6
  161. package/src/session/auth-broker-config.ts +6 -6
  162. package/src/session/snapcompact-savings-journal.ts +1 -1
  163. package/src/slash-commands/helpers/mcp.ts +1 -1
  164. package/src/system-prompt.test.ts +14 -14
  165. package/src/task/commands.ts +1 -1
  166. package/src/task/critic-gate.test.ts +181 -0
  167. package/src/task/critic-gate.ts +148 -0
  168. package/src/task/discovery.ts +5 -5
  169. package/src/task/executor.ts +1 -1
  170. package/src/task/index.ts +35 -2
  171. package/src/tools/acp-bridge.ts +2 -2
  172. package/src/tools/browser/launch.ts +1 -1
  173. package/src/tools/browser/tab-protocol.ts +1 -1
  174. package/src/tools/grep.ts +2 -2
  175. package/src/tools/index.ts +6 -1
  176. package/src/tools/plan-mode-guard.ts +16 -0
  177. package/src/tools/read.ts +1 -1
  178. package/src/tools/report-tool-issue.ts +2 -2
  179. package/src/utils/changelog.ts +2 -2
  180. package/src/utils/image-loading.ts +4 -4
  181. package/src/utils/image-resize.ts +5 -5
  182. package/src/web/search/index.ts +1 -1
@@ -31,7 +31,7 @@ export interface LoadResult<T> {
31
31
  * A provider that can load items for a capability.
32
32
  */
33
33
  export interface Provider<T> {
34
- /** Unique provider ID (e.g., "claude", "omp", "mcp-json", "agents-md") */
34
+ /** Unique provider ID (e.g., "claude", "jeopi", "mcp-json", "agents-md") */
35
35
  id: string;
36
36
 
37
37
  /** Human-readable name for UI display (e.g., "Claude Code", "OpenAI Codex") */
@@ -43,7 +43,7 @@ export interface Provider<T> {
43
43
  /**
44
44
  * Priority (higher = checked first, wins on conflicts).
45
45
  * Suggested ranges:
46
- * 100+ : Primary providers (omp, pi)
46
+ * 100+ : Primary providers (jeopi, pi)
47
47
  * 50-99: Tool-specific providers (claude, codex, gemini)
48
48
  * 1-49 : Shared standards (mcp-json, agents-md)
49
49
  */
@@ -7,7 +7,7 @@ import * as fs from "node:fs/promises";
7
7
  import * as path from "node:path";
8
8
  import { YAML } from "bun";
9
9
  import chalk from "chalk";
10
- import { getAgentDir, getProjectDir, isEnoent } from "jeopi-utils";
10
+ import { CONFIG_DIR_NAME, getAgentDir, getProjectDir, isEnoent } from "jeopi-utils";
11
11
  import { theme } from "../modes/theme/theme";
12
12
  import { loadBundledAgents } from "../task/agents";
13
13
  import type { AgentDefinition } from "../task/types";
@@ -46,7 +46,7 @@ function resolveTargetDir(flags: AgentsCommandArgs["flags"]): string {
46
46
  }
47
47
 
48
48
  if (flags.project) {
49
- return path.resolve(getProjectDir(), ".omp", "agents");
49
+ return path.resolve(getProjectDir(), CONFIG_DIR_NAME, "agents");
50
50
  }
51
51
 
52
52
  return path.join(getAgentDir(), "agents");
package/src/cli/args.ts CHANGED
@@ -349,7 +349,7 @@ export function getExtraHelpText(): string {
349
349
  ANTHROPIC_SEARCH_BASE_URL - Anthropic web search base URL (override; pairs with ANTHROPIC_SEARCH_API_KEY)
350
350
 
351
351
  ${chalk.dim("# Configuration")}
352
- OMP_PROFILE - Named profile for isolated agent state (same as --profile)
352
+ JEOPI_PROFILE - Named profile for isolated agent state (same as --profile)
353
353
  Use \`${APP_NAME} --profile <name> --alias <command>\` to create a shell shortcut for a profile
354
354
  PI_CODING_AGENT_DIR - Session storage directory (default: ~/${CONFIG_DIR_NAME}/agent)
355
355
  PI_PACKAGE_DIR - Override package directory (for Nix/Guix store paths)
@@ -380,8 +380,8 @@ ${chalk.bold("Plugin Options:")}
380
380
  --plugin-dir <path> Load plugin from directory (repeatable)
381
381
 
382
382
  ${chalk.bold("Useful Commands:")}
383
- jeopi agents unpack - Export bundled subagents to ~/.omp/agent/agents (default)
384
- jeopi agents unpack --project - Export bundled subagents to ./.omp/agents`;
383
+ jeopi agents unpack - Export bundled subagents to ~/.jeopi/agent/agents (default)
384
+ jeopi agents unpack --project - Export bundled subagents to ./.jeopi/agents`;
385
385
  }
386
386
 
387
387
  export function printHelp(): void {
@@ -122,7 +122,7 @@ async function ensureToken(): Promise<string> {
122
122
  async function runServe(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
123
123
  // The broker is a long-running headless service: route structured logs to
124
124
  // stdout so a process supervisor (pm2, journald, k8s) captures them, and
125
- // skip the rotating ~/.omp/logs/ file the TUI default would have used.
125
+ // skip the rotating ~/.jeopi/logs/ file the TUI default would have used.
126
126
  setLoggerTransports({ console: true, file: false });
127
127
 
128
128
  const bind = flags.bind ?? DEFAULT_AUTH_BROKER_BIND;
@@ -412,7 +412,7 @@ async function runList(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
412
412
  // ─── CLIProxyAPI import ─────────────────────────────────────────────────
413
413
 
414
414
  /**
415
- * Maps the `type` field of a CLIProxyAPI credential JSON to the omp provider id.
415
+ * Maps the `type` field of a CLIProxyAPI credential JSON to the jeopi provider id.
416
416
  * The filename also encodes the type (e.g. `claude-foo@bar.json`), but the
417
417
  * in-file `type` is authoritative — we only fall back to filename if absent.
418
418
  */
@@ -508,7 +508,7 @@ async function loadImportPlan(
508
508
  if (!provider) {
509
509
  skipped.push({
510
510
  file,
511
- reason: `cannot determine omp provider from type=${json.type ?? "?"} (pass --provider to override)`,
511
+ reason: `cannot determine jeopi provider from type=${json.type ?? "?"} (pass --provider to override)`,
512
512
  });
513
513
  continue;
514
514
  }
@@ -693,7 +693,7 @@ async function runMigrate(flags: AuthBrokerCommandArgs["flags"]): Promise<void>
693
693
  const brokerConfig = await resolveAuthBrokerConfig();
694
694
  if (!brokerConfig) {
695
695
  throw new Error(
696
- "OMP_AUTH_BROKER_URL must be set (or `auth.broker.url` in config.yml). `migrate` uploads local credentials to a configured broker.",
696
+ "JEOPI_AUTH_BROKER_URL must be set (or `auth.broker.url` in config.yml). `migrate` uploads local credentials to a configured broker.",
697
697
  );
698
698
  }
699
699
  if (flags.fromLocal !== true) {
@@ -846,7 +846,7 @@ async function runMigrate(flags: AuthBrokerCommandArgs["flags"]): Promise<void>
846
846
  async function runStatus(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
847
847
  const cfg = await resolveAuthBrokerConfig();
848
848
  if (!cfg) {
849
- const message = "No auth-broker configured (set OMP_AUTH_BROKER_URL to enable).";
849
+ const message = "No auth-broker configured (set JEOPI_AUTH_BROKER_URL to enable).";
850
850
  if (flags.json) process.stdout.write(`${JSON.stringify({ ok: false, reason: "not_configured" })}\n`);
851
851
  else process.stdout.write(`${chalk.yellow(message)}\n`);
852
852
  return;
@@ -5,7 +5,7 @@
5
5
  * usage widget, robomp containers, …) make provider API calls without ever
6
6
  * seeing the access token. The gateway is itself a broker client and
7
7
  * resolves credentials through the configured broker (via the same
8
- * `OMP_AUTH_BROKER_URL` / `auth.broker.url` precedence used elsewhere).
8
+ * `JEOPI_AUTH_BROKER_URL` / `auth.broker.url` precedence used elsewhere).
9
9
  *
10
10
  * Sub-verbs:
11
11
  * - `serve [--bind=…]` — boots the gateway against the configured broker.
@@ -139,7 +139,7 @@ async function runServe(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
139
139
  const brokerConfig = await resolveAuthBrokerConfig();
140
140
  if (!brokerConfig) {
141
141
  throw new Error(
142
- "`jeopi auth-gateway serve` requires OMP_AUTH_BROKER_URL (or `auth.broker.url`/`auth.broker.token` in config.yml). The gateway is itself a broker client.",
142
+ "`jeopi auth-gateway serve` requires JEOPI_AUTH_BROKER_URL (or `auth.broker.url`/`auth.broker.token` in config.yml). The gateway is itself a broker client.",
143
143
  );
144
144
  }
145
145
  const bind = flags.bind ?? DEFAULT_AUTH_GATEWAY_BIND;
@@ -266,7 +266,7 @@ async function runStatus(flags: AuthGatewayCommandArgs["flags"]): Promise<void>
266
266
  if (flags.json) {
267
267
  process.stdout.write(`${JSON.stringify(status)}\n`);
268
268
  } else {
269
- process.stdout.write(`${chalk.yellow("No broker configured.")} Set OMP_AUTH_BROKER_URL.\n`);
269
+ process.stdout.write(`${chalk.yellow("No broker configured.")} Set JEOPI_AUTH_BROKER_URL.\n`);
270
270
  process.stdout.write(
271
271
  `token: ${status.tokenPresent ? chalk.green("present") : chalk.red("missing")} at ${status.tokenFile}\n`,
272
272
  );
@@ -534,7 +534,7 @@ async function runCheck(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
534
534
  const brokerConfig = await resolveAuthBrokerConfig();
535
535
  if (!brokerConfig) {
536
536
  throw new Error(
537
- "`jeopi auth-gateway check` requires OMP_AUTH_BROKER_URL (or `auth.broker.url`/`auth.broker.token` in config.yml). It probes the same credentials the gateway would serve.",
537
+ "`jeopi auth-gateway check` requires JEOPI_AUTH_BROKER_URL (or `auth.broker.url`/`auth.broker.token` in config.yml). It probes the same credentials the gateway would serve.",
538
538
  );
539
539
  }
540
540
 
@@ -749,7 +749,7 @@ export async function runClaudeMessagesCapture(args: ClaudeTraceCommandArgs = {}
749
749
  try {
750
750
  session.write(`${message}\r`);
751
751
  } catch (error) {
752
- ptyOutput += `\n[omp input write failed: ${errorMessage(error)}]\n`;
752
+ ptyOutput += `\n[jeopi input write failed: ${errorMessage(error)}]\n`;
753
753
  }
754
754
  })();
755
755
  const captureRace = proxy.waitForCapture(timeoutMs).then(
@@ -0,0 +1,24 @@
1
+ import { APP_NAME, hasUnmigratedLegacyConfigDir, LEGACY_CONFIG_DIR_NAME, migrateLegacyConfigDir } from "jeopi-utils";
2
+
3
+ export async function migrateLegacyConfig(): Promise<void> {
4
+ if (process.env.PI_CONFIG_DIR) {
5
+ console.error(
6
+ "PI_CONFIG_DIR is set — you already control the config directory name; there is nothing to migrate.",
7
+ );
8
+ process.exit(1);
9
+ }
10
+
11
+ if (!hasUnmigratedLegacyConfigDir()) {
12
+ console.log(`No unmigrated ${LEGACY_CONFIG_DIR_NAME} directory found. Nothing to do.`);
13
+ return;
14
+ }
15
+
16
+ try {
17
+ const { from, to } = migrateLegacyConfigDir();
18
+ console.log(`Migrated ${from} -> ${to}`);
19
+ console.log(`${APP_NAME} now reads auth, sessions, and settings from ${to}.`);
20
+ } catch (err) {
21
+ console.error(err instanceof Error ? err.message : String(err));
22
+ process.exit(1);
23
+ }
24
+ }
@@ -21,12 +21,13 @@ import {
21
21
  import { SETTINGS_SCHEMA } from "../config/settings-schema";
22
22
  import { theme } from "../modes/theme/theme";
23
23
  import { initXdg } from "./commands/init-xdg";
24
+ import { migrateLegacyConfig } from "./commands/migrate-legacy";
24
25
 
25
26
  // =============================================================================
26
27
  // Types
27
28
  // =============================================================================
28
29
 
29
- export type ConfigAction = "list" | "get" | "set" | "reset" | "path" | "init-xdg";
30
+ export type ConfigAction = "list" | "get" | "set" | "reset" | "path" | "init-xdg" | "migrate-legacy";
30
31
 
31
32
  export interface ConfigCommandArgs {
32
33
  action: ConfigAction;
@@ -74,7 +75,7 @@ function getSettingValues(def: CliSettingDef): readonly string[] | undefined {
74
75
  // Argument Parser
75
76
  // =============================================================================
76
77
 
77
- const VALID_ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path", "init-xdg"];
78
+ const VALID_ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path", "init-xdg", "migrate-legacy"];
78
79
 
79
80
  /**
80
81
  * Parse config subcommand arguments.
@@ -237,6 +238,21 @@ function parseAndSetValue(path: SettingPath, rawValue: string): void {
237
238
  // =============================================================================
238
239
 
239
240
  export async function runConfigCommand(cmd: ConfigCommandArgs): Promise<void> {
241
+ // migrate-legacy and init-xdg are directory-bootstrapping operations that
242
+ // must run BEFORE Settings.init() touches the config root: Settings.init()
243
+ // opens AgentStorage (agent.db), which mkdir's the agent dir as a side
244
+ // effect. Running it first would silently create `~/.jeopi` ahead of the
245
+ // migration check, making `hasUnmigratedLegacyConfigDir()` always report
246
+ // "nothing to migrate" even when a real `~/.omp` install exists.
247
+ if (cmd.action === "migrate-legacy") {
248
+ await migrateLegacyConfig();
249
+ return;
250
+ }
251
+ if (cmd.action === "init-xdg") {
252
+ await initXdg();
253
+ return;
254
+ }
255
+
240
256
  await Settings.init();
241
257
 
242
258
  switch (cmd.action) {
@@ -255,9 +271,6 @@ export async function runConfigCommand(cmd: ConfigCommandArgs): Promise<void> {
255
271
  case "path":
256
272
  handlePath();
257
273
  break;
258
- case "init-xdg":
259
- await initXdg();
260
- break;
261
274
  }
262
275
  }
263
276
 
@@ -402,6 +415,7 @@ ${chalk.bold("Commands:")}
402
415
  reset <key> Reset a setting to its default value
403
416
  path Print the config directory path
404
417
  init-xdg Initialize XDG Base Directory structure
418
+ migrate-legacy Migrate ~/.omp to ~/.jeopi (pre-rebrand config directory)
405
419
 
406
420
  ${chalk.bold("Options:")}
407
421
  --json Output as JSON
@@ -415,6 +429,7 @@ ${chalk.bold("Examples:")}
415
429
  ${APP_NAME} config reset steeringMode
416
430
  ${APP_NAME} config list --json
417
431
  ${APP_NAME} config init-xdg
432
+ ${APP_NAME} config migrate-legacy
418
433
 
419
434
  ${chalk.bold("Boolean Values:")}
420
435
  true, false, yes, no, on, off, 1, 0
@@ -247,7 +247,7 @@ export const OPTIONAL_VALUE_FLAGS: ReadonlySet<string> = new Set(Object.keys(OPT
247
247
  * value of a preceding optional/extension flag. `parseArgs` ignores it, but its
248
248
  * flag-looking shape preserves argv boundaries during the second parse.
249
249
  */
250
- export const PROFILE_BOOTSTRAP_BOUNDARY_ARG = "--omp-profile-boundary";
250
+ export const PROFILE_BOOTSTRAP_BOUNDARY_ARG = "--jeopi-profile-boundary";
251
251
 
252
252
  /**
253
253
  * Long-form launch flags that take NO value (booleans). The bootstrap pre-parser
@@ -110,8 +110,8 @@ export const miscFixtures: Record<string, GalleryFixture> = {
110
110
  },
111
111
  args: {
112
112
  host: "deploy@web-01",
113
- command: "systemctl status omp-api --no-pager | head -n 12",
114
- cwd: "/srv/omp",
113
+ command: "systemctl status jeopi-api --no-pager | head -n 12",
114
+ cwd: "/srv/jeopi",
115
115
  timeout: 60,
116
116
  },
117
117
  result: {
@@ -119,14 +119,14 @@ export const miscFixtures: Record<string, GalleryFixture> = {
119
119
  {
120
120
  type: "text",
121
121
  text: [
122
- "● omp-api.service - Oh My Pi API",
123
- " Loaded: loaded (/etc/systemd/system/omp-api.service; enabled)",
122
+ "● jeopi-api.service - jeopi API",
123
+ " Loaded: loaded (/etc/systemd/system/jeopi-api.service; enabled)",
124
124
  " Active: active (running) since Sat 2026-06-06 09:14:02 UTC; 3h 21min ago",
125
125
  " Main PID: 4812 (bun)",
126
126
  " Tasks: 17 (limit: 4915)",
127
127
  " Memory: 142.6M",
128
128
  " CPU: 38.214s",
129
- " CGroup: /system.slice/omp-api.service",
129
+ " CGroup: /system.slice/jeopi-api.service",
130
130
  " └─4812 /usr/local/bin/bun run dist/server.js",
131
131
  ].join("\n"),
132
132
  },
@@ -152,7 +152,7 @@ export const miscFixtures: Record<string, GalleryFixture> = {
152
152
  args: {
153
153
  op: "search_prs",
154
154
  query: "is:open review-requested:@me sort:updated",
155
- repo: "oh-my-pi/pi",
155
+ repo: "akillness/jeopi",
156
156
  },
157
157
  result: {
158
158
  content: [
@@ -173,7 +173,7 @@ export const miscFixtures: Record<string, GalleryFixture> = {
173
173
  content: [
174
174
  {
175
175
  type: "text",
176
- text: "gh: Could not resolve to a Repository with the name 'oh-my-pi/pi'. (HTTP 404)",
176
+ text: "gh: Could not resolve to a Repository with the name 'akillness/jeopi'. (HTTP 404)",
177
177
  },
178
178
  ],
179
179
  isError: true,
@@ -77,7 +77,7 @@ export async function captureGalleryScreenshots(
77
77
 
78
78
  const baseDir = options.out
79
79
  ? path.dirname(path.resolve(options.out))
80
- : fs.mkdtempSync(path.join(os.tmpdir(), "omp-gallery-"));
80
+ : fs.mkdtempSync(path.join(os.tmpdir(), "jeopi-gallery-"));
81
81
  await fs.promises.mkdir(baseDir, { recursive: true });
82
82
 
83
83
  const outPaths: string[] = [];
@@ -194,7 +194,7 @@ function buildVhsTheme(): string {
194
194
  const foreground = theme.isLight ? "#1a1a1a" : "#d4d4d4";
195
195
  const selection = theme.isLight ? "#c8d6ff" : "#404862";
196
196
  return JSON.stringify({
197
- name: "omp-gallery",
197
+ name: "jeopi-gallery",
198
198
  background,
199
199
  foreground,
200
200
  cursor: foreground,
@@ -195,7 +195,7 @@ function makeProgressBar(total: number, width = 30): ProgressBar {
195
195
  * ignoring the user-facing consent gate (manual push is the user's
196
196
  * explicit "yes ship these now" intent).
197
197
  *
198
- * Requires endpoint configuration (default `qa.omp.sh/v1/grievances`).
198
+ * Requires endpoint configuration (default `qa.jeopi.sh/v1/grievances`).
199
199
  */
200
200
  export async function pushGrievances(options: PushGrievancesOptions): Promise<void> {
201
201
  const db = openAutoQaDb();
@@ -5,7 +5,7 @@
5
5
  * - `ls` (default): list every available model grouped by provider.
6
6
  * - `find <substring>`: list models whose provider, id, or name contains the substring.
7
7
  * - `refresh`: force an online catalog re-fetch (ignoring the model cache TTL),
8
- * then list. This is the supported replacement for `rm -rf ~/.omp/models.db`
8
+ * then list. This is the supported replacement for `rm -rf ~/.jeopi/models.db`
9
9
  * when a provider ships a new model that the 24h cache has not picked up yet.
10
10
  *
11
11
  * `ls`/`find` use the cache when fresh (`online-if-uncached`); only `refresh`
@@ -350,7 +350,7 @@ async function handleInstall(
350
350
  if (packages.length === 0) {
351
351
  console.error(chalk.red(`Usage: ${APP_NAME} plugin install <source>[features] ...`));
352
352
  console.error(chalk.dim("Examples:"));
353
- console.error(chalk.dim(` ${APP_NAME} plugin install @oh-my-pi/exa`));
353
+ console.error(chalk.dim(` ${APP_NAME} plugin install @jeopi/exa`));
354
354
  console.error(chalk.dim(` ${APP_NAME} plugin install name@marketplace`));
355
355
  console.error(chalk.dim(` ${APP_NAME} plugin install github:user/repo`));
356
356
  console.error(chalk.dim(` ${APP_NAME} plugin install https://github.com/user/repo#v1.0`));
@@ -985,7 +985,7 @@ ${chalk.bold("Options:")}
985
985
  -l, --local Use project-local overrides
986
986
 
987
987
  ${chalk.bold("Examples:")}
988
- ${APP_NAME} plugin install @oh-my-pi/exa[search]
988
+ ${APP_NAME} plugin install @jeopi/exa[search]
989
989
  ${APP_NAME} plugin list --json
990
990
  ${APP_NAME} plugin features my-plugin --enable search,web
991
991
  ${APP_NAME} plugin config set my-plugin apiKey sk-xxx
@@ -147,8 +147,8 @@ function validateAliasName(aliasName: string, shell: ProfileAliasShell): string
147
147
  if (!ALIAS_NAME_RE.test(normalized)) {
148
148
  throw new Error(`Invalid alias "${aliasName}". Alias names must match ${ALIAS_NAME_RE.source}.`);
149
149
  }
150
- if (normalized.toLowerCase() === "omp") {
151
- throw new Error('Invalid alias "omp". Refusing to shadow the base omp command.');
150
+ if (normalized.toLowerCase() === "jeopi") {
151
+ throw new Error('Invalid alias "jeopi". Refusing to shadow the base jeopi command.');
152
152
  }
153
153
  if (getReservedAliasNames(shell).has(normalized.toLowerCase())) {
154
154
  throw new Error(`Invalid alias "${aliasName}". Refusing to create a ${shell} reserved word.`);
@@ -254,7 +254,7 @@ function resolveShellConfigPath(
254
254
  // a hard-coded ~/.config would be silently ignored when the user relocates
255
255
  // their XDG config root, leaving the alias unsourced after a restart.
256
256
  const configHome = env.XDG_CONFIG_HOME ? toPosix(env.XDG_CONFIG_HOME) : posixJoinUnc(posixHome, ".config");
257
- return posixJoinUnc(configHome, "fish", "conf.d", "omp-profiles.fish");
257
+ return posixJoinUnc(configHome, "fish", "conf.d", "jeopi-profiles.fish");
258
258
  }
259
259
  case "pwsh":
260
260
  return platform === "win32"
@@ -272,13 +272,13 @@ function renderAliasBlock(
272
272
  command: ProfileAliasCommand,
273
273
  ): { block: string; command: string } {
274
274
  const profiledCommand = `${command.display} --profile=${profile}`;
275
- const start = `# >>> omp profile alias: ${aliasName} >>>`;
276
- const end = `# <<< omp profile alias: ${aliasName} <<<`;
275
+ const start = `# >>> jeopi profile alias: ${aliasName} >>>`;
276
+ const end = `# <<< jeopi profile alias: ${aliasName} <<<`;
277
277
  let body: string;
278
278
  switch (shell) {
279
279
  case "fish":
280
280
  body = [
281
- `function ${aliasName} --wraps jeopi --description 'OMP profile ${profile}'`,
281
+ `function ${aliasName} --wraps jeopi --description 'jeopi profile ${profile}'`,
282
282
  ` command ${command.fish} --profile=${profile} $argv`,
283
283
  "end",
284
284
  ].join("\n");
@@ -295,8 +295,8 @@ function renderAliasBlock(
295
295
  }
296
296
 
297
297
  function upsertBlock(content: string, aliasName: string, block: string): string {
298
- const start = `# >>> omp profile alias: ${aliasName} >>>`;
299
- const end = `# <<< omp profile alias: ${aliasName} <<<`;
298
+ const start = `# >>> jeopi profile alias: ${aliasName} >>>`;
299
+ const end = `# <<< jeopi profile alias: ${aliasName} <<<`;
300
300
  const startIndex = content.indexOf(start);
301
301
  if (startIndex !== -1) {
302
302
  const endIndex = content.indexOf(end, startIndex + start.length);
@@ -38,7 +38,7 @@ export async function runReadCommand(cmd: ReadCommandArgs): Promise<void> {
38
38
  const tool = wrapToolWithMetaNotice(new ReadTool(session));
39
39
 
40
40
  try {
41
- const result = await tool.execute("omp-read", { path: cmd.path });
41
+ const result = await tool.execute("jeopi-read", { path: cmd.path });
42
42
 
43
43
  for (const block of result.content) {
44
44
  if (block.type === "text") {
@@ -149,7 +149,7 @@ async function handleList(cmd: SSHCommandArgs): Promise<void> {
149
149
  }
150
150
 
151
151
  if (hasProject) {
152
- process.stdout.write(chalk.bold("Project SSH Hosts (.omp/ssh.json):\n"));
152
+ process.stdout.write(chalk.bold("Project SSH Hosts (.jeopi/ssh.json):\n"));
153
153
  printHosts(projectHosts);
154
154
  }
155
155
 
@@ -158,7 +158,7 @@ async function handleList(cmd: SSHCommandArgs): Promise<void> {
158
158
  }
159
159
 
160
160
  if (hasUser) {
161
- process.stdout.write(chalk.bold("User SSH Hosts (~/.omp/agent/ssh.json):\n"));
161
+ process.stdout.write(chalk.bold("User SSH Hosts (~/.jeopi/agent/ssh.json):\n"));
162
162
  printHosts(userHosts);
163
163
  }
164
164
  }
@@ -2,7 +2,7 @@
2
2
  * Update CLI command handler.
3
3
  *
4
4
  * Handles `jeopi update` to check for and install updates.
5
- * Uses the installer that owns the active omp executable when it can be detected.
5
+ * Uses the installer that owns the active jeopi executable when it can be detected.
6
6
  */
7
7
  import * as fs from "node:fs";
8
8
  import * as os from "node:os";
@@ -14,7 +14,7 @@ import { $which, APP_NAME, isEnoent, VERSION } from "jeopi-utils";
14
14
  import { theme } from "../modes/theme/theme";
15
15
 
16
16
  const REPO = "akillness/jeopi";
17
- const PACKAGE = "jeopi";
17
+ const PACKAGE = "jeopi-cli";
18
18
  const HOMEBREW_FORMULA = "akillness/tap/jeopi";
19
19
  const MISE_TOOL = "github:akillness/jeopi";
20
20
  /**
@@ -170,10 +170,10 @@ function isPathInDirectory(filePath: string, directoryPath: string): boolean {
170
170
  if (isPathInDirectoryLexical(filePath, directoryPath)) return true;
171
171
  // Layer realpath resolution on top of the lexical guard. On Windows, ~/.bun
172
172
  // is a junction when Bun is installed via Scoop, so `bun pm bin -g` and the
173
- // PATH-resolved omp path can refer to the same directory through different
173
+ // PATH-resolved jeopi path can refer to the same directory through different
174
174
  // strings. path.resolve does not traverse junctions/symlinks; realpath does.
175
175
  // Resolve both the file and its parent directory: the file catches manager
176
- // links like Homebrew's `bin/omp -> Cellar/.../bin/omp`; the parent fallback
176
+ // links like Homebrew's `bin/jeopi -> Cellar/.../bin/jeopi`; the parent fallback
177
177
  // still tolerates fresh install paths where the file does not exist yet.
178
178
  const dirReal = tryRealpath(path.resolve(directoryPath));
179
179
  if (!dirReal) return false;
@@ -196,24 +196,24 @@ interface UpdateMethodResolutionOptions {
196
196
  type UpdateTarget = { method: "brew" } | { method: "mise" } | { method: "bun" } | { method: "binary"; path: string };
197
197
 
198
198
  function resolveUpdateMethod(
199
- ompPath: string,
199
+ jeopiPath: string,
200
200
  bunBinDir: string | undefined,
201
201
  options: UpdateMethodResolutionOptions = {},
202
202
  ): UpdateMethod {
203
203
  const { homebrewPrefix, miseBinDirs = [], miseDataDir } = options;
204
- if (homebrewPrefix && isPathInDirectory(ompPath, path.join(homebrewPrefix, "bin"))) return "brew";
205
- if (miseBinDirs.some(dir => isPathInDirectory(ompPath, dir))) return "mise";
206
- if (miseDataDir && isPathInDirectory(ompPath, path.join(miseDataDir, "shims"))) return "mise";
207
- if (bunBinDir && isPathInDirectory(ompPath, bunBinDir)) return "bun";
204
+ if (homebrewPrefix && isPathInDirectory(jeopiPath, path.join(homebrewPrefix, "bin"))) return "brew";
205
+ if (miseBinDirs.some(dir => isPathInDirectory(jeopiPath, dir))) return "mise";
206
+ if (miseDataDir && isPathInDirectory(jeopiPath, path.join(miseDataDir, "shims"))) return "mise";
207
+ if (bunBinDir && isPathInDirectory(jeopiPath, bunBinDir)) return "bun";
208
208
  return "binary";
209
209
  }
210
210
 
211
211
  export function resolveUpdateMethodForTest(
212
- ompPath: string,
212
+ jeopiPath: string,
213
213
  bunBinDir: string | undefined,
214
214
  options: UpdateMethodResolutionOptions = {},
215
215
  ): UpdateMethod {
216
- return resolveUpdateMethod(ompPath, bunBinDir, options);
216
+ return resolveUpdateMethod(jeopiPath, bunBinDir, options);
217
217
  }
218
218
  async function resolveUpdateTarget(): Promise<UpdateTarget> {
219
219
  const bunBinDir = await getBunGlobalBinDir();
@@ -221,11 +221,11 @@ async function resolveUpdateTarget(): Promise<UpdateTarget> {
221
221
  const miseAvailable = $which("mise") !== undefined;
222
222
  const miseBinDirs = miseAvailable ? await getMiseBinDirs() : [];
223
223
  const miseDataDir = miseAvailable ? getMiseDataDir() : undefined;
224
- const ompPath = resolveOmpPath();
224
+ const jeopiPath = resolveJeopiPath();
225
225
 
226
- if (ompPath) {
227
- const method = resolveUpdateMethod(ompPath, bunBinDir, { homebrewPrefix, miseBinDirs, miseDataDir });
228
- if (method === "binary") return { method, path: ompPath };
226
+ if (jeopiPath) {
227
+ const method = resolveUpdateMethod(jeopiPath, bunBinDir, { homebrewPrefix, miseBinDirs, miseDataDir });
228
+ if (method === "binary") return { method, path: jeopiPath };
229
229
  return { method };
230
230
  }
231
231
 
@@ -514,7 +514,7 @@ async function pruneBunCacheAfterGlobalInstall(): Promise<BunInstallCachePruneRe
514
514
  const packageNames = globalNodeModulesDir
515
515
  ? await collectInstalledPackageNames(globalNodeModulesDir)
516
516
  : new Set<string>();
517
- if (packageNames.size === 0 && !path.basename(cacheDir).toLowerCase().includes("omp")) return undefined;
517
+ if (packageNames.size === 0 && !path.basename(cacheDir).toLowerCase().includes("jeopi")) return undefined;
518
518
  return await pruneBunInstallCache(cacheDir, packageNames.size === 0 ? undefined : packageNames);
519
519
  }
520
520
 
@@ -561,26 +561,26 @@ function getBinaryName(): string {
561
561
  /**
562
562
  * Resolve the path that `jeopi` maps to in the user's PATH.
563
563
  */
564
- function resolveOmpPath(): string | undefined {
564
+ function resolveJeopiPath(): string | undefined {
565
565
  return $which(APP_NAME) ?? undefined;
566
566
  }
567
567
 
568
568
  /**
569
- * Run the resolved omp binary and check if it reports the expected version.
569
+ * Run the resolved jeopi binary and check if it reports the expected version.
570
570
  */
571
571
  async function verifyInstalledVersion(expectedVersion: string): Promise<InstalledVersionVerification> {
572
- const ompPath = resolveOmpPath();
573
- if (!ompPath) return { ok: false };
572
+ const jeopiPath = resolveJeopiPath();
573
+ if (!jeopiPath) return { ok: false };
574
574
  try {
575
- const result = await $`${ompPath} --version`.quiet().nothrow();
576
- if (result.exitCode !== 0) return { ok: false, path: ompPath };
575
+ const result = await $`${jeopiPath} --version`.quiet().nothrow();
576
+ if (result.exitCode !== 0) return { ok: false, path: jeopiPath };
577
577
  const output = result.text().trim();
578
- // Output format: "omp/X.Y.Z"
578
+ // Output format: "jeopi/X.Y.Z"
579
579
  const match = output.match(/\/(\d+\.\d+\.\d+)/);
580
580
  const actual = match?.[1];
581
- return { ok: actual === expectedVersion, actual, path: ompPath };
581
+ return { ok: actual === expectedVersion, actual, path: jeopiPath };
582
582
  } catch {
583
- return { ok: false, path: ompPath };
583
+ return { ok: false, path: jeopiPath };
584
584
  }
585
585
  }
586
586
 
@@ -702,7 +702,7 @@ export async function replaceBinaryForUpdate(options: BinaryReplacementOptions):
702
702
  }
703
703
 
704
704
  /**
705
- * Build the bun argv used to globally install a specific omp version.
705
+ * Build the bun argv used to globally install a specific jeopi version.
706
706
  *
707
707
  * The version is selected by hitting {@link NPM_REGISTRY} directly in
708
708
  * {@link getLatestRelease}, so the install MUST observe the same catalog:
@@ -886,7 +886,7 @@ export async function runUpdateCommand(opts: { force: boolean; check: boolean })
886
886
  return;
887
887
  }
888
888
 
889
- // Choose update method based on the prioritized omp binary in PATH
889
+ // Choose update method based on the prioritized jeopi binary in PATH
890
890
  try {
891
891
  const target = await resolveUpdateTarget();
892
892
  if (target.method === "brew") {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * CLI handler for `jeopi worktree` — list and clean up agent-managed worktrees.
3
3
  *
4
- * Layout under `~/.omp/wt/`:
4
+ * Layout under `~/.jeopi/wt/`:
5
5
  *
6
6
  * - **PR-checkout worktrees** (`tools/gh.ts`): a regular git worktree dir
7
7
  * containing a `.git` *file* that points back at
@@ -25,7 +25,7 @@ type WorktreeKind = "pr-checkout" | "task-isolation" | "empty" | "stray";
25
25
  const TASK_ISOLATION_MOUNT_DIRS = ["m", "merged"] as const;
26
26
 
27
27
  export interface WorktreeEntry {
28
- /** Absolute path to the worktree dir (or stray container) under `~/.omp/wt/`. */
28
+ /** Absolute path to the worktree dir (or stray container) under `~/.jeopi/wt/`. */
29
29
  path: string;
30
30
  /** Classification of what we found on disk. */
31
31
  kind: WorktreeKind;
@@ -176,7 +176,7 @@ async function scanWorktrees(): Promise<WorktreeEntry[]> {
176
176
  continue;
177
177
  }
178
178
 
179
- // Legacy nesting: ~/.omp/wt/<encoded-project>/<branch-or-id>
179
+ // Legacy nesting: ~/.jeopi/wt/<encoded-project>/<branch-or-id>
180
180
  let children: string[];
181
181
  try {
182
182
  children = await fs.readdir(dir);
package/src/cli.ts CHANGED
@@ -229,20 +229,20 @@ export async function runCli(argv: string[]): Promise<void> {
229
229
  if (extracted.profile !== undefined) {
230
230
  setProfile(extracted.profile);
231
231
  } else {
232
- // No explicit --profile: activate any OMP_PROFILE/PI_PROFILE inherited
232
+ // No explicit --profile: activate any JEOPI_PROFILE/PI_PROFILE inherited
233
233
  // from the environment. Module-load resolution deliberately swallows an
234
234
  // invalid value to avoid an uncaught throw before this try/catch is in
235
235
  // scope (see `readProfileFromEnvSafe` in dirs.ts), and callers may set
236
- // OMP_PROFILE after importing this module (profile aliases/tests). Surfacing
237
- // validation here turns `OMP_PROFILE=.. jeopi --version` into a clean error;
236
+ // JEOPI_PROFILE after importing this module (profile aliases/tests). Surfacing
237
+ // validation here turns `JEOPI_PROFILE=.. jeopi --version` into a clean error;
238
238
  // calling setProfile keeps every later path helper on the env-selected
239
239
  // profile instead of the default agent directory.
240
- setProfile(resolveProfileEnv(process.env.OMP_PROFILE, process.env.PI_PROFILE));
240
+ setProfile(resolveProfileEnv(process.env.JEOPI_PROFILE, process.env.PI_PROFILE));
241
241
  }
242
242
  if (extracted.aliasName !== undefined) {
243
243
  const profile = extracted.profile ?? getActiveProfile();
244
244
  if (!profile) {
245
- throw new Error("--alias requires --profile <name> or OMP_PROFILE");
245
+ throw new Error("--alias requires --profile <name> or JEOPI_PROFILE");
246
246
  }
247
247
  const result = await installProfileAlias({
248
248
  profile,
@@ -23,8 +23,8 @@ export default class Agents extends Command {
23
23
  force: Flags.boolean({ char: "f", description: "Overwrite existing agent files" }),
24
24
  json: Flags.boolean({ description: "Output JSON" }),
25
25
  dir: Flags.string({ description: "Output directory (overrides --user/--project)" }),
26
- user: Flags.boolean({ description: "Write to ~/.omp/agent/agents (default)" }),
27
- project: Flags.boolean({ description: "Write to ./.omp/agents" }),
26
+ user: Flags.boolean({ description: "Write to ~/.jeopi/agent/agents (default)" }),
27
+ project: Flags.boolean({ description: "Write to ./.jeopi/agents" }),
28
28
  };
29
29
 
30
30
  static examples = [