fullstackgtm 0.55.1 → 0.55.2
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.
- package/CHANGELOG.md +13 -0
- package/CONTRIBUTING.md +6 -0
- package/dist/cli/enrich.js +14 -3
- package/dist/cli/help.js +2 -2
- package/package.json +2 -2
- package/src/cli/enrich.ts +13 -3
- package/src/cli/help.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,19 @@ The path to 1.0 is planned in [docs/roadmap-to-1.0.md](https://github.com/fullst
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.55.2] — 2026-07-13
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- The OSS repository now publishes a representative contributor test suite
|
|
15
|
+
covering CLI contracts, planning, configuration, HTTP safety, and security,
|
|
16
|
+
while hosted, live-integration, and adversarial release tests remain private.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- OSS mirror generation and `npm test` now fail when zero public tests are
|
|
21
|
+
discovered, preventing false-green contributor and release checks.
|
|
22
|
+
|
|
10
23
|
## [0.55.1] — 2026-07-13
|
|
11
24
|
|
|
12
25
|
### Fixed
|
package/CONTRIBUTING.md
CHANGED
|
@@ -64,6 +64,12 @@ Linux, macOS, and Windows; source-level tests remain on Node 22.6+.
|
|
|
64
64
|
> (a `pretest` guard) rather than silently passing with zero tests. On the
|
|
65
65
|
> published mirror, `tests/` is present and `npm test` works there.
|
|
66
66
|
|
|
67
|
+
The public mirror includes a representative suite covering supported CLI,
|
|
68
|
+
planning, configuration, HTTP, and security behavior. Additional hosted-product,
|
|
69
|
+
live-integration, and adversarial release tests remain in the private monorepo;
|
|
70
|
+
both suites gate releases. The public test selection is reviewed explicitly in
|
|
71
|
+
`oss/public-tests.txt`, and `npm test` fails if the mirror contains zero tests.
|
|
72
|
+
|
|
67
73
|
**Node:** the published runtime supports Node ≥ 20 (`engines`), but the test
|
|
68
74
|
runner needs Node **≥ 22.6** for `--experimental-strip-types`. Develop on 22.6+.
|
|
69
75
|
|
package/dist/cli/enrich.js
CHANGED
|
@@ -44,7 +44,7 @@ enrich append [--source apollo] [--objects companies,contacts] [--save] [--conf
|
|
|
44
44
|
enrich refresh [--source apollo] [--stale-days <n>] [--save] [--config <path>]
|
|
45
45
|
[source options] [--run-label <label>] [--json]
|
|
46
46
|
enrich ingest <file.csv|payload.json|spool.jsonl|spool-dir> --source clay [--run-label <label>] [--objects companies|contacts] [--config <path>]
|
|
47
|
-
enrich acquire [--source <id>] [--max <new-leads>] [--scan-limit <candidates>] [--list <id>] [--assign-owner <id>] [--save] [--config <path>] [--json]
|
|
47
|
+
enrich acquire [--source <id>] [--max <new-leads>] [--scan-limit <candidates>] [--company-domain <domain>] [--list <id>] [--assign-owner <id>] [--save] [--config <path>] [--json]
|
|
48
48
|
enrich status [--runs] [--source <id>] [--config <path>] [--json]
|
|
49
49
|
|
|
50
50
|
acquire creates NET-NEW leads from a staged prospect list (ingest first):
|
|
@@ -515,8 +515,14 @@ async function acquireFromApi(config, source, rest, icp, snapshot, seen, priorRu
|
|
|
515
515
|
: disc.provider === "clay"
|
|
516
516
|
? (icp ? icpToClayPeopleFilters(icp) : (disc.filters ?? {}))
|
|
517
517
|
: {};
|
|
518
|
+
const targetCompanyDomain = option(rest, "--company-domain")?.trim().toLowerCase().replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/.*$/, "");
|
|
519
|
+
if (targetCompanyDomain) {
|
|
520
|
+
if (disc.provider !== "clay")
|
|
521
|
+
throw new Error("enrich acquire: --company-domain currently requires --source clay");
|
|
522
|
+
filters = { ...filters, company_identifier: [targetCompanyDomain] };
|
|
523
|
+
}
|
|
518
524
|
const queryFingerprint = createHash("sha256")
|
|
519
|
-
.update(JSON.stringify({ source, provider: disc.provider, listId, filters, icp: icp ?? null }))
|
|
525
|
+
.update(JSON.stringify({ source, provider: disc.provider, listId, filters, icp: icp ?? null, targetCompanyDomain: targetCompanyDomain ?? null }))
|
|
520
526
|
.digest("hex");
|
|
521
527
|
const checkpointKey = {
|
|
522
528
|
provider: disc.provider,
|
|
@@ -599,7 +605,7 @@ async function acquireFromApi(config, source, rest, icp, snapshot, seen, priorRu
|
|
|
599
605
|
if (!cursor) {
|
|
600
606
|
const route = clayRoutes[clayRouteIndex];
|
|
601
607
|
if (route)
|
|
602
|
-
filters = route.filters;
|
|
608
|
+
filters = { ...route.filters, ...(targetCompanyDomain ? { company_identifier: [targetCompanyDomain] } : {}) };
|
|
603
609
|
progress.note(`creating Clay people-search iterator · ${route?.id ?? "configured"}`);
|
|
604
610
|
cursor = await createClaySearch({ apiKey: providerKey("clay"), sourceType: "people", filters });
|
|
605
611
|
}
|
|
@@ -643,6 +649,8 @@ async function acquireFromApi(config, source, rest, icp, snapshot, seen, priorRu
|
|
|
643
649
|
}
|
|
644
650
|
discovered += page.length;
|
|
645
651
|
progress.items(discovered, scanLimit);
|
|
652
|
+
if (targetCompanyDomain)
|
|
653
|
+
page = page.filter((prospect) => normalizedCompanyDomain(prospect.companyDomain) === targetCompanyDomain);
|
|
646
654
|
if (page.length === 0) {
|
|
647
655
|
exhausted = true;
|
|
648
656
|
break;
|
|
@@ -885,6 +893,9 @@ function printAcquireOutput(options) {
|
|
|
885
893
|
console.log("The meter is charged only when a create lands at apply.");
|
|
886
894
|
}
|
|
887
895
|
}
|
|
896
|
+
function normalizedCompanyDomain(value) {
|
|
897
|
+
return (value ?? "").trim().toLowerCase().replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/.*$/, "");
|
|
898
|
+
}
|
|
888
899
|
function hostedRunsUrl() {
|
|
889
900
|
const baseUrl = getCredential("broker")?.baseUrl?.replace(/\/+$/, "");
|
|
890
901
|
return baseUrl ? `${baseUrl}/dashboard/runs` : null;
|
package/dist/cli/help.js
CHANGED
|
@@ -630,7 +630,7 @@ export const COMMAND_FLAGS = {
|
|
|
630
630
|
dedupe: [...SOURCE_FLAGS, "--key", "--keep", "--reason", "--max-operations", "--save", "--dry-run", "--verbose", "--json", "--out"],
|
|
631
631
|
reassign: [...SOURCE_FLAGS, "--from", "--assign-unowned", "--to", "--objects", "--where", "--except-deal-stage", "--include-closed-deals", "--reason", "--max-operations", "--save", "--dry-run", "--verbose", "--json", "--out"],
|
|
632
632
|
backfill: [...SOURCE_FLAGS, "--since", "--pipeline", "--match-property", "--skip-unmatched", "--save", "--dry-run", "--verbose", "--json"],
|
|
633
|
-
enrich: [...SOURCE_FLAGS, "--config", "--source", "--icp", "--input", "--provider", "--list", "--stale-days", "--assign-owner", "--objects", "--max", "--scan-limit", "--staged-run", "--run-label", "--label", "--runs", "--save", "--dry-run", "--verbose", "--json", "--out"],
|
|
633
|
+
enrich: [...SOURCE_FLAGS, "--config", "--source", "--icp", "--input", "--provider", "--list", "--stale-days", "--assign-owner", "--objects", "--max", "--scan-limit", "--company-domain", "--staged-run", "--run-label", "--label", "--runs", "--save", "--dry-run", "--verbose", "--json", "--out"],
|
|
634
634
|
call: [...SOURCE_FLAGS, "--transcript", "--title", "--source", "--model", "--deterministic", "--heuristics", "--llm", "--verbose", "--json", "--ndjson", "--out", "--call", "--call-type", "--rubric", "--list", "--list-rubrics", "--attendees", "--domain", "--deal", "--save", "--dry-run"],
|
|
635
635
|
suggest: [...SOURCE_FLAGS, "--plan-id", "--plan", "--json", "--out"],
|
|
636
636
|
plans: ["--status", "--operations", "--value", "--values-from", "--min-confidence", "--include-creates", "--acknowledge-uncertain-writes", "--verbose", "--json"],
|
|
@@ -645,7 +645,7 @@ export const COMMAND_FLAGS = {
|
|
|
645
645
|
schedule: ["--cron", "--label", "--provider", "--trigger", "--timer", "--runs", "--verbose", "--json"],
|
|
646
646
|
};
|
|
647
647
|
export const FLAGS_WITH_VALUES = new Set([
|
|
648
|
-
"--account", "--account-id", "--accounts", "--acv", "--acv-basis", "--after", "--anchor", "--api-key", "--approve", "--archive", "--assign-owner", "--attendees", "--before", "--bucket", "--buyers-per-account", "--call", "--call-type", "--calls", "--capture-run", "--category", "--channel", "--client", "--client-id", "--client-secret", "--config", "--connector", "--connector-opt", "--contact", "--cron", "--cross-checks", "--deal", "--deal-period", "--diff", "--domain", "--email", "--except-deal-stage", "--format", "--from", "--from-judge", "--golden", "--guard", "--icp", "--in", "--input", "--instance-url", "--keep", "--key", "--keywords", "--label", "--list", "--login-url", "--match", "--match-property", "--max", "--max-accounts", "--max-claims", "--max-credits", "--max-examples", "--max-operations", "--max-results", "--max-searches", "--max-usd", "--min-accuracy", "--min-confidence", "--min-mentions", "--min-score", "--model", "--name", "--objects", "--operations", "--out", "--pipeline", "--plan", "--plan-id", "--policy", "--port", "--prepared-by", "--prior-run", "--profile", "--promote-lift", "--prompt", "--provider", "--reason", "--require", "--result", "--rubric", "--rule", "--rules", "--run", "--run-label", "--runs", "--scan-limit", "--scopes", "--seed", "--set", "--signals-from", "--since", "--snapshot", "--source", "--staged-run", "--stale-days", "--status", "--task-account", "--task-deal", "--timer", "--title", "--to", "--today", "--token", "--token-env", "--touch", "--transcript", "--trigger", "--usd-per-credit", "--value", "--values-from", "--vendor", "--via", "--watchlist", "--where",
|
|
648
|
+
"--account", "--account-id", "--accounts", "--acv", "--acv-basis", "--after", "--anchor", "--api-key", "--approve", "--archive", "--assign-owner", "--attendees", "--before", "--bucket", "--buyers-per-account", "--call", "--call-type", "--calls", "--capture-run", "--category", "--channel", "--client", "--client-id", "--client-secret", "--company-domain", "--config", "--connector", "--connector-opt", "--contact", "--cron", "--cross-checks", "--deal", "--deal-period", "--diff", "--domain", "--email", "--except-deal-stage", "--format", "--from", "--from-judge", "--golden", "--guard", "--icp", "--in", "--input", "--instance-url", "--keep", "--key", "--keywords", "--label", "--list", "--login-url", "--match", "--match-property", "--max", "--max-accounts", "--max-claims", "--max-credits", "--max-examples", "--max-operations", "--max-results", "--max-searches", "--max-usd", "--min-accuracy", "--min-confidence", "--min-mentions", "--min-score", "--model", "--name", "--objects", "--operations", "--out", "--pipeline", "--plan", "--plan-id", "--policy", "--port", "--prepared-by", "--prior-run", "--profile", "--promote-lift", "--prompt", "--provider", "--reason", "--require", "--result", "--rubric", "--rule", "--rules", "--run", "--run-label", "--runs", "--scan-limit", "--scopes", "--seed", "--set", "--signals-from", "--since", "--snapshot", "--source", "--staged-run", "--stale-days", "--status", "--task-account", "--task-deal", "--timer", "--title", "--to", "--today", "--token", "--token-env", "--touch", "--transcript", "--trigger", "--usd-per-credit", "--value", "--values-from", "--vendor", "--via", "--watchlist", "--where",
|
|
649
649
|
]);
|
|
650
650
|
// Lifecycle-grouped front door. One line per verb, organized by the
|
|
651
651
|
// Prevent→Detect→Remediate→Verify loop so a new user sees ~6 jobs, not 22 verbs.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fullstackgtm",
|
|
3
|
-
"version": "0.55.
|
|
3
|
+
"version": "0.55.2",
|
|
4
4
|
"description": "Open-source agentic GTM ops framework: canonical GTM data model, pluggable deterministic audits, reviewable dry-run patch plans, approval-gated write-back with conflict detection, and cross-system entity resolution. HubSpot, Salesforce, and Stripe connectors included.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Full Stack GTM LLC <ryan@fullstackgtm.com> (https://fullstackgtm.com)",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"scripts": {
|
|
48
48
|
"clean": "node scripts/clean.mjs",
|
|
49
49
|
"build": "npm run clean && tsc -p tsconfig.build.json",
|
|
50
|
-
"pretest": "
|
|
50
|
+
"pretest": "node scripts/verify-public-tests.mjs",
|
|
51
51
|
"test": "node --experimental-strip-types --test tests/*.test.ts",
|
|
52
52
|
"verify:package": "npm run build && node scripts/verify-packed-install.mjs --with-peers",
|
|
53
53
|
"prepublishOnly": "npm run verify:package"
|
package/src/cli/enrich.ts
CHANGED
|
@@ -50,7 +50,7 @@ enrich append [--source apollo] [--objects companies,contacts] [--save] [--conf
|
|
|
50
50
|
enrich refresh [--source apollo] [--stale-days <n>] [--save] [--config <path>]
|
|
51
51
|
[source options] [--run-label <label>] [--json]
|
|
52
52
|
enrich ingest <file.csv|payload.json|spool.jsonl|spool-dir> --source clay [--run-label <label>] [--objects companies|contacts] [--config <path>]
|
|
53
|
-
enrich acquire [--source <id>] [--max <new-leads>] [--scan-limit <candidates>] [--list <id>] [--assign-owner <id>] [--save] [--config <path>] [--json]
|
|
53
|
+
enrich acquire [--source <id>] [--max <new-leads>] [--scan-limit <candidates>] [--company-domain <domain>] [--list <id>] [--assign-owner <id>] [--save] [--config <path>] [--json]
|
|
54
54
|
enrich status [--runs] [--source <id>] [--config <path>] [--json]
|
|
55
55
|
|
|
56
56
|
acquire creates NET-NEW leads from a staged prospect list (ingest first):
|
|
@@ -596,8 +596,13 @@ async function acquireFromApi(
|
|
|
596
596
|
: disc.provider === "clay"
|
|
597
597
|
? (icp ? icpToClayPeopleFilters(icp) : (disc.filters ?? {}))
|
|
598
598
|
: {};
|
|
599
|
+
const targetCompanyDomain = option(rest, "--company-domain")?.trim().toLowerCase().replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/.*$/, "");
|
|
600
|
+
if (targetCompanyDomain) {
|
|
601
|
+
if (disc.provider !== "clay") throw new Error("enrich acquire: --company-domain currently requires --source clay");
|
|
602
|
+
filters = { ...filters, company_identifier: [targetCompanyDomain] };
|
|
603
|
+
}
|
|
599
604
|
const queryFingerprint = createHash("sha256")
|
|
600
|
-
.update(JSON.stringify({ source, provider: disc.provider, listId, filters, icp: icp ?? null }))
|
|
605
|
+
.update(JSON.stringify({ source, provider: disc.provider, listId, filters, icp: icp ?? null, targetCompanyDomain: targetCompanyDomain ?? null }))
|
|
601
606
|
.digest("hex");
|
|
602
607
|
const checkpointKey: AcquireCheckpointKey = {
|
|
603
608
|
provider: disc.provider,
|
|
@@ -690,7 +695,7 @@ async function acquireFromApi(
|
|
|
690
695
|
while (true) {
|
|
691
696
|
if (!cursor) {
|
|
692
697
|
const route = clayRoutes[clayRouteIndex];
|
|
693
|
-
if (route) filters = route.filters;
|
|
698
|
+
if (route) filters = { ...route.filters, ...(targetCompanyDomain ? { company_identifier: [targetCompanyDomain] } : {}) };
|
|
694
699
|
progress.note(`creating Clay people-search iterator · ${route?.id ?? "configured"}`);
|
|
695
700
|
cursor = await createClaySearch({ apiKey: providerKey("clay"), sourceType: "people", filters });
|
|
696
701
|
}
|
|
@@ -730,6 +735,7 @@ async function acquireFromApi(
|
|
|
730
735
|
}
|
|
731
736
|
discovered += page.length;
|
|
732
737
|
progress.items(discovered, scanLimit);
|
|
738
|
+
if (targetCompanyDomain) page = page.filter((prospect) => normalizedCompanyDomain(prospect.companyDomain) === targetCompanyDomain);
|
|
733
739
|
if (page.length === 0) {
|
|
734
740
|
exhausted = true;
|
|
735
741
|
break;
|
|
@@ -1011,6 +1017,10 @@ function printAcquireOutput(options: {
|
|
|
1011
1017
|
}
|
|
1012
1018
|
}
|
|
1013
1019
|
|
|
1020
|
+
function normalizedCompanyDomain(value: string | undefined): string {
|
|
1021
|
+
return (value ?? "").trim().toLowerCase().replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/.*$/, "");
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1014
1024
|
function hostedRunsUrl(): string | null {
|
|
1015
1025
|
const baseUrl = getCredential("broker")?.baseUrl?.replace(/\/+$/, "");
|
|
1016
1026
|
return baseUrl ? `${baseUrl}/dashboard/runs` : null;
|
package/src/cli/help.ts
CHANGED
|
@@ -692,7 +692,7 @@ export const COMMAND_FLAGS: Record<string, string[]> = {
|
|
|
692
692
|
dedupe: [...SOURCE_FLAGS, "--key", "--keep", "--reason", "--max-operations", "--save", "--dry-run", "--verbose", "--json", "--out"],
|
|
693
693
|
reassign: [...SOURCE_FLAGS, "--from", "--assign-unowned", "--to", "--objects", "--where", "--except-deal-stage", "--include-closed-deals", "--reason", "--max-operations", "--save", "--dry-run", "--verbose", "--json", "--out"],
|
|
694
694
|
backfill: [...SOURCE_FLAGS, "--since", "--pipeline", "--match-property", "--skip-unmatched", "--save", "--dry-run", "--verbose", "--json"],
|
|
695
|
-
enrich: [...SOURCE_FLAGS, "--config", "--source", "--icp", "--input", "--provider", "--list", "--stale-days", "--assign-owner", "--objects", "--max", "--scan-limit", "--staged-run", "--run-label", "--label", "--runs", "--save", "--dry-run", "--verbose", "--json", "--out"],
|
|
695
|
+
enrich: [...SOURCE_FLAGS, "--config", "--source", "--icp", "--input", "--provider", "--list", "--stale-days", "--assign-owner", "--objects", "--max", "--scan-limit", "--company-domain", "--staged-run", "--run-label", "--label", "--runs", "--save", "--dry-run", "--verbose", "--json", "--out"],
|
|
696
696
|
call: [...SOURCE_FLAGS, "--transcript", "--title", "--source", "--model", "--deterministic", "--heuristics", "--llm", "--verbose", "--json", "--ndjson", "--out", "--call", "--call-type", "--rubric", "--list", "--list-rubrics", "--attendees", "--domain", "--deal", "--save", "--dry-run"],
|
|
697
697
|
suggest: [...SOURCE_FLAGS, "--plan-id", "--plan", "--json", "--out"],
|
|
698
698
|
plans: ["--status", "--operations", "--value", "--values-from", "--min-confidence", "--include-creates", "--acknowledge-uncertain-writes", "--verbose", "--json"],
|
|
@@ -708,7 +708,7 @@ export const COMMAND_FLAGS: Record<string, string[]> = {
|
|
|
708
708
|
};
|
|
709
709
|
|
|
710
710
|
export const FLAGS_WITH_VALUES = new Set([
|
|
711
|
-
"--account", "--account-id", "--accounts", "--acv", "--acv-basis", "--after", "--anchor", "--api-key", "--approve", "--archive", "--assign-owner", "--attendees", "--before", "--bucket", "--buyers-per-account", "--call", "--call-type", "--calls", "--capture-run", "--category", "--channel", "--client", "--client-id", "--client-secret", "--config", "--connector", "--connector-opt", "--contact", "--cron", "--cross-checks", "--deal", "--deal-period", "--diff", "--domain", "--email", "--except-deal-stage", "--format", "--from", "--from-judge", "--golden", "--guard", "--icp", "--in", "--input", "--instance-url", "--keep", "--key", "--keywords", "--label", "--list", "--login-url", "--match", "--match-property", "--max", "--max-accounts", "--max-claims", "--max-credits", "--max-examples", "--max-operations", "--max-results", "--max-searches", "--max-usd", "--min-accuracy", "--min-confidence", "--min-mentions", "--min-score", "--model", "--name", "--objects", "--operations", "--out", "--pipeline", "--plan", "--plan-id", "--policy", "--port", "--prepared-by", "--prior-run", "--profile", "--promote-lift", "--prompt", "--provider", "--reason", "--require", "--result", "--rubric", "--rule", "--rules", "--run", "--run-label", "--runs", "--scan-limit", "--scopes", "--seed", "--set", "--signals-from", "--since", "--snapshot", "--source", "--staged-run", "--stale-days", "--status", "--task-account", "--task-deal", "--timer", "--title", "--to", "--today", "--token", "--token-env", "--touch", "--transcript", "--trigger", "--usd-per-credit", "--value", "--values-from", "--vendor", "--via", "--watchlist", "--where",
|
|
711
|
+
"--account", "--account-id", "--accounts", "--acv", "--acv-basis", "--after", "--anchor", "--api-key", "--approve", "--archive", "--assign-owner", "--attendees", "--before", "--bucket", "--buyers-per-account", "--call", "--call-type", "--calls", "--capture-run", "--category", "--channel", "--client", "--client-id", "--client-secret", "--company-domain", "--config", "--connector", "--connector-opt", "--contact", "--cron", "--cross-checks", "--deal", "--deal-period", "--diff", "--domain", "--email", "--except-deal-stage", "--format", "--from", "--from-judge", "--golden", "--guard", "--icp", "--in", "--input", "--instance-url", "--keep", "--key", "--keywords", "--label", "--list", "--login-url", "--match", "--match-property", "--max", "--max-accounts", "--max-claims", "--max-credits", "--max-examples", "--max-operations", "--max-results", "--max-searches", "--max-usd", "--min-accuracy", "--min-confidence", "--min-mentions", "--min-score", "--model", "--name", "--objects", "--operations", "--out", "--pipeline", "--plan", "--plan-id", "--policy", "--port", "--prepared-by", "--prior-run", "--profile", "--promote-lift", "--prompt", "--provider", "--reason", "--require", "--result", "--rubric", "--rule", "--rules", "--run", "--run-label", "--runs", "--scan-limit", "--scopes", "--seed", "--set", "--signals-from", "--since", "--snapshot", "--source", "--staged-run", "--stale-days", "--status", "--task-account", "--task-deal", "--timer", "--title", "--to", "--today", "--token", "--token-env", "--touch", "--transcript", "--trigger", "--usd-per-credit", "--value", "--values-from", "--vendor", "--via", "--watchlist", "--where",
|
|
712
712
|
]);
|
|
713
713
|
|
|
714
714
|
// Lifecycle-grouped front door. One line per verb, organized by the
|