autotouch-cli 0.2.48__tar.gz → 0.2.49__tar.gz

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 (46) hide show
  1. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/PKG-INFO +5 -5
  2. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/README.md +4 -4
  3. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/data/CLI_REFERENCE.md +1 -1
  4. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/data/cli-manifest.json +1 -1
  5. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli.egg-info/PKG-INFO +5 -5
  6. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_shared/provider_registry.py +52 -13
  7. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/pyproject.toml +1 -1
  8. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/MANIFEST.in +0 -0
  9. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/__init__.py +0 -0
  10. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/cli.py +0 -0
  11. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/cli_contracts.py +0 -0
  12. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/__init__.py +0 -0
  13. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/auth.py +0 -0
  14. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/cells.py +0 -0
  15. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/columns.py +0 -0
  16. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/jobs.py +0 -0
  17. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/leads.py +0 -0
  18. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/linkedin.py +0 -0
  19. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/prompts.py +0 -0
  20. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/rows.py +0 -0
  21. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/search.py +0 -0
  22. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/sequences.py +0 -0
  23. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/tables.py +0 -0
  24. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/tasks.py +0 -0
  25. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/webhooks.py +0 -0
  26. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/commands/workspace_secrets.py +0 -0
  27. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/core/__init__.py +0 -0
  28. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/core/auth.py +0 -0
  29. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/core/config.py +0 -0
  30. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/core/http.py +0 -0
  31. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/core/io.py +0 -0
  32. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/core/output.py +0 -0
  33. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/core/polling.py +0 -0
  34. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/mongo_status.py +0 -0
  35. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/parser_groups.py +0 -0
  36. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/sequence_support.py +0 -0
  37. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli/templates.py +0 -0
  38. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli.egg-info/SOURCES.txt +0 -0
  39. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli.egg-info/dependency_links.txt +0 -0
  40. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli.egg-info/entry_points.txt +0 -0
  41. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli.egg-info/requires.txt +0 -0
  42. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_cli.egg-info/top_level.txt +0 -0
  43. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_shared/__init__.py +0 -0
  44. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_shared/linkedin_contract.py +0 -0
  45. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/autotouch_shared/search_contract.py +0 -0
  46. {autotouch_cli-0.2.48 → autotouch_cli-0.2.49}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: autotouch-cli
3
- Version: 0.2.48
3
+ Version: 0.2.49
4
4
  Summary: Autotouch Smart Table CLI
5
5
  Project-URL: Homepage, https://app.autotouch.ai
6
6
  Project-URL: Documentation, https://github.com/nicolonic/autotouch_main/tree/main/docs/research-table/reference
@@ -157,7 +157,7 @@ Only send `user_schema` / `response_schema` when you intentionally want to overr
157
157
 
158
158
  ## Docs
159
159
 
160
- - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/autotouch-cli.md
161
- - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/guides/autotouch-cli-agent-playbook.md
162
- - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/tables-api.md
163
- - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/platform/authentication.md
160
+ - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/research-table/reference/autotouch-cli.md
161
+ - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/research-table/guides/autotouch-cli-agent-playbook.md
162
+ - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/research-table/reference/tables-api.md
163
+ - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/platform/authentication.md
@@ -132,7 +132,7 @@ Only send `user_schema` / `response_schema` when you intentionally want to overr
132
132
 
133
133
  ## Docs
134
134
 
135
- - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/autotouch-cli.md
136
- - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/guides/autotouch-cli-agent-playbook.md
137
- - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/tables-api.md
138
- - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/platform/authentication.md
135
+ - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/research-table/reference/autotouch-cli.md
136
+ - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/research-table/guides/autotouch-cli-agent-playbook.md
137
+ - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/research-table/reference/tables-api.md
138
+ - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/platform/authentication.md
@@ -1,6 +1,6 @@
1
1
  # Autotouch CLI Reference
2
2
 
3
- Generated from the installed parser for `autotouch-cli` `0.2.48`.
3
+ Generated from the installed parser for `autotouch-cli` `0.2.49`.
4
4
  Manifest schema version: `2`.
5
5
 
6
6
  ## Output Modes
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.2.48",
2
+ "version": "0.2.49",
3
3
  "manifest_schema_version": 2,
