ethos-cli 0.6.0 → 0.7.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.
@@ -3,7 +3,7 @@ import { resolveAgentClientId } from "../lib/agent-clients.js";
3
3
  import { withClient } from "../lib/command-helpers.js";
4
4
  import { isJsonMode } from "../lib/config.js";
5
5
  import { createFindPeopleHandoff } from "../lib/find-people-flow.js";
6
- import { ALL_HOOK_AGENTS, detectHookAgents, installEagerOpenHook, parseHookAgents, uninstallEagerOpenHook, } from "../lib/hooks-installer.js";
6
+ import { installEagerOpenHook, uninstallEagerOpenHook } from "../lib/hooks-installer.js";
7
7
  import { openInBrowser } from "../lib/open-browser.js";
8
8
  import { printResult } from "../lib/output.js";
9
9
  const SKILL = "find-people-at-companies";
@@ -25,21 +25,20 @@ export function matchesEagerOpenTrigger(prompt) {
25
25
  function registerEagerOpen(hooks) {
26
26
  const eagerOpen = hooks
27
27
  .command("eager-open")
28
- .description(`${HOOK_EVENT} hook handler: when the ${SKILL} skill is invoked, pre-open the upload browser and inject the started handoff for the skill to reuse`);
28
+ .description(`${HOOK_EVENT} hook handler (Claude Code): when the ${SKILL} skill is invoked, pre-open the upload browser and inject the started handoff for the skill to reuse`);
29
29
  eagerOpen.action(async () => {
30
30
  try {
31
31
  const prompt = readHookPrompt();
32
32
  if (!matchesEagerOpenTrigger(prompt))
33
33
  return; // not this skill - leave the prompt untouched
34
+ // Codex's upload is its agent-driven in-app Browser, which this hook can't
35
+ // open; the skill drives Codex, so the hook is a no-op there.
36
+ if (resolveAgentClientId("auto") === "codex")
37
+ return;
34
38
  await withClient(eagerOpen, async (client, config) => {
35
- const clientId = resolveAgentClientId("auto");
36
- const handoff = await createFindPeopleHandoff(client, config, { agentClient: clientId });
37
- // Codex uploads in its in-app Browser, a surface only the agent can open;
38
- // the OS opener would surface the wrong window. So only shell clients
39
- // (Claude Code) open here — on Codex we inject the URL for the agent to open.
40
- if (clientId !== "codex")
41
- openInBrowser(handoff.handoff_url);
42
- emitAdditionalContext(eagerOpenContext(handoff, clientId));
39
+ const handoff = await createFindPeopleHandoff(client, config, { agentClient: "claude-desktop" });
40
+ openInBrowser(handoff.handoff_url);
41
+ emitAdditionalContext(eagerOpenContext(handoff));
43
42
  });
44
43
  }
45
44
  catch {
@@ -61,14 +60,10 @@ function readHookPrompt() {
61
60
  return "";
62
61
  }
63
62
  }
64
- function eagerOpenContext(handoff, clientId) {
63
+ function eagerOpenContext(handoff) {
65
64
  const workspace = handoff.org_name ? ` in workspace "${handoff.org_name}"` : "";
66
- // Codex can't be OS-opened by the hook, so tell the agent to open it in-app;
67
- // Claude Code's OS browser is already opening.
68
- const lead = clientId === "codex"
69
- ? `Ethos find-people: a CSV upload flow is ready${workspace}. Open ${handoff.upload_url} in your in-app Browser`
70
- : `Ethos find-people: the CSV upload browser is already opening${workspace} (pre-started by a hook)`;
71
- return (`${lead}. Reuse this flow when running the ${SKILL} skill - do NOT run \`ethos flows start\` again. ` +
65
+ return (`Ethos find-people: the CSV upload browser is already opening${workspace} (pre-started by a hook). ` +
66
+ `Reuse this flow when running the ${SKILL} skill - do NOT run \`ethos flows start\` again. ` +
72
67
  `handoff_token=${handoff.handoff_token}. ` +
73
68
  `Next: ask the user for their ICP and buying-signal brief while they upload, then run ` +
74
69
  `\`ethos flows wait ${handoff.handoff_token} --json\` to capture the uploaded table id.`);
@@ -81,33 +76,28 @@ function emitAdditionalContext(additionalContext) {
81
76
  function registerInstall(hooks) {
82
77
  const install = hooks
83
78
  .command("install")
84
- .description("Register the find-people eager-open UserPromptSubmit hook in your agent config(s)")
85
- .option("-a, --agents <list>", `comma-separated agents (default: auto-detect). Supported: ${ALL_HOOK_AGENTS.join(", ")}`);
79
+ .description("Register the find-people eager-open UserPromptSubmit hook in Claude Code (and prune any legacy Codex hook)");
86
80
  install.action(async () => {
87
- const agents = parseHookAgents(install.opts().agents) ?? detectHookAgents();
88
- const { command, results } = await installEagerOpenHook({ agents });
81
+ const { command, claude, codexPruned } = await installEagerOpenHook();
82
+ const notes = [`Claude Code: ${claude.action} (${claude.path})`];
83
+ if (codexPruned.action === "removed")
84
+ notes.push(`removed legacy Codex hook (${codexPruned.path})`);
89
85
  printHooksResult(install, {
90
- label: results.length
91
- ? `Eager-open hook installed for ${results.map((entry) => entry.agent).join(", ")} (command: ${command})`
92
- : "No supported agents detected (claude-code, codex). Install an agent, then run `ethos hooks install`.",
93
- data: { command, agents: results },
86
+ label: `Eager-open hook ${claude.action} for Claude Code (command: ${command})`,
87
+ data: { command, claude, codex_pruned: codexPruned, notes },
94
88
  });
95
89
  });
96
90
  }
97
91
  function registerUninstall(hooks) {
98
92
  const uninstall = hooks
99
93
  .command("uninstall")
100
- .description("Remove the find-people eager-open hook from your agent config(s)")
101
- .option("-a, --agents <list>", `comma-separated agents (default: all). Supported: ${ALL_HOOK_AGENTS.join(", ")}`);
94
+ .description("Remove the find-people eager-open hook from Claude Code (and any legacy Codex hook)");
102
95
  uninstall.action(async () => {
103
- const agents = parseHookAgents(uninstall.opts().agents);
104
- const { results } = await uninstallEagerOpenHook({ agents });
105
- const removed = results.reduce((total, entry) => total + entry.removed, 0);
96
+ const { claude, codex } = await uninstallEagerOpenHook();
97
+ const removed = [claude, codex].filter((entry) => entry.action === "removed");
106
98
  printHooksResult(uninstall, {
107
- label: removed
108
- ? `Removed the eager-open hook from ${results.filter((entry) => entry.removed).map((entry) => entry.agent).join(", ")}`
109
- : "Nothing to remove.",
110
- data: { agents: results },
99
+ label: removed.length ? `Removed the eager-open hook from ${removed.map((entry) => entry.path).join(", ")}` : "Nothing to remove.",
100
+ data: { claude, codex },
111
101
  });
112
102
  });
113
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"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"}
@@ -1,39 +1,23 @@
1
- export type HookAgentName = "claude-code" | "codex";
2
- export interface HookAgent {
3
- name: HookAgentName;
4
- displayName: string;
5
- settingsFile(): string;
6
- detect(): boolean;
7
- }
8
- export declare const HOOK_AGENTS: Record<HookAgentName, HookAgent>;
9
- export declare const ALL_HOOK_AGENTS: HookAgentName[];
10
- export type HookInstallResult = {
11
- agent: HookAgentName;
1
+ export type HookFileResult = {
12
2
  path: string;
13
- action: "installed" | "updated";
14
- };
15
- export type HookRemoveResult = {
16
- agent: HookAgentName;
17
- path: string;
18
- removed: number;
3
+ action: "installed" | "updated" | "removed" | "absent";
19
4
  };
5
+ export declare function claudeCodeDetected(): boolean;
6
+ export declare function claudeSettingsPath(): string;
20
7
  /**
21
8
  * The command the hook runs. Bound to whichever CLI installs it: the dev CLI
22
9
  * sets ETHOS_CLI_COMMAND (so `make dev` points the hook at localhost), while a
23
10
  * normal `npm install` / global run has it unset and binds to prod `ethos`.
24
11
  */
25
12
  export declare function eagerOpenCommand(): string;
26
- export declare function detectHookAgents(): HookAgentName[];
27
13
  export declare function installEagerOpenHook(options?: {
28
- agents?: HookAgentName[];
29
14
  command?: string;
30
15
  }): Promise<{
31
16
  command: string;
32
- results: HookInstallResult[];
17
+ claude: HookFileResult;
18
+ codexPruned: HookFileResult;
33
19
  }>;
34
- export declare function uninstallEagerOpenHook(options?: {
35
- agents?: HookAgentName[];
36
- }): Promise<{
37
- results: HookRemoveResult[];
20
+ export declare function uninstallEagerOpenHook(): Promise<{
21
+ claude: HookFileResult;
22
+ codex: HookFileResult;
38
23
  }>;
39
- export declare function parseHookAgents(value: string | undefined): HookAgentName[] | undefined;
@@ -2,25 +2,23 @@ import { existsSync } from "node:fs";
2
2
  import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
3
3
  import { homedir } from "node:os";
4
4
  import { dirname, join } from "node:path";
5
- export const HOOK_AGENTS = {
6
- "claude-code": {
7
- name: "claude-code",
8
- displayName: "Claude Code",
9
- settingsFile: () => join(process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude"), "settings.json"),
10
- detect: () => existsSync(process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude")),
11
- },
12
- codex: {
13
- name: "codex",
14
- displayName: "Codex",
15
- settingsFile: () => join(process.env.CODEX_HOME || join(homedir(), ".codex"), "hooks.json"),
16
- detect: () => existsSync(process.env.CODEX_HOME || join(homedir(), ".codex")),
17
- },
18
- };
19
- export const ALL_HOOK_AGENTS = Object.keys(HOOK_AGENTS);
5
+ // The eager-open hook is Claude Code only. On Codex the CSV upload happens in its
6
+ // agent-driven in-app Browser, which a hook cannot open, so a Codex hook would
7
+ // only create a duplicate handoff — the find-people skill drives Codex itself.
8
+ // ethos-cli <= 0.6.0 also installed a Codex hook; install prunes that legacy file.
20
9
  const HOOK_EVENT = "UserPromptSubmit";
21
10
  // Substring identifying our handler, so install/uninstall stay idempotent and
22
- // migrate older bindings (e.g. a dev-CLI path) in place.
11
+ // migrate an older binding (e.g. a dev-CLI path) in place.
23
12
  const HOOK_COMMAND_MARKER = "hooks eager-open";
13
+ export function claudeCodeDetected() {
14
+ return existsSync(process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude"));
15
+ }
16
+ export function claudeSettingsPath() {
17
+ return join(process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude"), "settings.json");
18
+ }
19
+ function legacyCodexHooksPath() {
20
+ return join(process.env.CODEX_HOME || join(homedir(), ".codex"), "hooks.json");
21
+ }
24
22
  /**
25
23
  * The command the hook runs. Bound to whichever CLI installs it: the dev CLI
26
24
  * sets ETHOS_CLI_COMMAND (so `make dev` points the hook at localhost), while a
@@ -29,27 +27,30 @@ const HOOK_COMMAND_MARKER = "hooks eager-open";
29
27
  export function eagerOpenCommand() {
30
28
  return `${process.env.ETHOS_CLI_COMMAND || "ethos"} hooks eager-open`;
31
29
  }
32
- export function detectHookAgents() {
33
- return ALL_HOOK_AGENTS.filter((name) => HOOK_AGENTS[name].detect());
34
- }
35
30
  export async function installEagerOpenHook(options = {}) {
36
31
  const command = options.command ?? eagerOpenCommand();
37
- const agents = options.agents ?? detectHookAgents();
38
- const results = [];
39
- for (const name of agents) {
40
- const merged = await mergeHook(HOOK_AGENTS[name].settingsFile(), command);
41
- results.push({ agent: name, ...merged });
32
+ const claude = await mergeHook(claudeSettingsPath(), command);
33
+ // Best-effort: remove any legacy Codex hook so it can't fire a duplicate
34
+ // handoff there. Never let a malformed Codex file fail the Claude install.
35
+ let codexPruned;
36
+ try {
37
+ codexPruned = await removeHook(legacyCodexHooksPath());
42
38
  }
43
- return { command, results };
39
+ catch {
40
+ codexPruned = { path: legacyCodexHooksPath(), action: "absent" };
41
+ }
42
+ return { command, claude, codexPruned };
44
43
  }
45
- export async function uninstallEagerOpenHook(options = {}) {
46
- const agents = options.agents ?? ALL_HOOK_AGENTS;
47
- const results = [];
48
- for (const name of agents) {
49
- const removed = await removeHook(HOOK_AGENTS[name].settingsFile());
50
- results.push({ agent: name, ...removed });
44
+ export async function uninstallEagerOpenHook() {
45
+ const claude = await removeHook(claudeSettingsPath());
46
+ let codex;
47
+ try {
48
+ codex = await removeHook(legacyCodexHooksPath());
49
+ }
50
+ catch {
51
+ codex = { path: legacyCodexHooksPath(), action: "absent" };
51
52
  }
52
- return { results };
53
+ return { claude, codex };
53
54
  }
54
55
  async function mergeHook(path, command) {
55
56
  const config = await readJsonObject(path);
@@ -72,11 +73,11 @@ async function mergeHook(path, command) {
72
73
  }
73
74
  async function removeHook(path) {
74
75
  if (!existsSync(path))
75
- return { path, removed: 0 };
76
+ return { path, action: "absent" };
76
77
  const config = await readJsonObject(path);
77
78
  const list = config.hooks?.[HOOK_EVENT];
78
79
  if (!config.hooks || !list)
79
- return { path, removed: 0 };
80
+ return { path, action: "absent" };
80
81
  let removed = 0;
81
82
  const kept = [];
82
83
  for (const group of list) {
@@ -91,7 +92,7 @@ async function removeHook(path) {
91
92
  else
92
93
  delete config.hooks[HOOK_EVENT];
93
94
  await writeJsonFile(path, config);
94
- return { path, removed };
95
+ return { path, action: removed ? "removed" : "absent" };
95
96
  }
96
97
  async function readJsonObject(path) {
97
98
  let raw;
@@ -133,16 +134,4 @@ async function writeJsonFile(path, value) {
133
134
  throw error;
134
135
  }
135
136
  }
136
- export function parseHookAgents(value) {
137
- if (!value)
138
- return undefined;
139
- const parsed = [];
140
- for (const raw of value.split(",").map((part) => part.trim()).filter(Boolean)) {
141
- if (ALL_HOOK_AGENTS.includes(raw))
142
- parsed.push(raw);
143
- else
144
- throw new Error(`unknown hook agent: ${raw} (supported: ${ALL_HOOK_AGENTS.join(", ")})`);
145
- }
146
- return parsed.length ? parsed : undefined;
147
- }
148
137
  //# sourceMappingURL=hooks-installer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-installer.js","sourceRoot":"","sources":["../../src/lib/hooks-installer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks-installer.js","sourceRoot":"","sources":["../../src/lib/hooks-installer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,kFAAkF;AAClF,+EAA+E;AAC/E,+EAA+E;AAC/E,mFAAmF;AACnF,MAAM,UAAU,GAAG,kBAAkB,CAAC;AACtC,8EAA8E;AAC9E,2DAA2D;AAC3D,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAQ/C,MAAM,UAAU,kBAAkB;IAChC,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,eAAe,CAAC,CAAC;AAC5F,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAC;AACjF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,mBAAmB,CAAC;AACxE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAgC,EAAE;IAElC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gBAAgB,EAAE,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;IAC9D,yEAAyE;IACzE,2EAA2E;IAC3E,IAAI,WAA2B,CAAC;IAChC,IAAI,CAAC;QACH,WAAW,GAAG,MAAM,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,WAAW,GAAG,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACtD,IAAI,KAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,GAAG,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC7D,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,OAAe;IACpD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;IAE3C,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YACtC,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBACrF,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC;gBACvB,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;gBACxB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAEnE,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AAC7D,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IACzD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAE9D,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,IAAI,GAAgB,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAChC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAC/F,CAAC;QACF,OAAO,IAAI,UAAU,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/C,IAAI,QAAQ,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,IAAI,CAAC,MAAM;QAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;;QAC5C,OAAO,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAErC,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC1D,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAY;IACxC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC,CAAC,4BAA4B;QAC/F,MAAM,KAAK,CAAC,CAAC,2DAA2D;IAC1E,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAC3B,8EAA8E;IAC9E,gFAAgF;IAChF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,MAAqB,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,sBAAsB,IAAI,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,CACxI,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,KAAc;IACvD,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,8EAA8E;IAC9E,gFAAgF;IAChF,iFAAiF;IACjF,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;IACvD,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC/C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1,8 +1,8 @@
1
- import { HOOK_AGENTS, detectHookAgents, installEagerOpenHook } from "../lib/hooks-installer.js";
2
- // Runs on `npm install`. Re-binds the find-people eager-open hook to the CLI
3
- // being installed — for a normal global install that is prod `ethos`, so
4
- // installing through npm always returns the hook to production (a `make dev`
5
- // run rebinds it to the dev CLI for local testing).
1
+ import { claudeCodeDetected, installEagerOpenHook } from "../lib/hooks-installer.js";
2
+ // Runs on `npm install`. Re-binds the Claude Code find-people eager-open hook to
3
+ // the CLI being installed — for a normal global install that is prod `ethos`, so
4
+ // installing through npm always returns the hook to production (a `make dev` run
5
+ // rebinds it to the dev CLI for local testing). Also prunes any legacy Codex hook.
6
6
  async function main() {
7
7
  if (process.env.ETHOS_SKIP_HOOKS || process.env.ETHOS_SKIP_SKILLS) {
8
8
  process.stderr.write("ethos: skipping eager-open hook install.\n");
@@ -13,12 +13,13 @@ async function main() {
13
13
  process.stderr.write("ethos: detected sudo install - skipping hook install. Run `ethos hooks install` as your user.\n");
14
14
  return;
15
15
  }
16
- const agents = detectHookAgents();
17
- if (!agents.length)
18
- return;
19
- const { command, results } = await installEagerOpenHook({ agents });
20
- const targets = results.map((entry) => HOOK_AGENTS[entry.agent].displayName).join(", ");
21
- process.stderr.write(`ethos: eager-open hook installed for ${targets} (command: ${command})\n`);
16
+ if (!claudeCodeDetected())
17
+ return; // the hook is Claude Code only
18
+ const { command, claude, codexPruned } = await installEagerOpenHook();
19
+ let line = `ethos: eager-open hook ${claude.action} for Claude Code (command: ${command})`;
20
+ if (codexPruned.action === "removed")
21
+ line += "; removed legacy Codex hook";
22
+ process.stderr.write(line + "\n");
22
23
  }
23
24
  main().catch((err) => {
24
25
  process.stderr.write(`ethos: hook install failed (continuing) - ${err instanceof Error ? err.message : String(err)}\nRun \`ethos hooks install\` manually after install completes.\n`);
@@ -1 +1 @@
1
- {"version":3,"file":"install-hooks.js","sourceRoot":"","sources":["../../src/scripts/install-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEhG,6EAA6E;AAC7E,yEAAyE;AACzE,6EAA6E;AAC7E,oDAAoD;AACpD,KAAK,UAAU,IAAI;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAClE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3E,IAAI,GAAG,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iGAAiG,CAClG,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO;IAE3B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,OAAO,cAAc,OAAO,KAAK,CAAC,CAAC;AAClG,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6CACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,mEAAmE,CACpE,CAAC;AACJ,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"install-hooks.js","sourceRoot":"","sources":["../../src/scripts/install-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAErF,iFAAiF;AACjF,iFAAiF;AACjF,iFAAiF;AACjF,mFAAmF;AACnF,KAAK,UAAU,IAAI;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAClE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3E,IAAI,GAAG,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iGAAiG,CAClG,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,CAAC,kBAAkB,EAAE;QAAE,OAAO,CAAC,+BAA+B;IAElE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,oBAAoB,EAAE,CAAC;IACtE,IAAI,IAAI,GAAG,0BAA0B,MAAM,CAAC,MAAM,8BAA8B,OAAO,GAAG,CAAC;IAC3F,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS;QAAE,IAAI,IAAI,6BAA6B,CAAC;IAC5E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6CACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,mEAAmE,CACpE,CAAC;AACJ,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ethos-cli",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Commander-based CLI for Ethos table operations",
5
5
  "homepage": "https://github.com/cluster-software/ethos#readme",
6
6
  "repository": {
@@ -11,34 +11,28 @@ pass `--api-url` for local development or an explicitly requested environment.
11
11
 
12
12
  ## Required CLI
13
13
 
14
- The Ethos CLI (`ethos`) is required. The first command in this skill opens the
15
- upload browser straight away:
16
-
17
- ```sh
18
- ethos flows start find-people-at-companies --agent-client auto --open --json
19
- ```
20
-
21
- If that command fails because `ethos` is not installed or not available on
14
+ The Ethos CLI (`ethos`) is required. If `ethos` is not installed or not on
22
15
  `PATH`, install the latest CLI and retry:
23
16
 
24
17
  ```sh
25
18
  npm install -g ethos-cli@latest --prefer-online
26
19
  ```
27
20
 
28
- If it fails because the CLI is not authenticated, run
29
- `ethos auth login --agent-client auto`, then re-run the `flows start` command.
30
- Do not run a separate `ethos auth status` first; `flows start` already requires
31
- auth and surfaces a clear error when login is needed.
21
+ If a command fails because the CLI is not authenticated, run
22
+ `ethos auth login --agent-client auto`, then retry. Do not run a separate
23
+ `ethos auth status` first; the flow commands already require auth and surface a
24
+ clear error when login is needed.
32
25
 
33
26
  ## Flow
34
27
 
35
28
  Keep CSV upload in the browser-based Ethos product flow:
36
29
 
37
- 1. Start the flow and open the upload browser in one command (`ethos flows start --open`). Save the `handoff_token` from the response.
38
- 2. Immediately ask the user for ICP, buying signals, person targets, and max contacts while they upload.
39
- 3. Capture the uploaded table id automatically with `ethos flows wait "$HANDOFF_TOKEN" --json`. Do not ask the user to paste the table URL unless `flows wait` cannot recover.
40
- 4. Once the brief is ready, inspect the table, create the `people_sourcing` agent, and create the agent-client-created column with the CLI.
41
- 5. Run the column for the FIRST 3 ROWS ONLY. Tell the user you're running for 3 rows to see if the results are good. If yes, the next step is to run on the whole table. If not, refine the agent based on their feedback so it finds the right people.
30
+ 1. Get the upload flow. On Claude Code a `UserPromptSubmit` hook may have already started one if the conversation has an injected `handoff_token`, REUSE it and do NOT run `ethos flows start`. Otherwise run `ethos flows start find-people-at-companies --agent-client auto --json` and save `handoff_token` and `upload_url`. Add `--open` only on shell clients (Claude Code, Cursor) to open the OS browser; on Codex do NOT pass `--open`.
31
+ 2. Open `upload_url` in the right surface. On Codex, open it in the in-app Browser — the default surface (OS-open, via `--open` or `open <url>`, is only a fallback if the in-app Browser is not working). On Claude Code and other shell clients, `--open` already opened the OS browser.
32
+ 3. Immediately ask the user for ICP, buying signals, person targets, and max contacts while they upload.
33
+ 4. Capture the uploaded table id with `ethos flows wait "$HANDOFF_TOKEN" --json`. Do not ask the user to paste the table URL unless `flows wait` cannot recover.
34
+ 5. Once the brief is ready, inspect the table, create the `people_sourcing` agent, and create the agent-client-created column with the CLI.
35
+ 6. Run the column for the FIRST 3 ROWS ONLY. Tell the user you're running for 3 rows to see if the results are good. If yes, the next step is to run on the whole table. If not, refine the agent based on their feedback so it finds the right people.
42
36
 
43
37
  Do not run `ethos tables import-csv` for this skill unless the user explicitly
44
38
  asks for a CLI-only/non-browser fallback. The browser upload is part of the
@@ -60,19 +54,25 @@ setup.
60
54
 
61
55
  ## Start Upload Flow
62
56
 
63
- **Reuse a pre-started flow first.** If the conversation already contains an
64
- injected Ethos handoff for example a `UserPromptSubmit` hook reporting that the
65
- upload browser is already opening and providing a `handoff_token` — do NOT run
66
- `ethos flows start` again. Reuse that `handoff_token`: skip to the brief and then
67
- `ethos flows wait <handoff_token>`. Only run the command below when no such
68
- handoff has been provided.
57
+ **Reuse a pre-started flow first (Claude Code).** On Claude Code a
58
+ `UserPromptSubmit` hook may have already started the flow and injected a
59
+ `handoff_token` ("upload browser is already opening"). If so, do NOT run
60
+ `ethos flows start` again reuse that `handoff_token`: skip to the brief and
61
+ then `ethos flows wait <handoff_token>`. The hook does not run on Codex, so there
62
+ you always run the command below.
69
63
 
70
- Start the browser handoff flow through the CLI abstraction instead of constructing client-specific URLs. Pass `--open` so the CLI opens the upload browser itself:
64
+ Otherwise start the handoff through the CLI abstraction instead of constructing
65
+ client-specific URLs:
71
66
 
72
67
  ```sh
73
- ethos flows start find-people-at-companies --agent-client auto --open --json
68
+ ethos flows start find-people-at-companies --agent-client auto --json
74
69
  ```
75
70
 
71
+ Add `--open` only on shell clients (Claude Code, Cursor) so the CLI opens the OS
72
+ browser. On Codex, do NOT pass `--open` — open `upload_url` in the in-app Browser
73
+ (see Open Browser Upload); use `--open` there only as a fallback if the in-app
74
+ Browser is not working.
75
+
76
76
  Save these fields from `response`:
77
77
 
78
78
  - `handoff_token` (needed for `ethos flows wait`)
@@ -83,8 +83,7 @@ Save these fields from `response`:
83
83
  - `next_prompt`
84
84
 
85
85
  The `upload_url` is a handoff URL that verifies the browser session and
86
- workspace before redirecting to the CSV upload modal. With `--open`, the CLI
87
- already launched it in the default browser.
86
+ workspace before redirecting to the CSV upload modal.
88
87
 
89
88
  If the detected client is wrong, rerun the same command with an explicit client,
90
89
  such as `--agent-client codex` or `--agent-client claude-desktop`.
@@ -94,19 +93,19 @@ session.
94
93
 
95
94
  ## Open Browser Upload
96
95
 
97
- With `--open`, the CLI already launched `response.upload_url` in the default
98
- browser and the CSV upload modal opens directly. You usually do not open
99
- anything yourself. Handle the exceptions per client:
100
-
101
- - In Codex, the in-app Browser is the right surface. If `--open` did not surface
102
- the page there, open `response.upload_url` in the Codex Browser. Do not click
103
- `Import CSV` or take other browser actions after navigating unless the user
104
- asks for help.
105
- - In Claude Code, Cursor, or another shell-based client, `--open` uses the OS
106
- opener. If it failed (for example, no desktop session), run `open "$UPLOAD_URL"`
107
- yourself, and only fall back to MCP browser tools, Chrome connectors, or in-app
108
- browser plugins if that also fails. If every option fails, show the URL and ask
109
- the user to open it.
96
+ Open the upload page in the browser surface for this client. Use `upload_url`
97
+ from the reused hook handoff (Claude Code) or from the `flows start` response.
98
+
99
+ - **Codex**: open `upload_url` in the **in-app Browser** — the default and only
100
+ surface you open. Do NOT also OS-open it. Only if the user says the in-app
101
+ Browser is not working, fall back to OS-opening it (`open "$UPLOAD_URL"`). Do
102
+ not click `Import CSV` or take other browser actions after navigating unless
103
+ the user asks for help.
104
+ - **Claude Code, Cursor, or another shell-based client**: `--open` already
105
+ opened the OS browser. If it failed (for example, no desktop session), run
106
+ `open "$UPLOAD_URL"` yourself, and only fall back to MCP browser tools, Chrome
107
+ connectors, or in-app browser plugins if that also fails. If every option
108
+ fails, show the URL and ask the user to open it.
110
109
 
111
110
  Right after the browser opens, immediately ask `response.next_prompt`. If the
112
111
  flow response is not available for some reason, ask: