@meltstudio/meltctl 4.192.0 → 4.193.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 +130 -96
  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.192.0";
17
+ CLI_VERSION = "4.193.0";
18
18
  }
19
19
  });
20
20
 
@@ -723,10 +723,6 @@ 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);
730
726
  if (filters?.status)
731
727
  params.set("status", filters.status);
732
728
  if (filters?.severity)
@@ -788,20 +784,6 @@ function createFindingsResource(config) {
788
784
  throw new Error(errMessage ?? `Failed to fetch findings stats (${status})`);
789
785
  }
790
786
  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;
805
787
  }
806
788
  };
807
789
  }
@@ -1531,6 +1513,67 @@ function createEndpointChecksResource(config) {
1531
1513
  };
1532
1514
  }
1533
1515
 
1516
+ // ../sdk/dist/resources/profile-audits.js
1517
+ function createProfileAuditsResource(config) {
1518
+ return {
1519
+ async list(filters) {
1520
+ const params = new URLSearchParams();
1521
+ if (filters?.personEmail)
1522
+ params.set("personEmail", filters.personEmail);
1523
+ if (filters?.status)
1524
+ params.set("status", filters.status);
1525
+ if (filters?.severity)
1526
+ params.set("severity", filters.severity);
1527
+ if (filters?.checkCode)
1528
+ params.set("checkCode", filters.checkCode);
1529
+ if (filters?.limit)
1530
+ params.set("limit", String(filters.limit));
1531
+ const query = params.toString();
1532
+ const path9 = `/profile-audits${query ? `?${query}` : ""}`;
1533
+ const { data, status } = await apiFetch(config, path9);
1534
+ if (status === 403)
1535
+ throw new Error("Access denied. Only Team Managers can list profile audits.");
1536
+ if (status !== 200)
1537
+ throw new Error(data.error ?? `Failed to list profile audits (${status})`);
1538
+ return data;
1539
+ },
1540
+ async getStatsByPerson() {
1541
+ const { data, status } = await apiFetch(config, "/profile-audits/stats/by-person");
1542
+ if (status === 403)
1543
+ throw new Error("Access denied. Only Team Managers can view profile audit stats.");
1544
+ if (status !== 200) {
1545
+ const errMessage = data && typeof data === "object" && "error" in data ? data.error : void 0;
1546
+ throw new Error(errMessage ?? `Failed to fetch profile audit stats (${status})`);
1547
+ }
1548
+ return data;
1549
+ },
1550
+ /** Read whether the on-demand "Run audit" button is currently
1551
+ * clickable, along with the last-run timestamp + cooldown window
1552
+ * the dashboard renders. Manager-only. */
1553
+ async getRunStatus() {
1554
+ const { data, status } = await apiFetch(config, "/profile-audits/status");
1555
+ if (status === 403)
1556
+ throw new Error("Access denied. Only Team Managers can read profile audit status.");
1557
+ if (status !== 200)
1558
+ throw new Error(data.error ?? `Failed to fetch profile audit status (${status})`);
1559
+ return data;
1560
+ },
1561
+ /** Enqueue a one-off profile audit run. Returns the new job id +
1562
+ * the refreshed status (so the button can flip to disabled on the
1563
+ * client without waiting for a re-fetch). Resolves with the
1564
+ * cooldown / in-flight payload on 429 so the dashboard can render
1565
+ * the same disabled-with-reason UI without a special error path. */
1566
+ async runNow() {
1567
+ const { data, status } = await apiFetch(config, "/profile-audits/run", { method: "POST" });
1568
+ if (status === 403)
1569
+ throw new Error("Access denied. Only Team Managers can run profile audits.");
1570
+ if (status !== 202 && status !== 429)
1571
+ throw new Error(data.error ?? `Failed to start profile audit (${status})`);
1572
+ return data;
1573
+ }
1574
+ };
1575
+ }
1576
+
1534
1577
  // ../sdk/dist/client.js