4
4
  "entry_points": {
5
5
  "autotouch": "autotouch_cli.cli:main",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: autotouch-cli
3
- Version: 0.2.48
3
+ Version: 0.2.49
4
4
  Summary: Autotouch Smart Table CLI
5
5
  Project-URL: Homepage, https://app.autotouch.ai
6
6
  Project-URL: Documentation, https://github.com/nicolonic/autotouch_main/tree/main/docs/research-table/reference
@@ -157,7 +157,7 @@ Only send `user_schema` / `response_schema` when you intentionally want to overr
157
157
 
158
158
  ## Docs
159
159
 
160
- - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/autotouch-cli.md
161
- - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/guides/autotouch-cli-agent-playbook.md
162
- - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/tables-api.md
163
- - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/platform/authentication.md
160
+ - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/research-table/reference/autotouch-cli.md
161
+ - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/research-table/guides/autotouch-cli-agent-playbook.md
162
+ - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/research-table/reference/tables-api.md
163
+ - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.49/docs/platform/authentication.md
@@ -151,6 +151,12 @@ def _text(value: Any) -> str:
151
151
  return str(value or "").strip()
152
152
 
153
153
 
154
+ def _mapping_text(value: Any) -> str:
155
+ if isinstance(value, dict):
156
+ return _text(value.get("column"))
157
+ return _text(value)
158
+
159
+
154
160
  def _llm_provider_values() -> Tuple[str, ...]:
155
161
  return ("gemini", "xai", "openai", "anthropic", "groq")
156
162
 
@@ -515,6 +521,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
515
521
  },
516
522
  recipe_notes=(
517
523
  "For non-LinkedIn lookup, use lookupStrategy=domain/company with firstName+lastName+domain/company fields.",
524
+ "Primitive source columns map directly. If an upstream source column stores structured JSON, map it as an object with column + path, for example {\"column\": \"linkedin_lookup\", \"path\": \"linkedin_url\"}.",
518
525
  ),
519
526
  column_type={
520
527
  "type": "email_finder",
@@ -541,6 +548,13 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
541
548
  "strategy_field": "config.strategy",
542
549
  "lookup_strategy_field": "config.lookupStrategy",
543
550
  "input_fields": ["config.linkedinUrl", "config.firstName", "config.lastName", "config.company", "config.domain"],
551
+ "structured_source_mapping": {
552
+ "rule": "primitive columns map directly; structured columns use {column, path}",
553
+ "examples": [
554
+ {"linkedinUrl": {"column": "linkedin_lookup", "path": "linkedin_url"}},
555
+ {"emailColumn": {"column": "email_validation", "path": "response"}},
556
+ ],
557
+ },
544
558
  },
545
559
  composition_contract={
546
560
  "consumes": {
@@ -583,6 +597,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
583
597
  },
584
598
  recipe_notes=(
585
599
  "You can use linkedinUrl or email/workEmail/personalEmail inputs.",
600
+ "Primitive source columns map directly. If an upstream source column stores structured JSON, map it as an object with column + path, for example {\"column\": \"linkedin_lookup\", \"path\": \"linkedin_url\"}.",
586
601
  ),
587
602
  column_type={
588
603
  "type": "phone_finder",
@@ -616,6 +631,13 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
616
631
  "config.lastName",
617
632
  "config.company",
618
633
  ],
634
+ "structured_source_mapping": {
635
+ "rule": "primitive columns map directly; structured columns use {column, path}",
636
+ "examples": [
637
+ {"linkedinUrl": {"column": "linkedin_lookup", "path": "linkedin_url"}},
638
+ {"phoneColumn": {"column": "mobile_phone", "path": "mobile_number"}},
639
+ ],
640
+ },
619
641
  },
