deepline 0.1.261 → 0.1.262
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.
|
@@ -123,7 +123,7 @@ export const SDK_RELEASE = {
|
|
|
123
123
|
// Deepline-native radars. Older clients must update before discovering,
|
|
124
124
|
// checking, or deploying an unlaunched monitor integration.
|
|
125
125
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
126
|
-
version: '0.1.
|
|
126
|
+
version: '0.1.262',
|
|
127
127
|
apiContract: '2026-07-native-monitor-launch-hard-cutover',
|
|
128
128
|
supportPolicy: {
|
|
129
129
|
minimumSupported: '0.1.53',
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// One-line definitions for the tool categories surfaced by `deepline tools list`.
|
|
2
|
+
//
|
|
3
|
+
// Tool categories are free-form strings that each provider tool declares in the
|
|
4
|
+
// generated catalog (see `src/lib/integrations/**`), not a single closed enum.
|
|
5
|
+
// The canonical set of well-known category slugs lives next to this file in
|
|
6
|
+
// `DEEPLINE_TOOL_CATEGORIES` (bootstrap-routes.ts) and in the richer
|
|
7
|
+
// `IntegrationCatalogTag` enum (src/lib/integrations/catalog-tags.ts). This map
|
|
8
|
+
// MUST track the categories that actually appear on live tools. The CLI derives
|
|
9
|
+
// the category enumeration from the live catalog, so a new category slug shows
|
|
10
|
+
// up automatically; only its human-readable definition comes from here. When a
|
|
11
|
+
// category has no entry the CLI renders it without a definition (never invents
|
|
12
|
+
// one), which is the loud signal to add it here.
|
|
13
|
+
//
|
|
14
|
+
// Keep each definition to a single, plain sentence fragment.
|
|
15
|
+
|
|
16
|
+
export const TOOL_CATEGORY_DESCRIPTIONS: Readonly<Record<string, string>> = {
|
|
17
|
+
company_search: 'Find companies matching firmographic, ad, or web criteria.',
|
|
18
|
+
people_search: 'Find people matching role, company, or persona criteria.',
|
|
19
|
+
people_enrich:
|
|
20
|
+
'Enrich a known person with contact, social, and profile data.',
|
|
21
|
+
company_enrich: 'Enrich a known company with firmographic and account data.',
|
|
22
|
+
email_finder: 'Find work or personal email addresses for a person.',
|
|
23
|
+
email_verify: 'Validate email deliverability and catch-all status.',
|
|
24
|
+
phone_finder: 'Find mobile or direct phone numbers for a person.',
|
|
25
|
+
phone_verify: 'Validate phone-number reachability and line type.',
|
|
26
|
+
research:
|
|
27
|
+
'Research accounts, people, news, and signals for context and scoring.',
|
|
28
|
+
autocomplete: 'Resolve names and entities to canonical catalog records.',
|
|
29
|
+
automation:
|
|
30
|
+
'Kick off provider-side jobs, exports, and asynchronous workflows.',
|
|
31
|
+
outbound_tools:
|
|
32
|
+
'Run outbound sequencing, deliverability, and campaign operations.',
|
|
33
|
+
admin:
|
|
34
|
+
'Provider-side status, metadata, and account operations behind other tools.',
|
|
35
|
+
smb: 'Look up small-business listings, local records, and public filings.',
|
|
36
|
+
identity_resolution:
|
|
37
|
+
'Match a partial identity to a single resolved person or company.',
|
|
38
|
+
reverse_lookup: 'Resolve an email, phone, or profile back to a person.',
|
|
39
|
+
enrichment: 'General-purpose record enrichment across people and companies.',
|
|
40
|
+
batch: 'Run an enrichment or search operation over many rows at once.',
|
|
41
|
+
premium: 'Higher-cost tools with premium provider coverage.',
|
|
42
|
+
free: 'Free tools that do not spend Deepline credits.',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* One-line definition for a tool category slug, or null when none is declared.
|
|
47
|
+
* Never fabricates a definition for unknown slugs.
|
|
48
|
+
*/
|
|
49
|
+
export function describeToolCategory(category: string): string | null {
|
|
50
|
+
return TOOL_CATEGORY_DESCRIPTIONS[category] ?? null;
|
|
51
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -716,7 +716,7 @@ var SDK_RELEASE = {
|
|
|
716
716
|
// Deepline-native radars. Older clients must update before discovering,
|
|
717
717
|
// checking, or deploying an unlaunched monitor integration.
|
|
718
718
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
719
|
-
version: "0.1.
|
|
719
|
+
version: "0.1.262",
|
|
720
720
|
apiContract: "2026-07-native-monitor-launch-hard-cutover",
|
|
721
721
|
supportPolicy: {
|
|
722
722
|
minimumSupported: "0.1.53",
|
|
@@ -26616,6 +26616,33 @@ function extractSummaryFields(payload) {
|
|
|
26616
26616
|
return {};
|
|
26617
26617
|
}
|
|
26618
26618
|
|
|
26619
|
+
// ../shared_libs/plays/tool-category-descriptions.ts
|
|
26620
|
+
var TOOL_CATEGORY_DESCRIPTIONS = {
|
|
26621
|
+
company_search: "Find companies matching firmographic, ad, or web criteria.",
|
|
26622
|
+
people_search: "Find people matching role, company, or persona criteria.",
|
|
26623
|
+
people_enrich: "Enrich a known person with contact, social, and profile data.",
|
|
26624
|
+
company_enrich: "Enrich a known company with firmographic and account data.",
|
|
26625
|
+
email_finder: "Find work or personal email addresses for a person.",
|
|
26626
|
+
email_verify: "Validate email deliverability and catch-all status.",
|
|
26627
|
+
phone_finder: "Find mobile or direct phone numbers for a person.",
|
|
26628
|
+
phone_verify: "Validate phone-number reachability and line type.",
|
|
26629
|
+
research: "Research accounts, people, news, and signals for context and scoring.",
|
|
26630
|
+
autocomplete: "Resolve names and entities to canonical catalog records.",
|
|
26631
|
+
automation: "Kick off provider-side jobs, exports, and asynchronous workflows.",
|
|
26632
|
+
outbound_tools: "Run outbound sequencing, deliverability, and campaign operations.",
|
|
26633
|
+
admin: "Provider-side status, metadata, and account operations behind other tools.",
|
|
26634
|
+
smb: "Look up small-business listings, local records, and public filings.",
|
|
26635
|
+
identity_resolution: "Match a partial identity to a single resolved person or company.",
|
|
26636
|
+
reverse_lookup: "Resolve an email, phone, or profile back to a person.",
|
|
26637
|
+
enrichment: "General-purpose record enrichment across people and companies.",
|
|
26638
|
+
batch: "Run an enrichment or search operation over many rows at once.",
|
|
26639
|
+
premium: "Higher-cost tools with premium provider coverage.",
|
|
26640
|
+
free: "Free tools that do not spend Deepline credits."
|
|
26641
|
+
};
|
|
26642
|
+
function describeToolCategory(category) {
|
|
26643
|
+
return TOOL_CATEGORY_DESCRIPTIONS[category] ?? null;
|
|
26644
|
+
}
|
|
26645
|
+
|
|
26619
26646
|
// src/cli/commands/model-description.ts
|
|
26620
26647
|
function formatModelDescription(description) {
|
|
26621
26648
|
const lines = [];
|
|
@@ -26782,21 +26809,181 @@ function zeroMatchRender(emptyResult) {
|
|
|
26782
26809
|
]
|
|
26783
26810
|
};
|
|
26784
26811
|
}
|
|
26785
|
-
|
|
26812
|
+
function firstSentence(text) {
|
|
26813
|
+
const clean = (text ?? "").replace(/\s+/g, " ").trim();
|
|
26814
|
+
if (!clean) return "";
|
|
26815
|
+
const match = clean.match(/^.*?[.!?](?=\s|$)/);
|
|
26816
|
+
return (match ? match[0] : clean).trim();
|
|
26817
|
+
}
|
|
26818
|
+
function requiredInputIds(tool) {
|
|
26819
|
+
const inputSchema = recordField2(
|
|
26820
|
+
tool,
|
|
26821
|
+
"inputSchema",
|
|
26822
|
+
"input_schema"
|
|
26823
|
+
);
|
|
26824
|
+
return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
|
|
26825
|
+
}
|
|
26826
|
+
function shortPricingHint(tool) {
|
|
26827
|
+
const pricing = recordField2(
|
|
26828
|
+
tool,
|
|
26829
|
+
"pricing"
|
|
26830
|
+
);
|
|
26831
|
+
const credits = numberField2(pricing, "creditsPerUnit", "credits_per_unit");
|
|
26832
|
+
const unit = stringField2(pricing, "unit");
|
|
26833
|
+
if (credits !== null) {
|
|
26834
|
+
return `${formatDecimal(credits)} cr/${unit || "unit"}`;
|
|
26835
|
+
}
|
|
26836
|
+
const summary = stringField2(pricing, "summary");
|
|
26837
|
+
if (summary) return summary;
|
|
26838
|
+
const displayText = stringField2(pricing, "displayText", "display_text");
|
|
26839
|
+
return displayText || null;
|
|
26840
|
+
}
|
|
26841
|
+
function aggregateCategorySummaries(tools) {
|
|
26842
|
+
const counts = /* @__PURE__ */ new Map();
|
|
26843
|
+
for (const tool of tools) {
|
|
26844
|
+
for (const category of tool.categories ?? []) {
|
|
26845
|
+
counts.set(category, (counts.get(category) ?? 0) + 1);
|
|
26846
|
+
}
|
|
26847
|
+
}
|
|
26848
|
+
return [...counts.entries()].map(([name, count]) => ({
|
|
26849
|
+
name,
|
|
26850
|
+
count,
|
|
26851
|
+
description: describeToolCategory(name)
|
|
26852
|
+
})).sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
|
|
26853
|
+
}
|
|
26854
|
+
function categoryEnumerationRender(summaries) {
|
|
26855
|
+
const nameWidth = summaries.reduce(
|
|
26856
|
+
(max, item) => Math.max(max, item.name.length),
|
|
26857
|
+
0
|
|
26858
|
+
);
|
|
26859
|
+
const countWidth = summaries.reduce(
|
|
26860
|
+
(max, item) => Math.max(max, String(item.count).length),
|
|
26861
|
+
0
|
|
26862
|
+
);
|
|
26863
|
+
return {
|
|
26864
|
+
sections: [
|
|
26865
|
+
{
|
|
26866
|
+
title: `${summaries.length} tool categories:`,
|
|
26867
|
+
lines: summaries.map((item) => {
|
|
26868
|
+
const name = item.name.padEnd(nameWidth);
|
|
26869
|
+
const count = String(item.count).padStart(countWidth);
|
|
26870
|
+
const definition = item.description ? ` - ${item.description}` : "";
|
|
26871
|
+
return `${name} ${count}${definition}`;
|
|
26872
|
+
})
|
|
26873
|
+
},
|
|
26874
|
+
{
|
|
26875
|
+
title: "next",
|
|
26876
|
+
lines: ["Pass a category: deepline tools list email_finder"]
|
|
26877
|
+
}
|
|
26878
|
+
]
|
|
26879
|
+
};
|
|
26880
|
+
}
|
|
26881
|
+
async function listToolCategories(emitJson, compact) {
|
|
26882
|
+
const client2 = new DeeplineClient();
|
|
26883
|
+
const rawTools = await client2.listTools({ compact });
|
|
26884
|
+
const items = rawTools.map(toListedTool);
|
|
26885
|
+
const summaries = aggregateCategorySummaries(rawTools);
|
|
26886
|
+
const outputItems = compact ? items.map(compactTool) : items;
|
|
26887
|
+
printCommandEnvelope(
|
|
26888
|
+
{
|
|
26889
|
+
tools: outputItems,
|
|
26890
|
+
count: outputItems.length,
|
|
26891
|
+
categories: summaries,
|
|
26892
|
+
filters: {
|
|
26893
|
+
categories: []
|
|
26894
|
+
},
|
|
26895
|
+
commandTemplates: TOOL_COMMAND_TEMPLATES,
|
|
26896
|
+
render: categoryEnumerationRender(summaries)
|
|
26897
|
+
},
|
|
26898
|
+
{ json: emitJson }
|
|
26899
|
+
);
|
|
26900
|
+
return 0;
|
|
26901
|
+
}
|
|
26902
|
+
function unknownCategoryError(category, summaries, emitJson) {
|
|
26903
|
+
const known = summaries.map((item) => item.name);
|
|
26904
|
+
const message = `Unknown tool category "${category}". Run \`deepline tools list\` to browse categories.`;
|
|
26905
|
+
if (emitJson) {
|
|
26906
|
+
printJson({
|
|
26907
|
+
ok: false,
|
|
26908
|
+
exitCode: 4,
|
|
26909
|
+
code: "TOOL_CATEGORY_NOT_FOUND",
|
|
26910
|
+
message,
|
|
26911
|
+
category,
|
|
26912
|
+
categories: summaries,
|
|
26913
|
+
next: "deepline tools list"
|
|
26914
|
+
});
|
|
26915
|
+
return 4;
|
|
26916
|
+
}
|
|
26917
|
+
const render = categoryEnumerationRender(summaries);
|
|
26918
|
+
console.error(message);
|
|
26919
|
+
console.error("");
|
|
26920
|
+
console.error(renderCommandEnvelopeText({ render }).trimEnd());
|
|
26921
|
+
console.error("");
|
|
26922
|
+
console.error(`Valid categories: ${known.join(", ")}`);
|
|
26923
|
+
return 4;
|
|
26924
|
+
}
|
|
26925
|
+
async function listToolsInCategory(category, emitJson) {
|
|
26926
|
+
const client2 = new DeeplineClient();
|
|
26927
|
+
const rawTools = await client2.listTools({
|
|
26928
|
+
categories: category,
|
|
26929
|
+
compact: false
|
|
26930
|
+
});
|
|
26931
|
+
const allTools = await client2.listTools({ compact: true });
|
|
26932
|
+
const summaries = aggregateCategorySummaries(allTools);
|
|
26933
|
+
if (!summaries.some((item) => item.name === category)) {
|
|
26934
|
+
return unknownCategoryError(category, summaries, emitJson);
|
|
26935
|
+
}
|
|
26936
|
+
const rows = rawTools.filter((tool) => tool.categories?.includes(category)).map((tool) => ({
|
|
26937
|
+
id: tool.toolId,
|
|
26938
|
+
provider: tool.provider,
|
|
26939
|
+
required: requiredInputIds(tool),
|
|
26940
|
+
pricing: shortPricingHint(tool),
|
|
26941
|
+
description: firstSentence(tool.description)
|
|
26942
|
+
})).sort((a, b) => a.id.localeCompare(b.id));
|
|
26943
|
+
const idWidth = rows.reduce((max, row) => Math.max(max, row.id.length), 0);
|
|
26944
|
+
const render = {
|
|
26945
|
+
sections: [
|
|
26946
|
+
{
|
|
26947
|
+
title: `${rows.length} tools in ${category}:`,
|
|
26948
|
+
lines: rows.map((row) => {
|
|
26949
|
+
const id = row.id.padEnd(idWidth);
|
|
26950
|
+
const required = row.required.length ? `(${row.required.join(", ")})` : "(no required inputs)";
|
|
26951
|
+
const pricing = row.pricing ? ` [${row.pricing}]` : "";
|
|
26952
|
+
const description = row.description ? ` - ${row.description}` : "";
|
|
26953
|
+
return `${id} ${required}${pricing}${description}`;
|
|
26954
|
+
})
|
|
26955
|
+
},
|
|
26956
|
+
{
|
|
26957
|
+
title: "next",
|
|
26958
|
+
lines: [
|
|
26959
|
+
"Run `deepline tools describe <toolId>` for the full contract."
|
|
26960
|
+
]
|
|
26961
|
+
}
|
|
26962
|
+
]
|
|
26963
|
+
};
|
|
26964
|
+
printCommandEnvelope(
|
|
26965
|
+
{
|
|
26966
|
+
category,
|
|
26967
|
+
total: rows.length,
|
|
26968
|
+
tools: rows,
|
|
26969
|
+
commandTemplates: TOOL_COMMAND_TEMPLATES,
|
|
26970
|
+
render
|
|
26971
|
+
},
|
|
26972
|
+
{ json: emitJson }
|
|
26973
|
+
);
|
|
26974
|
+
return 0;
|
|
26975
|
+
}
|
|
26976
|
+
async function listToolsForCategoryFilter(requestedCategories, emitJson, compact) {
|
|
26786
26977
|
const client2 = new DeeplineClient();
|
|
26787
|
-
const categoryArgIndex = args.findIndex((arg) => arg === "--categories");
|
|
26788
|
-
const categoryFilter = categoryArgIndex >= 0 ? args[categoryArgIndex + 1] : "";
|
|
26789
|
-
const compact = !args.includes("--full");
|
|
26790
|
-
const requestedCategories = categoryFilter ? categoryFilter.split(",").map((item) => item.trim()).filter(Boolean) : [];
|
|
26791
26978
|
const items = (await client2.listTools({
|
|
26792
|
-
|
|
26979
|
+
categories: requestedCategories.join(","),
|
|
26793
26980
|
compact
|
|
26794
26981
|
})).map(toListedTool).filter(
|
|
26795
|
-
(item) => requestedCategories.
|
|
26982
|
+
(item) => requestedCategories.some(
|
|
26796
26983
|
(category) => item.categories.includes(category)
|
|
26797
26984
|
)
|
|
26798
26985
|
);
|
|
26799
|
-
const emptyResult = items.length === 0
|
|
26986
|
+
const emptyResult = items.length === 0 ? zeroMatchToolGuidance({ categories: requestedCategories }) : null;
|
|
26800
26987
|
const render = {
|
|
26801
26988
|
sections: emptyResult ? zeroMatchRender(emptyResult).sections : [
|
|
26802
26989
|
{
|
|
@@ -26827,10 +27014,41 @@ async function listTools(args) {
|
|
|
26827
27014
|
commandTemplates: TOOL_COMMAND_TEMPLATES,
|
|
26828
27015
|
render
|
|
26829
27016
|
},
|
|
26830
|
-
{ json:
|
|
27017
|
+
{ json: emitJson }
|
|
26831
27018
|
);
|
|
26832
27019
|
return 0;
|
|
26833
27020
|
}
|
|
27021
|
+
async function listTools(category, options = {}) {
|
|
27022
|
+
const positional = category?.trim() ?? "";
|
|
27023
|
+
const flagCategories = (options.categories ?? "").split(",").map((item) => item.trim()).filter(Boolean);
|
|
27024
|
+
const compact = options.compact !== false;
|
|
27025
|
+
const emitJson = options.json === true || shouldEmitJson();
|
|
27026
|
+
if (positional && flagCategories.length > 0) {
|
|
27027
|
+
const flagIsSameSingle = flagCategories.length === 1 && flagCategories[0] === positional;
|
|
27028
|
+
if (!flagIsSameSingle) {
|
|
27029
|
+
const message = `Category "${positional}" and --categories ${flagCategories.join(",")} disagree. Pass one: deepline tools list ${positional}`;
|
|
27030
|
+
if (emitJson) {
|
|
27031
|
+
printJson({
|
|
27032
|
+
ok: false,
|
|
27033
|
+
exitCode: 2,
|
|
27034
|
+
code: "TOOL_LIST_CATEGORY_CONFLICT",
|
|
27035
|
+
message,
|
|
27036
|
+
next: `deepline tools list ${positional}`
|
|
27037
|
+
});
|
|
27038
|
+
} else {
|
|
27039
|
+
console.error(message);
|
|
27040
|
+
}
|
|
27041
|
+
return 2;
|
|
27042
|
+
}
|
|
27043
|
+
}
|
|
27044
|
+
if (positional) {
|
|
27045
|
+
return listToolsInCategory(positional, emitJson);
|
|
27046
|
+
}
|
|
27047
|
+
if (flagCategories.length > 0) {
|
|
27048
|
+
return listToolsForCategoryFilter(flagCategories, emitJson, compact);
|
|
27049
|
+
}
|
|
27050
|
+
return listToolCategories(emitJson, compact);
|
|
27051
|
+
}
|
|
26834
27052
|
async function searchTools(queryInput, options = {}) {
|
|
26835
27053
|
const query = queryInput?.trim() ?? "";
|
|
26836
27054
|
const hasStructuredSearch = Boolean(
|
|
@@ -27029,27 +27247,37 @@ Output:
|
|
|
27029
27247
|
Use execute to run a tool.
|
|
27030
27248
|
`
|
|
27031
27249
|
);
|
|
27032
|
-
tools.command("list").description("
|
|
27250
|
+
tools.command("list [category]").description("Browse tool categories, or list every tool in a category.").addHelpText(
|
|
27033
27251
|
"after",
|
|
27034
27252
|
`
|
|
27035
27253
|
Notes:
|
|
27036
|
-
|
|
27037
|
-
|
|
27254
|
+
Bare \`tools list\` prints the category enumeration: one line per category with
|
|
27255
|
+
its tool count and definition. Pass a category to list every tool in it, one
|
|
27256
|
+
succinct row each (required inputs, Deepline pricing hint, first sentence).
|
|
27257
|
+
The listing is exhaustive and never truncated. Use search for ranked discovery
|
|
27258
|
+
by intent, aliases, descriptions, and schema fields.
|
|
27259
|
+
|
|
27260
|
+
--categories is a back-compat inventory filter. Passing it alone returns the
|
|
27261
|
+
legacy flat inventory envelope (one row per tool). The positional category is
|
|
27262
|
+
the newer exhaustive per-category view. If both are given they must name the
|
|
27263
|
+
same category (the positional view wins); otherwise it is a usage error.
|
|
27038
27264
|
|
|
27039
27265
|
Examples:
|
|
27040
27266
|
deepline tools list
|
|
27267
|
+
deepline tools list email_finder
|
|
27268
|
+
deepline tools list email_finder --json
|
|
27041
27269
|
deepline tools list --categories email_finder --json
|
|
27042
27270
|
deepline tools search email --json
|
|
27043
27271
|
`
|
|
27044
27272
|
).option(
|
|
27045
27273
|
"--categories <categories>",
|
|
27046
|
-
"Comma-separated categories
|
|
27047
|
-
).option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
|
|
27048
|
-
process.exitCode = await listTools(
|
|
27049
|
-
|
|
27050
|
-
|
|
27051
|
-
|
|
27052
|
-
|
|
27274
|
+
"Comma-separated categories filter (back-compat alias for the positional)"
|
|
27275
|
+
).option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (category, options) => {
|
|
27276
|
+
process.exitCode = await listTools(category, {
|
|
27277
|
+
categories: typeof options.categories === "string" ? options.categories : void 0,
|
|
27278
|
+
compact: options.compact !== false,
|
|
27279
|
+
json: Boolean(options.json)
|
|
27280
|
+
});
|
|
27053
27281
|
});
|
|
27054
27282
|
const addToolSearchCommand = (command) => command.description(
|
|
27055
27283
|
"Search available tools by intent query or structured filters."
|
package/dist/cli/index.mjs
CHANGED
|
@@ -701,7 +701,7 @@ var SDK_RELEASE = {
|
|
|
701
701
|
// Deepline-native radars. Older clients must update before discovering,
|
|
702
702
|
// checking, or deploying an unlaunched monitor integration.
|
|
703
703
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
704
|
-
version: "0.1.
|
|
704
|
+
version: "0.1.262",
|
|
705
705
|
apiContract: "2026-07-native-monitor-launch-hard-cutover",
|
|
706
706
|
supportPolicy: {
|
|
707
707
|
minimumSupported: "0.1.53",
|
|
@@ -26664,6 +26664,33 @@ function extractSummaryFields(payload) {
|
|
|
26664
26664
|
return {};
|
|
26665
26665
|
}
|
|
26666
26666
|
|
|
26667
|
+
// ../shared_libs/plays/tool-category-descriptions.ts
|
|
26668
|
+
var TOOL_CATEGORY_DESCRIPTIONS = {
|
|
26669
|
+
company_search: "Find companies matching firmographic, ad, or web criteria.",
|
|
26670
|
+
people_search: "Find people matching role, company, or persona criteria.",
|
|
26671
|
+
people_enrich: "Enrich a known person with contact, social, and profile data.",
|
|
26672
|
+
company_enrich: "Enrich a known company with firmographic and account data.",
|
|
26673
|
+
email_finder: "Find work or personal email addresses for a person.",
|
|
26674
|
+
email_verify: "Validate email deliverability and catch-all status.",
|
|
26675
|
+
phone_finder: "Find mobile or direct phone numbers for a person.",
|
|
26676
|
+
phone_verify: "Validate phone-number reachability and line type.",
|
|
26677
|
+
research: "Research accounts, people, news, and signals for context and scoring.",
|
|
26678
|
+
autocomplete: "Resolve names and entities to canonical catalog records.",
|
|
26679
|
+
automation: "Kick off provider-side jobs, exports, and asynchronous workflows.",
|
|
26680
|
+
outbound_tools: "Run outbound sequencing, deliverability, and campaign operations.",
|
|
26681
|
+
admin: "Provider-side status, metadata, and account operations behind other tools.",
|
|
26682
|
+
smb: "Look up small-business listings, local records, and public filings.",
|
|
26683
|
+
identity_resolution: "Match a partial identity to a single resolved person or company.",
|
|
26684
|
+
reverse_lookup: "Resolve an email, phone, or profile back to a person.",
|
|
26685
|
+
enrichment: "General-purpose record enrichment across people and companies.",
|
|
26686
|
+
batch: "Run an enrichment or search operation over many rows at once.",
|
|
26687
|
+
premium: "Higher-cost tools with premium provider coverage.",
|
|
26688
|
+
free: "Free tools that do not spend Deepline credits."
|
|
26689
|
+
};
|
|
26690
|
+
function describeToolCategory(category) {
|
|
26691
|
+
return TOOL_CATEGORY_DESCRIPTIONS[category] ?? null;
|
|
26692
|
+
}
|
|
26693
|
+
|
|
26667
26694
|
// src/cli/commands/model-description.ts
|
|
26668
26695
|
function formatModelDescription(description) {
|
|
26669
26696
|
const lines = [];
|
|
@@ -26830,21 +26857,181 @@ function zeroMatchRender(emptyResult) {
|
|
|
26830
26857
|
]
|
|
26831
26858
|
};
|
|
26832
26859
|
}
|
|
26833
|
-
|
|
26860
|
+
function firstSentence(text) {
|
|
26861
|
+
const clean = (text ?? "").replace(/\s+/g, " ").trim();
|
|
26862
|
+
if (!clean) return "";
|
|
26863
|
+
const match = clean.match(/^.*?[.!?](?=\s|$)/);
|
|
26864
|
+
return (match ? match[0] : clean).trim();
|
|
26865
|
+
}
|
|
26866
|
+
function requiredInputIds(tool) {
|
|
26867
|
+
const inputSchema = recordField2(
|
|
26868
|
+
tool,
|
|
26869
|
+
"inputSchema",
|
|
26870
|
+
"input_schema"
|
|
26871
|
+
);
|
|
26872
|
+
return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
|
|
26873
|
+
}
|
|
26874
|
+
function shortPricingHint(tool) {
|
|
26875
|
+
const pricing = recordField2(
|
|
26876
|
+
tool,
|
|
26877
|
+
"pricing"
|
|
26878
|
+
);
|
|
26879
|
+
const credits = numberField2(pricing, "creditsPerUnit", "credits_per_unit");
|
|
26880
|
+
const unit = stringField2(pricing, "unit");
|
|
26881
|
+
if (credits !== null) {
|
|
26882
|
+
return `${formatDecimal(credits)} cr/${unit || "unit"}`;
|
|
26883
|
+
}
|
|
26884
|
+
const summary = stringField2(pricing, "summary");
|
|
26885
|
+
if (summary) return summary;
|
|
26886
|
+
const displayText = stringField2(pricing, "displayText", "display_text");
|
|
26887
|
+
return displayText || null;
|
|
26888
|
+
}
|
|
26889
|
+
function aggregateCategorySummaries(tools) {
|
|
26890
|
+
const counts = /* @__PURE__ */ new Map();
|
|
26891
|
+
for (const tool of tools) {
|
|
26892
|
+
for (const category of tool.categories ?? []) {
|
|
26893
|
+
counts.set(category, (counts.get(category) ?? 0) + 1);
|
|
26894
|
+
}
|
|
26895
|
+
}
|
|
26896
|
+
return [...counts.entries()].map(([name, count]) => ({
|
|
26897
|
+
name,
|
|
26898
|
+
count,
|
|
26899
|
+
description: describeToolCategory(name)
|
|
26900
|
+
})).sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
|
|
26901
|
+
}
|
|
26902
|
+
function categoryEnumerationRender(summaries) {
|
|
26903
|
+
const nameWidth = summaries.reduce(
|
|
26904
|
+
(max, item) => Math.max(max, item.name.length),
|
|
26905
|
+
0
|
|
26906
|
+
);
|
|
26907
|
+
const countWidth = summaries.reduce(
|
|
26908
|
+
(max, item) => Math.max(max, String(item.count).length),
|
|
26909
|
+
0
|
|
26910
|
+
);
|
|
26911
|
+
return {
|
|
26912
|
+
sections: [
|
|
26913
|
+
{
|
|
26914
|
+
title: `${summaries.length} tool categories:`,
|
|
26915
|
+
lines: summaries.map((item) => {
|
|
26916
|
+
const name = item.name.padEnd(nameWidth);
|
|
26917
|
+
const count = String(item.count).padStart(countWidth);
|
|
26918
|
+
const definition = item.description ? ` - ${item.description}` : "";
|
|
26919
|
+
return `${name} ${count}${definition}`;
|
|
26920
|
+
})
|
|
26921
|
+
},
|
|
26922
|
+
{
|
|
26923
|
+
title: "next",
|
|
26924
|
+
lines: ["Pass a category: deepline tools list email_finder"]
|
|
26925
|
+
}
|
|
26926
|
+
]
|
|
26927
|
+
};
|
|
26928
|
+
}
|
|
26929
|
+
async function listToolCategories(emitJson, compact) {
|
|
26930
|
+
const client2 = new DeeplineClient();
|
|
26931
|
+
const rawTools = await client2.listTools({ compact });
|
|
26932
|
+
const items = rawTools.map(toListedTool);
|
|
26933
|
+
const summaries = aggregateCategorySummaries(rawTools);
|
|
26934
|
+
const outputItems = compact ? items.map(compactTool) : items;
|
|
26935
|
+
printCommandEnvelope(
|
|
26936
|
+
{
|
|
26937
|
+
tools: outputItems,
|
|
26938
|
+
count: outputItems.length,
|
|
26939
|
+
categories: summaries,
|
|
26940
|
+
filters: {
|
|
26941
|
+
categories: []
|
|
26942
|
+
},
|
|
26943
|
+
commandTemplates: TOOL_COMMAND_TEMPLATES,
|
|
26944
|
+
render: categoryEnumerationRender(summaries)
|
|
26945
|
+
},
|
|
26946
|
+
{ json: emitJson }
|
|
26947
|
+
);
|
|
26948
|
+
return 0;
|
|
26949
|
+
}
|
|
26950
|
+
function unknownCategoryError(category, summaries, emitJson) {
|
|
26951
|
+
const known = summaries.map((item) => item.name);
|
|
26952
|
+
const message = `Unknown tool category "${category}". Run \`deepline tools list\` to browse categories.`;
|
|
26953
|
+
if (emitJson) {
|
|
26954
|
+
printJson({
|
|
26955
|
+
ok: false,
|
|
26956
|
+
exitCode: 4,
|
|
26957
|
+
code: "TOOL_CATEGORY_NOT_FOUND",
|
|
26958
|
+
message,
|
|
26959
|
+
category,
|
|
26960
|
+
categories: summaries,
|
|
26961
|
+
next: "deepline tools list"
|
|
26962
|
+
});
|
|
26963
|
+
return 4;
|
|
26964
|
+
}
|
|
26965
|
+
const render = categoryEnumerationRender(summaries);
|
|
26966
|
+
console.error(message);
|
|
26967
|
+
console.error("");
|
|
26968
|
+
console.error(renderCommandEnvelopeText({ render }).trimEnd());
|
|
26969
|
+
console.error("");
|
|
26970
|
+
console.error(`Valid categories: ${known.join(", ")}`);
|
|
26971
|
+
return 4;
|
|
26972
|
+
}
|
|
26973
|
+
async function listToolsInCategory(category, emitJson) {
|
|
26974
|
+
const client2 = new DeeplineClient();
|
|
26975
|
+
const rawTools = await client2.listTools({
|
|
26976
|
+
categories: category,
|
|
26977
|
+
compact: false
|
|
26978
|
+
});
|
|
26979
|
+
const allTools = await client2.listTools({ compact: true });
|
|
26980
|
+
const summaries = aggregateCategorySummaries(allTools);
|
|
26981
|
+
if (!summaries.some((item) => item.name === category)) {
|
|
26982
|
+
return unknownCategoryError(category, summaries, emitJson);
|
|
26983
|
+
}
|
|
26984
|
+
const rows = rawTools.filter((tool) => tool.categories?.includes(category)).map((tool) => ({
|
|
26985
|
+
id: tool.toolId,
|
|
26986
|
+
provider: tool.provider,
|
|
26987
|
+
required: requiredInputIds(tool),
|
|
26988
|
+
pricing: shortPricingHint(tool),
|
|
26989
|
+
description: firstSentence(tool.description)
|
|
26990
|
+
})).sort((a, b) => a.id.localeCompare(b.id));
|
|
26991
|
+
const idWidth = rows.reduce((max, row) => Math.max(max, row.id.length), 0);
|
|
26992
|
+
const render = {
|
|
26993
|
+
sections: [
|
|
26994
|
+
{
|
|
26995
|
+
title: `${rows.length} tools in ${category}:`,
|
|
26996
|
+
lines: rows.map((row) => {
|
|
26997
|
+
const id = row.id.padEnd(idWidth);
|
|
26998
|
+
const required = row.required.length ? `(${row.required.join(", ")})` : "(no required inputs)";
|
|
26999
|
+
const pricing = row.pricing ? ` [${row.pricing}]` : "";
|
|
27000
|
+
const description = row.description ? ` - ${row.description}` : "";
|
|
27001
|
+
return `${id} ${required}${pricing}${description}`;
|
|
27002
|
+
})
|
|
27003
|
+
},
|
|
27004
|
+
{
|
|
27005
|
+
title: "next",
|
|
27006
|
+
lines: [
|
|
27007
|
+
"Run `deepline tools describe <toolId>` for the full contract."
|
|
27008
|
+
]
|
|
27009
|
+
}
|
|
27010
|
+
]
|
|
27011
|
+
};
|
|
27012
|
+
printCommandEnvelope(
|
|
27013
|
+
{
|
|
27014
|
+
category,
|
|
27015
|
+
total: rows.length,
|
|
27016
|
+
tools: rows,
|
|
27017
|
+
commandTemplates: TOOL_COMMAND_TEMPLATES,
|
|
27018
|
+
render
|
|
27019
|
+
},
|
|
27020
|
+
{ json: emitJson }
|
|
27021
|
+
);
|
|
27022
|
+
return 0;
|
|
27023
|
+
}
|
|
27024
|
+
async function listToolsForCategoryFilter(requestedCategories, emitJson, compact) {
|
|
26834
27025
|
const client2 = new DeeplineClient();
|
|
26835
|
-
const categoryArgIndex = args.findIndex((arg) => arg === "--categories");
|
|
26836
|
-
const categoryFilter = categoryArgIndex >= 0 ? args[categoryArgIndex + 1] : "";
|
|
26837
|
-
const compact = !args.includes("--full");
|
|
26838
|
-
const requestedCategories = categoryFilter ? categoryFilter.split(",").map((item) => item.trim()).filter(Boolean) : [];
|
|
26839
27026
|
const items = (await client2.listTools({
|
|
26840
|
-
|
|
27027
|
+
categories: requestedCategories.join(","),
|
|
26841
27028
|
compact
|
|
26842
27029
|
})).map(toListedTool).filter(
|
|
26843
|
-
(item) => requestedCategories.
|
|
27030
|
+
(item) => requestedCategories.some(
|
|
26844
27031
|
(category) => item.categories.includes(category)
|
|
26845
27032
|
)
|
|
26846
27033
|
);
|
|
26847
|
-
const emptyResult = items.length === 0
|
|
27034
|
+
const emptyResult = items.length === 0 ? zeroMatchToolGuidance({ categories: requestedCategories }) : null;
|
|
26848
27035
|
const render = {
|
|
26849
27036
|
sections: emptyResult ? zeroMatchRender(emptyResult).sections : [
|
|
26850
27037
|
{
|
|
@@ -26875,10 +27062,41 @@ async function listTools(args) {
|
|
|
26875
27062
|
commandTemplates: TOOL_COMMAND_TEMPLATES,
|
|
26876
27063
|
render
|
|
26877
27064
|
},
|
|
26878
|
-
{ json:
|
|
27065
|
+
{ json: emitJson }
|
|
26879
27066
|
);
|
|
26880
27067
|
return 0;
|
|
26881
27068
|
}
|
|
27069
|
+
async function listTools(category, options = {}) {
|
|
27070
|
+
const positional = category?.trim() ?? "";
|
|
27071
|
+
const flagCategories = (options.categories ?? "").split(",").map((item) => item.trim()).filter(Boolean);
|
|
27072
|
+
const compact = options.compact !== false;
|
|
27073
|
+
const emitJson = options.json === true || shouldEmitJson();
|
|
27074
|
+
if (positional && flagCategories.length > 0) {
|
|
27075
|
+
const flagIsSameSingle = flagCategories.length === 1 && flagCategories[0] === positional;
|
|
27076
|
+
if (!flagIsSameSingle) {
|
|
27077
|
+
const message = `Category "${positional}" and --categories ${flagCategories.join(",")} disagree. Pass one: deepline tools list ${positional}`;
|
|
27078
|
+
if (emitJson) {
|
|
27079
|
+
printJson({
|
|
27080
|
+
ok: false,
|
|
27081
|
+
exitCode: 2,
|
|
27082
|
+
code: "TOOL_LIST_CATEGORY_CONFLICT",
|
|
27083
|
+
message,
|
|
27084
|
+
next: `deepline tools list ${positional}`
|
|
27085
|
+
});
|
|
27086
|
+
} else {
|
|
27087
|
+
console.error(message);
|
|
27088
|
+
}
|
|
27089
|
+
return 2;
|
|
27090
|
+
}
|
|
27091
|
+
}
|
|
27092
|
+
if (positional) {
|
|
27093
|
+
return listToolsInCategory(positional, emitJson);
|
|
27094
|
+
}
|
|
27095
|
+
if (flagCategories.length > 0) {
|
|
27096
|
+
return listToolsForCategoryFilter(flagCategories, emitJson, compact);
|
|
27097
|
+
}
|
|
27098
|
+
return listToolCategories(emitJson, compact);
|
|
27099
|
+
}
|
|
26882
27100
|
async function searchTools(queryInput, options = {}) {
|
|
26883
27101
|
const query = queryInput?.trim() ?? "";
|
|
26884
27102
|
const hasStructuredSearch = Boolean(
|
|
@@ -27077,27 +27295,37 @@ Output:
|
|
|
27077
27295
|
Use execute to run a tool.
|
|
27078
27296
|
`
|
|
27079
27297
|
);
|
|
27080
|
-
tools.command("list").description("
|
|
27298
|
+
tools.command("list [category]").description("Browse tool categories, or list every tool in a category.").addHelpText(
|
|
27081
27299
|
"after",
|
|
27082
27300
|
`
|
|
27083
27301
|
Notes:
|
|
27084
|
-
|
|
27085
|
-
|
|
27302
|
+
Bare \`tools list\` prints the category enumeration: one line per category with
|
|
27303
|
+
its tool count and definition. Pass a category to list every tool in it, one
|
|
27304
|
+
succinct row each (required inputs, Deepline pricing hint, first sentence).
|
|
27305
|
+
The listing is exhaustive and never truncated. Use search for ranked discovery
|
|
27306
|
+
by intent, aliases, descriptions, and schema fields.
|
|
27307
|
+
|
|
27308
|
+
--categories is a back-compat inventory filter. Passing it alone returns the
|
|
27309
|
+
legacy flat inventory envelope (one row per tool). The positional category is
|
|
27310
|
+
the newer exhaustive per-category view. If both are given they must name the
|
|
27311
|
+
same category (the positional view wins); otherwise it is a usage error.
|
|
27086
27312
|
|
|
27087
27313
|
Examples:
|
|
27088
27314
|
deepline tools list
|
|
27315
|
+
deepline tools list email_finder
|
|
27316
|
+
deepline tools list email_finder --json
|
|
27089
27317
|
deepline tools list --categories email_finder --json
|
|
27090
27318
|
deepline tools search email --json
|
|
27091
27319
|
`
|
|
27092
27320
|
).option(
|
|
27093
27321
|
"--categories <categories>",
|
|
27094
|
-
"Comma-separated categories
|
|
27095
|
-
).option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
|
|
27096
|
-
process.exitCode = await listTools(
|
|
27097
|
-
|
|
27098
|
-
|
|
27099
|
-
|
|
27100
|
-
|
|
27322
|
+
"Comma-separated categories filter (back-compat alias for the positional)"
|
|
27323
|
+
).option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (category, options) => {
|
|
27324
|
+
process.exitCode = await listTools(category, {
|
|
27325
|
+
categories: typeof options.categories === "string" ? options.categories : void 0,
|
|
27326
|
+
compact: options.compact !== false,
|
|
27327
|
+
json: Boolean(options.json)
|
|
27328
|
+
});
|
|
27101
27329
|
});
|
|
27102
27330
|
const addToolSearchCommand = (command) => command.description(
|
|
27103
27331
|
"Search available tools by intent query or structured filters."
|
package/dist/index.js
CHANGED
|
@@ -435,7 +435,7 @@ var SDK_RELEASE = {
|
|
|
435
435
|
// Deepline-native radars. Older clients must update before discovering,
|
|
436
436
|
// checking, or deploying an unlaunched monitor integration.
|
|
437
437
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
438
|
-
version: "0.1.
|
|
438
|
+
version: "0.1.262",
|
|
439
439
|
apiContract: "2026-07-native-monitor-launch-hard-cutover",
|
|
440
440
|
supportPolicy: {
|
|
441
441
|
minimumSupported: "0.1.53",
|
package/dist/index.mjs
CHANGED
|
@@ -365,7 +365,7 @@ var SDK_RELEASE = {
|
|
|
365
365
|
// Deepline-native radars. Older clients must update before discovering,
|
|
366
366
|
// checking, or deploying an unlaunched monitor integration.
|
|
367
367
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
368
|
-
version: "0.1.
|
|
368
|
+
version: "0.1.262",
|
|
369
369
|
apiContract: "2026-07-native-monitor-launch-hard-cutover",
|
|
370
370
|
supportPolicy: {
|
|
371
371
|
minimumSupported: "0.1.53",
|