@meltstudio/meltctl 4.191.0 → 4.192.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 (2) hide show
  1. package/dist/index.js +94 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var CLI_VERSION;
14
14
  var init_version = __esm({
15
15
  "src/utils/version.ts"() {
16
16
  "use strict";
17
- CLI_VERSION = "4.191.0";
17
+ CLI_VERSION = "4.192.0";
18
18
  }
19
19
  });
20
20
 
@@ -723,6 +723,10 @@ function createFindingsResource(config) {
723
723
  const params = new URLSearchParams();
724
724
  if (filters?.repository)
725
725
  params.set("repository", filters.repository);
726
+ if (filters?.personEmail)
727
+ params.set("personEmail", filters.personEmail);
728
+ if (filters?.scope)
729
+ params.set("scope", filters.scope);
726
730
  if (filters?.status)
727
731
  params.set("status", filters.status);
728
732
  if (filters?.severity)
@@ -784,6 +788,20 @@ function createFindingsResource(config) {
784
788
  throw new Error(errMessage ?? `Failed to fetch findings stats (${status})`);
785
789
  }
786
790
  return data;
791
+ },
792
+ /**
793
+ * #419: per-person rollup for the /findings "By Person" tab. Manager-only;
794
+ * non-manager callers get an empty array (the server enforces).
795
+ */
796
+ async getStatsByPerson() {
797
+ const { data, status } = await apiFetch(config, "/findings/stats/by-person");
798
+ if (status === 403)
799
+ throw new Error("Access denied. Only Team Managers can view profile-audit stats.");
800
+ if (status !== 200) {
801
+ const errMessage = data && typeof data === "object" && "error" in data ? data.error : void 0;
802
+ throw new Error(errMessage ?? `Failed to fetch findings-by-person stats (${status})`);
803
+ }
804
+ return data;
787
805
  }
788
806
  };
789
807
  }