620
642
  composition_contract={
621
643
  "consumes": {
@@ -662,6 +684,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
662
684
  },
663
685
  recipe_notes=(
664
686
  "Add more targeting keys as needed (jobFunctions, seniorities, keywords, excludeKeywords, skills).",
687
+ "Primitive source columns map directly. If companyDomain or other mapped inputs come from structured JSON, use {\"column\": \"...\", \"path\": \"...\"} instead of a plain string column key.",
665
688
  ),
666
689
  column_type={
667
690
  "type": "lead_finder",
@@ -687,6 +710,12 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
687
710
  "source_mode_field": "config.sourceMode",
688
711
  "company_domain_field": "config.companyDomain",
689
712
  "max_results_field": "config.maxResults",
713
+ "structured_source_mapping": {
714
+ "rule": "primitive columns map directly; structured columns use {column, path}",
715
+ "examples": [
716
+ {"companyDomain": {"column": "company_lookup", "path": "domain"}},
717
+ ],
718
+ },
690
719
  },
691
720
  composition_contract={
692
721
  "consumes": {
@@ -758,7 +787,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
758
787
  "companyDomain is required; LinkedIn is optional.",
759
788
  "Include at least one usable hard-identity mapping such as LinkedIn, email, or phone.",
760
789
  "If companyDomain is missing in the table, derive or enrich that domain column first.",
761
- "Primitive source columns map directly. Structured JSON columns must specify an explicit path such as work_email.response or mobile_phone.mobile_number.",
790
+ "Primitive source columns map directly. If a mapped source column stores structured JSON, send an object with column + path, for example {\"column\": \"work_email\", \"path\": \"response\"} or {\"column\": \"mobile_phone\", \"path\": \"mobile_number\"}.",
762
791
  "Add to CRM is optional and non-billable.",
763
792
  "Creating add_to_crm after upstream email/phone/lead columns already finished does not replay those older source updates; run add_to_crm explicitly or rerun the upstream source column.",
764
793
  ),
@@ -785,18 +814,19 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
785
814
  "eligibility": "company domain plus at least one valid LinkedIn URL, email, or phone must resolve from mapped source columns",
786
815
  "replay_behavior": "source updates only; explicit run required to backfill older upstream results",
787
816
  "structured_source_mapping": {
788
- "rule": "primitive columns map directly; structured columns require explicit path",
789
- "field": "config.fieldMappings.*.path",
817
+ "rule": "primitive columns map directly; structured columns use {column, path}",
818
+ "field": "config.fieldMappings.*",
790
819
  "examples": [
791
- "emailAddresses[].path = response",
792
- "phoneNumbers[].path = mobile_number",
820
+ {"emailAddresses": [{"column": "work_email", "path": "response", "type": "work"}]},
821
+ {"phoneNumbers": [{"column": "mobile_phone", "path": "mobile_number", "type": "mobile"}]},
822
+ {"linkedinUrl": {"column": "linkedin_lookup", "path": "linkedin_url"}},
793
823
  ],
794
824
  },
795
825
  },
796
826
  composition_contract={
797
827
  "consumes": {
798
828
  "kind": "crm_export_inputs",
799
- "shape": "mapped source row values including company domain plus LinkedIn/email/phone identity; structured source columns must identify the exact JSON key via path",
829
+ "shape": "mapped source row values including company domain plus LinkedIn/email/phone identity; structured source columns use explicit {column, path} mappings to identify the exact field",
800
830
  },
801
831
  "produces": {
802
832
  "kind": "lead_ids",
@@ -1276,30 +1306,39 @@ def validate_column_provider_contract(
1276
1306
 
1277
1307
  if contract.key == "email_finder":
1278
1308
  if not any(
1279
- _text(cfg.get(field_name))
1280
- for field_name in ("linkedinUrl", "firstName", "lastName", "company", "domain")
1309
+ _mapping_text(cfg.get(field_name))
1310
+ for field_name in ("linkedinUrl", "firstName", "lastName", "company", "domain", "emailColumn")
1281
1311
  ):
1282
1312
  raise ProviderContractValidationError(
1283
1313
  "missing_required_field",
1284
- "email_finder requires at least one lookup input such as config.linkedinUrl, config.domain, or name/company fields.",
1314
+ "email_finder requires at least one lookup input such as config.linkedinUrl, config.domain, config.emailColumn, or name/company fields.",
1285
1315
  hint="Use `autotouch columns recipe --type email_finder`.",
1286
1316
  )
1287
1317
  return contract
1288
1318
 
1289
1319
  if contract.key == "phone_finder":
1290
1320
  if not any(
1291
- _text(cfg.get(field_name))
1292
- for field_name in ("linkedinUrl", "email", "workEmail", "personalEmail", "firstName", "lastName", "company")
1321
+ _mapping_text(cfg.get(field_name))
1322
+ for field_name in (
1323
+ "linkedinUrl",
1324
+ "email",
1325
+ "workEmail",
1326
+ "personalEmail",
1327
+ "firstName",
1328
+ "lastName",
1329
+ "company",
1330
+ "phoneColumn",
1331
+ )
1293
1332
  ):
1294
1333
  raise ProviderContractValidationError(
1295
1334
  "missing_required_field",
1296
- "phone_finder requires at least one lookup input such as config.linkedinUrl or config.email/workEmail.",
1335
+ "phone_finder requires at least one lookup input such as config.linkedinUrl, config.email/workEmail, or config.phoneColumn.",
1297
1336
  hint="Use `autotouch columns recipe --type phone_finder`.",
1298
1337
  )
1299
1338
  return contract
1300
1339
 
1301
1340
  if contract.key == "lead_finder":
1302
- if not _text(cfg.get("companyDomain")):
1341
+ if not _mapping_text(cfg.get("companyDomain")):
1303
1342
  raise ProviderContractValidationError(
1304
1343
  "missing_required_field",
1305
1344
  "lead_finder requires config.companyDomain.",
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "autotouch-cli"
7
- version = "0.2.48"
7
+ version = "0.2.49"
8
8
  description = "Autotouch Smart Table CLI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
File without changes