diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a9c2e30..2724a1e 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,15 +5,15 @@ "url": "https://extruct.ai" }, "metadata": { - "description": "Official Extruct AI skills for company discovery, Deep Search, AI tables, enrichment, and people workflows", - "version": "1.0.5", + "description": "Official Extruct AI skills for company lookup, discovery, Deep Search, AI tables, enrichment, and people workflows", + "version": "1.0.6", "repository": "https://github.com/extruct-ai/skills" }, "plugins": [ { "name": "extruct-skills", - "version": "1.0.5", - "description": "Official Extruct AI skill bundle for semantic search, lookalike search, Deep Search, table operations, enrichment, and contact-finding workflows.", + "version": "1.0.6", + "description": "Official Extruct AI skill bundle for company lookup, semantic search, lookalike search, Deep Search, table operations, enrichment, and contact-finding workflows.", "source": "./", "strict": true, "skills": [ diff --git a/skills/extruct-api/SKILL.md b/skills/extruct-api/SKILL.md index 55af152..d86222b 100644 --- a/skills/extruct-api/SKILL.md +++ b/skills/extruct-api/SKILL.md @@ -43,6 +43,7 @@ This section covers the default operating intent of the skill: identify the Extr 2. Classify the request into the right Extruct path: - if the user provides an Extruct table URL or a raw table UUID, treat it as an existing table operation first - if the user provides an Extruct task URL or a raw task UUID, treat it as an existing Deep Search task first + - known company lookup: fetch the canonical company profile for one domain or UUID - company discovery: semantic search, lookalike search, or Deep Search - existing table operation: inspect, add/update rows or columns, run, poll, read - company-table workflow: enrich or score companies in a reusable table @@ -189,7 +190,7 @@ If search filters or pagination behavior appear different from the guidance here ### Lookalike Search -Use lookalike search when the user already has a reference company and wants similar companies. Prefer domains or URLs for `--company-identifier` unless a prior Extruct response already gives you a UUID. +Use lookalike search when the user already has a reference company and wants similar companies. Prefer domains for `--company-identifier` unless a prior Extruct response already gives you a UUID. Typical asks: @@ -209,6 +210,30 @@ Pagination uses the same `--offset` and `--limit` behavior as semantic search. If identifier handling is unclear for a specific seed company or the live API behavior differs, verify the current lookalike-search request contract in the official API reference. +### Company Lookup + +Use company lookup when the user has one known company and wants its full canonical Extruct company profile. This is not a discovery tool. + +Use lookup for: + +- "pull up Stripe's profile" +- "get the Extruct profile for ramp.com" +- "fetch details for this company profile UUID" + +Do not use lookup when: + +- the user describes a category or market — use semantic search +- the user asks for similar companies — use lookalike search +- the user wants a scored shortlist — use Deep Search + +Command: + +```bash + companies lookup --company-identifier stripe.com +``` + +`--company-identifier` accepts a domain or Extruct company profile UUID. The response returns `id`, `domain`, `company_name`, and the rich company profile in `context`. Company lookup currently consumes 0 credits, but successful and accepted lookups may appear in usage analytics. + ### Deep Search Use Deep Search when the user wants a higher-precision asynchronous company search, wants explicit criteria, or is comfortable waiting for a task. @@ -690,7 +715,7 @@ If the auth flow, expected status codes, or healthcheck contract has changed, de ### Lookalike Results Feel Wrong -- use a domain or URL instead of a company name when possible +- use a domain or UUID instead of a company name when possible - confirm the seed company is the correct one before judging the output ### Column Creation Fails diff --git a/skills/extruct-api/references/finding-companies.md b/skills/extruct-api/references/finding-companies.md index 41aab52..5adde34 100644 --- a/skills/extruct-api/references/finding-companies.md +++ b/skills/extruct-api/references/finding-companies.md @@ -8,6 +8,7 @@ All commands below use `` as shorthand for the resolved absolut Use this playbook when the user asks for: +- a full profile for one known company - semantic company discovery from a natural-language query - similar companies from a known seed company - a higher-precision asynchronous search with explicit criteria @@ -20,6 +21,15 @@ Do not use this playbook when: ## Choose The Right Search Path +### Use Company Lookup + +Use `companies lookup` when the user has a known company and wants its full canonical Extruct profile. This accepts a domain or Extruct company profile UUID. +Company lookup currently consumes 0 credits, but successful and accepted lookups may appear in usage analytics. + +```bash + companies lookup --company-identifier stripe.com +``` + ### Use Semantic Search Use `companies search` when the user describes a market, ICP, category, product, use case, or geography in natural language. @@ -40,7 +50,7 @@ Add `--filters` when the user specifies geography, size, city, or founded range: Use `companies similar` when the user already knows a reference company. -- prefer a domain or URL as `--company-identifier` +- prefer a domain as `--company-identifier` - use a UUID only when a prior Extruct response already gives you one ```bash diff --git a/skills/extruct-api/scripts/extruct-api b/skills/extruct-api/scripts/extruct-api index 10aee9e..41876e4 100755 --- a/skills/extruct-api/scripts/extruct-api +++ b/skills/extruct-api/scripts/extruct-api @@ -750,6 +750,17 @@ def _build_parser() -> argparse.ArgumentParser: companies_similar.add_argument("--limit", type=int, default=DEFAULT_LIST_LIMIT) companies_similar.add_argument("--filters", help="Search filters JSON string.") + companies_lookup = companies_actions.add_parser( + "lookup", + help="Look up the full company profile for a known company domain or UUID.", + parents=[global_options], + ) + companies_lookup.add_argument( + "--company-identifier", + required=True, + help="Company identifier (domain or UUID).", + ) + tables = resources.add_parser("tables", help="Table commands.", parents=[global_options]) tables_actions = tables.add_subparsers(dest="action", required=True) @@ -910,6 +921,11 @@ def _healthcheck_method_path() -> tuple[str, str]: def _companies_method_path(action: str, company_identifier: str | None = None) -> tuple[str, str]: if action == "search": return "GET", "/v1/companies/search" + if action == "lookup": + if company_identifier is None: + raise ValueError("company_identifier is required for lookup action.") + encoded_identifier = urllib.parse.quote(company_identifier, safe="") + return "GET", f"/v1/companies/{encoded_identifier}" if action == "similar": if company_identifier is None: raise ValueError("company_identifier is required for similar action.") @@ -1009,6 +1025,16 @@ def _handle_companies(args: argparse.Namespace) -> int: _json_print(query_error, args.pretty) return query_error_code query_params["q"] = args.query + elif args.action == "lookup": + identifier_error, identifier_error_code = _validate_non_empty( + args.company_identifier, + flag="--company-identifier", + path="/v1/companies/{company_identifier}", + ) + if identifier_error is not None: + _json_print(identifier_error, args.pretty) + return identifier_error_code + method, path = _companies_method_path("lookup", company_identifier=args.company_identifier) elif args.action == "similar": identifier_error, identifier_error_code = _validate_non_empty( args.company_identifier, @@ -1024,6 +1050,9 @@ def _handle_companies(args: argparse.Namespace) -> int: _json_print(error, args.pretty) return code + if args.action == "lookup": + return _execute_request(args, method=method, path=path) + pagination_error, pagination_error_code = _validate_pagination(args.offset, args.limit, path=path) if pagination_error is not None: _json_print(pagination_error, args.pretty)