securewithtrace 0.11.0 → 0.12.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.
Files changed (3) hide show
  1. package/README.md +14 -0
  2. package/dist/index.js +75 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -53,6 +53,7 @@ tracecli vulnerabilities list --severity HIGH
53
53
 
54
54
  - **Authenticate securely** with device authorization flow (`auth login/logout/status`)
55
55
  - **List and filter repositories** connected to your Trace organization (`repo list`, `repo filter`)
56
+ - **Find repositories by dependency** with optional version filtering (`repo list --dependency`)
56
57
  - **Clone repositories** with secure token handling (`repo clone`)
57
58
  - **Filter vulnerabilities** by repo, severity, and status (`vulnerabilities list`)
58
59
  - **Export results as JSON or TSV** for automation (`vulnerabilities list --output json`)
@@ -82,6 +83,18 @@ tracecli repo list --filter "platform=GITHUB" --filter "repo:trace" --filter "st
82
83
  # Alias command for filtering
83
84
  tracecli repo filter --filter "language:typescript" --filter "branch=main"
84
85
 
86
+ # Find repositories that use a specific dependency
87
+ tracecli repo list --dependency lodash
88
+
89
+ # Filter by dependency at a specific version
90
+ tracecli repo list --dependency lodash@4.17.21
91
+
92
+ # Filter by scoped package with partial version match
93
+ tracecli repo list --dependency @types/node@20
94
+
95
+ # Dependency results as JSON
96
+ tracecli repo list --dependency react --json | jq '.[].fullName'
97
+
85
98
  # Clone by owner/repo shorthand
86
99
  tracecli repo clone securewithtrace/trace
87
100
 
@@ -136,6 +149,7 @@ Repository filter options:
136
149
  - `--filter`: repeatable advanced expression in the form `<field><operator><value>`
137
150
  - Supported fields: `platform`, `status`, `url`, `repo`, `branch`, `language`
138
151
  - Supported operators: `=` (exact), `!=` (not exact), `:` (contains), `!:` (not contains)
152
+ - `--dependency`: filter by dependency name with optional `@version` (e.g. `lodash`, `lodash@4.17`, `@types/node@20`)
139
153
 
140
154
  ### Pentests
141
155
 
package/dist/index.js CHANGED
@@ -25748,6 +25748,19 @@ function validateBranchName(branch) {
25748
25748
  }
25749
25749
  return branch;
25750
25750
  }
25751
+ function parseDependencyFilter(filter) {
25752
+ const isScoped = filter.startsWith("@");
25753
+ const separatorIndex = isScoped ? filter.indexOf("@", 1) : filter.indexOf("@");
25754
+ if (separatorIndex === -1) {
25755
+ return { name: filter };
25756
+ }
25757
+ const name = filter.slice(0, separatorIndex);
25758
+ const version2 = filter.slice(separatorIndex + 1);
25759
+ if (!name || !version2) {
25760
+ return { name: filter };
25761
+ }
25762
+ return { name, version: version2 };
25763
+ }
25751
25764
  function parseCloneDepth(value) {
25752
25765
  const depth = Number.parseInt(value, 10);
25753
25766
  if (!Number.isInteger(depth) || depth < 1) {
@@ -25958,11 +25971,18 @@ function addRepositoryFilterOptions(command) {
25958
25971
  "Advanced filter expression. Repeatable. Examples: platform=GITHUB, repo:trace, status!=DISCONNECTED, language!:typescript",
25959
25972
  collectFilterExpression,
25960
25973
  []
25961
- ).option("--json", "Output as JSON");
25974
+ ).option("--json", "Output as JSON").option(
25975
+ "--dependency <pkg>",
25976
+ "Filter repositories that use a dependency (e.g. lodash, lodash@4.17.21, @types/node@20)"
25977
+ );
25962
25978
  }
25963
25979
  async function runRepositoryListCommand(options) {
25964
- let filteredRepositories;
25965
25980
  const organizationId = await resolveOrganizationId();
25981
+ if (options.dependency) {
25982
+ await runDependencyFilter(organizationId, options);
25983
+ return;
25984
+ }
25985
+ let filteredRepositories;
25966
25986
  const result = await authenticatedRequest(
25967
25987
  (client) => client.repository.listRepositories({
25968
25988
  params: { organizationId }
@@ -25998,6 +26018,59 @@ async function runRepositoryListCommand(options) {
25998
26018
  console.log(`${url2} (${platform}, ${status})`);
25999
26019
  }
26000
26020
  }
26021
+ async function runDependencyFilter(organizationId, options) {
26022
+ const { name, version: version2 } = parseDependencyFilter(options.dependency);
26023
+ const result = await authenticatedRequest(
26024
+ (client) => client.dependency.searchDependencies({
26025
+ params: { organizationId },
26026
+ body: {
26027
+ query: name,
26028
+ ...version2 ? { versionPrefix: version2 } : {},
26029
+ pageSize: 100
26030
+ }
26031
+ })
26032
+ );
26033
+ if (result.status !== 200) {
26034
+ console.error(`Failed to search dependencies (status ${result.status}).`);
26035
+ process.exit(1);
26036
+ }
26037
+ const repoMap = /* @__PURE__ */ new Map();
26038
+ for (const pkg of result.body.packages) {
26039
+ if (pkg.name.toLowerCase() !== name.toLowerCase()) {
26040
+ continue;
26041
+ }
26042
+ for (const repo of pkg.repositories) {
26043
+ const existing = repoMap.get(repo.repositoryId);
26044
+ const versionStrings = repo.versions.map((v) => v.version);
26045
+ if (existing) {
26046
+ for (const v of versionStrings) {
26047
+ if (!existing.versions.includes(v)) {
26048
+ existing.versions.push(v);
26049
+ }
26050
+ }
26051
+ } else {
26052
+ repoMap.set(repo.repositoryId, {
26053
+ fullName: repo.fullName,
26054
+ versions: versionStrings
26055
+ });
26056
+ }
26057
+ }
26058
+ }
26059
+ const repos = Array.from(repoMap.values());
26060
+ if (repos.length === 0) {
26061
+ const label = version2 ? `${name}@${version2}` : name;
26062
+ console.log(`No repositories found using dependency '${label}'.`);
26063
+ return;
26064
+ }
26065
+ if (options.json) {
26066
+ console.log(JSON.stringify(repos, null, 2));
26067
+ return;
26068
+ }
26069
+ for (const repo of repos) {
26070
+ const versions = repo.versions.join(", ");
26071
+ console.log(`${repo.fullName} (${versions})`);
26072
+ }
26073
+ }
26001
26074
  function createListCommand2() {
26002
26075
  return addRepositoryFilterOptions(
26003
26076
  new Command("list").description("List repositories in your organization")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securewithtrace",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Official Trace CLI for vulnerability intelligence in your terminal",
5
5
  "type": "module",
6
6
  "bin": {