1535
1578
  async function apiFetch(config, path9, options = {}) {
1536
1579
  const response = await fetch(`${config.baseUrl}${path9}`, {
@@ -1565,7 +1608,8 @@ function createMeltClient(config) {
1565
1608
  chat: createChatResource(config),
1566
1609
  me: createMeResource(config),
1567
1610
  developers: createDevelopersResource(config),
1568
- endpointChecks: createEndpointChecksResource(config)
1611
+ endpointChecks: createEndpointChecksResource(config),
1612
+ profileAudits: createProfileAuditsResource(config)
1569
1613
  };
1570
1614
  }
1571
1615
 
@@ -1573,13 +1617,7 @@ function createMeltClient(config) {
1573
1617
  import { z } from "zod";
1574
1618
  var auditFindingSchema = z.object({
1575
1619
  id: 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(),
1620
+ repository: z.string(),
1583
1621
  project: z.string(),
1584
1622
  auditType: z.string(),
1585
1623
  catalogCode: z.string().nullable(),
@@ -1631,12 +1669,6 @@ var findingsStatsSchema = z.object({
1631
1669
  });
1632
1670
  var findingsListFiltersSchema = z.object({
1633
1671
  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(),
1640
1672
  status: z.string().optional(),
1641
1673
  severity: z.string().optional(),
1642
1674
  effort: z.string().optional(),
@@ -1652,14 +1684,6 @@ var findingsStatsByRepositoryEntrySchema = findingsStatsSchema.extend({
1652
1684
  repository: z.string()
1653
1685
  });
1654
1686
  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);
1663
1687
  var extractionResultSchema = z.object({
1664
1688
  auditId: z.string(),
1665
1689
  findingsExtracted: z.number(),
@@ -4004,10 +4028,6 @@ function createFindingsResource2(config) {
4004
4028
  const params = new URLSearchParams();
4005
4029
  if (filters?.repository)
4006
4030
  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);
4011
4031
  if (filters?.status)
4012
4032
  params.set("status", filters.status);
4013
4033
  if (filters?.severity)
@@ -4069,20 +4089,6 @@ function createFindingsResource2(config) {
4069
4089
  throw new Error(errMessage ?? `Failed to fetch findings stats (${status})`);
4070
4090
  }
4071
4091
  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;
4086
4092
  }
4087
4093
  };
4088
4094
  }
@@ -4793,6 +4799,65 @@ function createEndpointChecksResource2(config) {
4793
4799
  }
4794
4800
  };
4795
4801
  }
4802
+ function createProfileAuditsResource2(config) {
4803
+ return {
4804
+ async list(filters) {
4805
+ const params = new URLSearchParams();
4806
+ if (filters?.personEmail)
4807
+ params.set("personEmail", filters.personEmail);
4808
+ if (filters?.status)
4809
+ params.set("status", filters.status);
4810
+ if (filters?.severity)
4811
+ params.set("severity", filters.severity);
4812
+ if (filters?.checkCode)
4813
+ params.set("checkCode", filters.checkCode);
4814
+ if (filters?.limit)
4815
+ params.set("limit", String(filters.limit));
4816
+ const query = params.toString();
4817
+ const path22 = `/profile-audits${query ? `?${query}` : ""}`;
4818
+ const { data, status } = await apiFetch2(config, path22);
4819
+ if (status === 403)
4820
+ throw new Error("Access denied. Only Team Managers can list profile audits.");
4821
+ if (status !== 200)
4822
+ throw new Error(data.error ?? `Failed to list profile audits (${status})`);
4823
+ return data;
4824
+ },
4825
+ async getStatsByPerson() {
4826
+ const { data, status } = await apiFetch2(config, "/profile-audits/stats/by-person");
4827
+ if (status === 403)
4828
+ throw new Error("Access denied. Only Team Managers can view profile audit stats.");
4829
+ if (status !== 200) {
4830
+ const errMessage = data && typeof data === "object" && "error" in data ? data.error : void 0;
4831
+ throw new Error(errMessage ?? `Failed to fetch profile audit stats (${status})`);
4832
+ }
4833
+ return data;
4834
+ },
4835
+ /** Read whether the on-demand "Run audit" button is currently
4836
+ * clickable, along with the last-run timestamp + cooldown window
4837
+ * the dashboard renders. Manager-only. */
4838
+ async getRunStatus() {
4839
+ const { data, status } = await apiFetch2(config, "/profile-audits/status");
4840
+ if (status === 403)
4841
+ throw new Error("Access denied. Only Team Managers can read profile audit status.");
4842
+ if (status !== 200)
4843
+ throw new Error(data.error ?? `Failed to fetch profile audit status (${status})`);
4844
+ return data;
4845
+ },
4846
+ /** Enqueue a one-off profile audit run. Returns the new job id +
4847
+ * the refreshed status (so the button can flip to disabled on the
4848
+ * client without waiting for a re-fetch). Resolves with the
4849
+ * cooldown / in-flight payload on 429 so the dashboard can render
4850
+ * the same disabled-with-reason UI without a special error path. */
4851
+ async runNow() {
4852
+ const { data, status } = await apiFetch2(config, "/profile-audits/run", { method: "POST" });
4853
+ if (status === 403)
4854
+ throw new Error("Access denied. Only Team Managers can run profile audits.");
4855
+ if (status !== 202 && status !== 429)
4856
+ throw new Error(data.error ?? `Failed to start profile audit (${status})`);
4857
+ return data;
4858
+ }
4859
+ };
4860
+ }
4796
4861
  async function apiFetch2(config, path22, options = {}) {
4797
4862
  const response = await fetch(`${config.baseUrl}${path22}`, {
4798
4863
  ...options,
@@ -4826,18 +4891,13 @@ function createMeltClient2(config) {
4826
4891
  chat: createChatResource2(config),
4827
4892
  me: createMeResource2(config),
4828
4893
  developers: createDevelopersResource2(config),
4829
- endpointChecks: createEndpointChecksResource2(config)
4894
+ endpointChecks: createEndpointChecksResource2(config),
4895
+ profileAudits: createProfileAuditsResource2(config)
4830
4896
  };
4831
4897
  }
4832
4898
  var auditFindingSchema2 = z2.object({
4833
4899
  id: 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(),
4900
+ repository: z2.string(),
4841
4901
  project: z2.string(),
4842
4902
  auditType: z2.string(),
4843
4903
  catalogCode: z2.string().nullable(),
@@ -4889,12 +4949,6 @@ var findingsStatsSchema2 = z2.object({
4889
4949
  });
4890
4950
  var findingsListFiltersSchema2 = z2.object({
4891
4951
  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(),
4898
4952
  status: z2.string().optional(),
4899
4953
  severity: z2.string().optional(),
4900
4954
  effort: z2.string().optional(),
@@ -4910,14 +4964,6 @@ var findingsStatsByRepositoryEntrySchema2 = findingsStatsSchema2.extend({
4910
4964
  repository: z2.string()
4911
4965
  });
4912
4966
  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);
4921
4967
  var extractionResultSchema2 = z2.object({
4922
4968
  auditId: z2.string(),
4923
4969
  findingsExtracted: z2.number(),
@@ -5979,14 +6025,10 @@ async function listFindings(client, input3 = {}) {
5979
6025
  var listFindingsInputSchema = z10.object({
5980
6026
  projectId: z10.number().int().positive().optional(),
5981
6027
  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(),
5986
6028
  status: z10.enum(["pass", "warning", "missing", "na"]).optional(),
5987
6029
  severity: z10.enum(["critical", "high", "medium", "low"]).optional(),
5988
6030
  effort: z10.enum(["low", "medium", "high", "unknown"]).optional(),
5989
- auditType: z10.enum(["audit", "ux-audit", "security-audit", "profile-audit"]).optional(),
6031
+ auditType: z10.enum(["audit", "ux-audit", "security-audit"]).optional(),
5990
6032
  limit: z10.number().int().positive().max(500).optional()
5991
6033
  });
5992
6034
  function registerFindingsTools(server, getClient2) {
@@ -5994,24 +6036,16 @@ function registerFindingsTools(server, getClient2) {
5994
6036
  "list_findings",
5995
6037
  {
5996
6038
  title: "List audit findings",
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.",
6039
+ 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.",
5998
6040
  inputSchema: {
5999
6041
  projectId: z10.number().int().positive().optional().describe("Strapi project id \u2014 scopes findings to that project\u2019s repos."),
6000
6042
  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
- ),
6007
6043
  status: z10.enum(["pass", "warning", "missing", "na"]).optional().describe("Filter by check status. 'missing' = the check failed outright."),
6008
6044
  severity: z10.enum(["critical", "high", "medium", "low"]).optional(),
6009
6045
  effort: z10.enum(["low", "medium", "high", "unknown"]).optional().describe(
6010
6046
  "Remediation effort. Combine effort=low with a high severity to find quick wins. 'unknown' = pass/na or not yet rated."
6011
6047
  ),
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
- ),
6048
+ auditType: z10.enum(["audit", "ux-audit", "security-audit"]).optional(),
6015
6049
  limit: z10.number().int().positive().max(500).optional()
6016
6050
  }
6017
6051
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meltstudio/meltctl",
3
- "version": "4.192.0",
3
+ "version": "4.193.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",