@@ -1555,7 +1573,13 @@ function createMeltClient(config) {
1555
1573
  import { z } from "zod";
1556
1574
  var auditFindingSchema = z.object({
1557
1575
  id: z.string(),
1558
- repository: z.string(),
1576
+ // Discriminator added with #419. 'project' is the original code/security/UX
1577
+ // shape — repository set, personEmail null. 'person' is the employee-profile
1578
+ // shape — personEmail set, repository null. Existing consumers can still
1579
+ // treat repository as the primary identity; the field is nullable now.
1580
+ scope: z.enum(["project", "person"]),
1581
+ repository: z.string().nullable(),
1582
+ personEmail: z.string().nullable(),
1559
1583
  project: z.string(),
1560
1584
  auditType: z.string(),
1561
1585
  catalogCode: z.string().nullable(),
@@ -1607,6 +1631,12 @@ var findingsStatsSchema = z.object({
1607
1631
  });
1608
1632
  var findingsListFiltersSchema = z.object({
1609
1633
  repository: z.string().optional(),
1634
+ // #419: filter to one employee's profile findings. Manager-only on the
1635
+ // server; non-manager callers passing this get an empty result.
1636
+ personEmail: z.string().optional(),
1637
+ // #419: 'project' | 'person'. Defaults to no filter when absent. Non-
1638
+ // managers cannot see scope='person' rows regardless of this value.
1639
+ scope: z.enum(["project", "person"]).optional(),
1610
1640
  status: z.string().optional(),
1611
1641
  severity: z.string().optional(),
1612
1642
  effort: z.string().optional(),
@@ -1622,6 +1652,14 @@ var findingsStatsByRepositoryEntrySchema = findingsStatsSchema.extend({
1622
1652
  repository: z.string()
1623
1653
  });
1624
1654
  var findingsStatsByRepositorySchema = z.array(findingsStatsByRepositoryEntrySchema);
1655
+ var findingsStatsByPersonEntrySchema = z.object({
1656
+ personEmail: z.string(),
1657
+ personName: z.string().nullable(),
1658
+ open: z.number(),
1659
+ worstSeverity: z.enum(["critical", "high", "medium", "low"]).nullable(),
1660
+ lastAuditedAt: z.string().nullable()
1661
+ });
1662
+ var findingsStatsByPersonSchema = z.array(findingsStatsByPersonEntrySchema);
1625
1663
  var extractionResultSchema = z.object({
1626
1664
  auditId: z.string(),
1627
1665
  findingsExtracted: z.number(),
@@ -3966,6 +4004,10 @@ function createFindingsResource2(config) {
3966
4004
  const params = new URLSearchParams();
3967
4005
  if (filters?.repository)
3968
4006
  params.set("repository", filters.repository);
4007
+ if (filters?.personEmail)
4008
+ params.set("personEmail", filters.personEmail);
4009
+ if (filters?.scope)
4010
+ params.set("scope", filters.scope);
3969
4011
  if (filters?.status)
3970
4012
  params.set("status", filters.status);
3971
4013
  if (filters?.severity)
@@ -4027,6 +4069,20 @@ function createFindingsResource2(config) {
4027
4069
  throw new Error(errMessage ?? `Failed to fetch findings stats (${status})`);
4028
4070
  }
4029
4071
  return data;
4072
+ },
4073
+ /**
4074
+ * #419: per-person rollup for the /findings "By Person" tab. Manager-only;
4075
+ * non-manager callers get an empty array (the server enforces).
4076
+ */
4077
+ async getStatsByPerson() {
4078
+ const { data, status } = await apiFetch2(config, "/findings/stats/by-person");
4079
+ if (status === 403)
4080
+ throw new Error("Access denied. Only Team Managers can view profile-audit stats.");
4081
+ if (status !== 200) {
4082
+ const errMessage = data && typeof data === "object" && "error" in data ? data.error : void 0;
4083
+ throw new Error(errMessage ?? `Failed to fetch findings-by-person stats (${status})`);
4084
+ }
4085
+ return data;
4030
4086
  }
4031
4087
  };
4032
4088
  }
@@ -4775,7 +4831,13 @@ function createMeltClient2(config) {
4775
4831
  }
4776
4832
  var auditFindingSchema2 = z2.object({
4777
4833
  id: z2.string(),
4778
- repository: z2.string(),
4834
+ // Discriminator added with #419. 'project' is the original code/security/UX
4835
+ // shape — repository set, personEmail null. 'person' is the employee-profile
4836
+ // shape — personEmail set, repository null. Existing consumers can still
4837
+ // treat repository as the primary identity; the field is nullable now.
4838
+ scope: z2.enum(["project", "person"]),
4839
+ repository: z2.string().nullable(),
4840
+ personEmail: z2.string().nullable(),
4779
4841
  project: z2.string(),
4780
4842
  auditType: z2.string(),
4781
4843
  catalogCode: z2.string().nullable(),
@@ -4827,6 +4889,12 @@ var findingsStatsSchema2 = z2.object({
4827
4889
  });
4828
4890
  var findingsListFiltersSchema2 = z2.object({
4829
4891
  repository: z2.string().optional(),
4892
+ // #419: filter to one employee's profile findings. Manager-only on the
4893
+ // server; non-manager callers passing this get an empty result.
4894
+ personEmail: z2.string().optional(),
4895
+ // #419: 'project' | 'person'. Defaults to no filter when absent. Non-
4896
+ // managers cannot see scope='person' rows regardless of this value.
4897
+ scope: z2.enum(["project", "person"]).optional(),
4830
4898
  status: z2.string().optional(),
4831
4899
  severity: z2.string().optional(),
4832
4900
  effort: z2.string().optional(),
@@ -4842,6 +4910,14 @@ var findingsStatsByRepositoryEntrySchema2 = findingsStatsSchema2.extend({
4842
4910
  repository: z2.string()
4843
4911
  });
4844
4912
  var findingsStatsByRepositorySchema2 = z2.array(findingsStatsByRepositoryEntrySchema2);
4913
+ var findingsStatsByPersonEntrySchema2 = z2.object({
4914
+ personEmail: z2.string(),
4915
+ personName: z2.string().nullable(),
4916
+ open: z2.number(),
4917
+ worstSeverity: z2.enum(["critical", "high", "medium", "low"]).nullable(),
4918
+ lastAuditedAt: z2.string().nullable()
4919
+ });
4920
+ var findingsStatsByPersonSchema2 = z2.array(findingsStatsByPersonEntrySchema2);
4845
4921
  var extractionResultSchema2 = z2.object({
4846
4922
  auditId: z2.string(),
4847
4923
  findingsExtracted: z2.number(),
@@ -5903,10 +5979,14 @@ async function listFindings(client, input3 = {}) {
5903
5979
  var listFindingsInputSchema = z10.object({
5904
5980
  projectId: z10.number().int().positive().optional(),
5905
5981
  repository: z10.string().optional(),
5982
+ // #419: filter to one employee's profile-audit findings. Manager-gated
5983
+ // server-side; non-manager callers get an empty result.
5984
+ personEmail: z10.string().email().optional(),
5985
+ scope: z10.enum(["project", "person"]).optional(),
5906
5986
  status: z10.enum(["pass", "warning", "missing", "na"]).optional(),
5907
5987
  severity: z10.enum(["critical", "high", "medium", "low"]).optional(),
5908
5988
  effort: z10.enum(["low", "medium", "high", "unknown"]).optional(),
5909
- auditType: z10.enum(["audit", "ux-audit", "security-audit"]).optional(),
5989
+ auditType: z10.enum(["audit", "ux-audit", "security-audit", "profile-audit"]).optional(),
5910
5990
  limit: z10.number().int().positive().max(500).optional()
5911
5991
  });
5912
5992
  function registerFindingsTools(server, getClient2) {
@@ -5914,16 +5994,24 @@ function registerFindingsTools(server, getClient2) {
5914
5994
  "list_findings",
5915
5995
  {
5916
5996
  title: "List audit findings",
5917
- description: "Lists code/security/UX audit findings. Each finding carries its check code, category, status (pass/warning/missing/na), severity (critical/high/medium/low), effort (low/medium/high \u2014 how much work the fix is, independent of severity), repository, and evidence (file/symbol) so you can see exactly what to fix. Filter by projectId, repository, status, severity, effort, or auditType. Results are ordered worst-first (missing > warning, then critical > high > \u2026). Use this to answer 'what's open on the app I'm working on?' \u2014 pass status='missing' or severity='critical' to focus on what matters, or effort='low' with severity='high'/'critical' to find cheap high-leverage wins. Read-only and open to any @meltstudio.co user.",
5997
+ description: "Lists code/security/UX audit findings, plus the People-Ops-facing Notion employee-profile audit (auditType='profile-audit', personEmail-keyed, manager-only). Each finding carries its check code, category, status (pass/warning/missing/na), severity (critical/high/medium/low), effort (low/medium/high \u2014 how much work the fix is, independent of severity), repository (project-scoped) or personEmail (person-scoped), and evidence (file/symbol or sentence) so you can see exactly what to fix. Filter by projectId, repository, personEmail, scope, status, severity, effort, or auditType. Results are ordered worst-first (missing > warning, then critical > high > \u2026). Profile-audit findings are filtered out for non-manager callers regardless of filters \u2014 they carry sensitive employee context. Read-only.",
5918
5998
  inputSchema: {
5919
5999
  projectId: z10.number().int().positive().optional().describe("Strapi project id \u2014 scopes findings to that project\u2019s repos."),
5920
6000
  repository: z10.string().optional().describe("Full repo slug, e.g. 'MeltStudio/atlas-api'. Scopes to a single repo."),
6001
+ personEmail: z10.string().email().optional().describe(
6002
+ "Scopes to one employee's profile-audit findings (#419). Manager-only \u2014 non-manager callers get an empty result."
6003
+ ),
6004
+ scope: z10.enum(["project", "person"]).optional().describe(
6005
+ "Filter by scope. 'project' = repo-scoped findings; 'person' = employee profile audits (manager-only)."
6006
+ ),
5921
6007
  status: z10.enum(["pass", "warning", "missing", "na"]).optional().describe("Filter by check status. 'missing' = the check failed outright."),
5922
6008
  severity: z10.enum(["critical", "high", "medium", "low"]).optional(),
5923
6009
  effort: z10.enum(["low", "medium", "high", "unknown"]).optional().describe(
5924
6010
  "Remediation effort. Combine effort=low with a high severity to find quick wins. 'unknown' = pass/na or not yet rated."
5925
6011
  ),
5926
- auditType: z10.enum(["audit", "ux-audit", "security-audit"]).optional(),
6012
+ auditType: z10.enum(["audit", "ux-audit", "security-audit", "profile-audit"]).optional().describe(
6013
+ "'audit' = tech, 'ux-audit' = UX, 'security-audit' = security, 'profile-audit' = employee Notion profile (manager-only)."
6014
+ ),
5927
6015
  limit: z10.number().int().positive().max(500).optional()
5928
6016
  }
5929
6017
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meltstudio/meltctl",
3
- "version": "4.191.0",
3
+ "version": "4.192.0",
4
4
  "description": "AI-first development tools for teams - set up AGENTS.md, Claude Code, Cursor, and OpenCode standards",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",