@superblocksteam/sdk 2.0.150-next.0 → 2.0.150-next.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.
Files changed (38) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/cli-replacement/dev.d.mts.map +1 -1
  3. package/dist/cli-replacement/dev.mjs +111 -8
  4. package/dist/cli-replacement/dev.mjs.map +1 -1
  5. package/dist/cli-replacement/install-packages.npm-registry.test.mjs +153 -0
  6. package/dist/cli-replacement/install-packages.npm-registry.test.mjs.map +1 -1
  7. package/dist/cli-replacement/npm-install-summary.d.mts +30 -0
  8. package/dist/cli-replacement/npm-install-summary.d.mts.map +1 -0
  9. package/dist/cli-replacement/npm-install-summary.mjs +67 -0
  10. package/dist/cli-replacement/npm-install-summary.mjs.map +1 -0
  11. package/dist/cli-replacement/npm-install-summary.test.d.mts +2 -0
  12. package/dist/cli-replacement/npm-install-summary.test.d.mts.map +1 -0
  13. package/dist/cli-replacement/npm-install-summary.test.mjs +70 -0
  14. package/dist/cli-replacement/npm-install-summary.test.mjs.map +1 -0
  15. package/dist/cli-replacement/npm-install-timing.d.mts +16 -0
  16. package/dist/cli-replacement/npm-install-timing.d.mts.map +1 -0
  17. package/dist/cli-replacement/npm-install-timing.mjs +104 -0
  18. package/dist/cli-replacement/npm-install-timing.mjs.map +1 -0
  19. package/dist/cli-replacement/npm-install-timing.test.d.mts +2 -0
  20. package/dist/cli-replacement/npm-install-timing.test.d.mts.map +1 -0
  21. package/dist/cli-replacement/npm-install-timing.test.mjs +151 -0
  22. package/dist/cli-replacement/npm-install-timing.test.mjs.map +1 -0
  23. package/dist/telemetry/logging.d.ts +7 -0
  24. package/dist/telemetry/logging.d.ts.map +1 -1
  25. package/dist/telemetry/logging.js +13 -0
  26. package/dist/telemetry/logging.js.map +1 -1
  27. package/dist/telemetry/logging.test.js +40 -0
  28. package/dist/telemetry/logging.test.js.map +1 -1
  29. package/package.json +6 -6
  30. package/src/cli-replacement/dev.mts +128 -10
  31. package/src/cli-replacement/install-packages.npm-registry.test.mts +235 -0
  32. package/src/cli-replacement/npm-install-summary.mts +82 -0
  33. package/src/cli-replacement/npm-install-summary.test.mts +94 -0
  34. package/src/cli-replacement/npm-install-timing.mts +121 -0
  35. package/src/cli-replacement/npm-install-timing.test.mts +199 -0
  36. package/src/telemetry/logging.test.ts +55 -0
  37. package/src/telemetry/logging.ts +21 -0
  38. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,151 @@
1
+ import nodeFs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import { consumeNpmInstallTimingAttributes } from "./npm-install-timing.mjs";
6
+ let logsDir;
7
+ beforeEach(async () => {
8
+ logsDir = await nodeFs.mkdtemp(path.join(os.tmpdir(), "npm-timing-"));
9
+ });
10
+ afterEach(async () => {
11
+ await nodeFs.rm(logsDir, { force: true, recursive: true });
12
+ });
13
+ /** Write a timing file using npm's own naming (`<log id>-timing.json`). */
14
+ async function writeTimingFile(logId, contents) {
15
+ const file = path.join(logsDir, `${logId}-timing.json`);
16
+ await nodeFs.writeFile(file, typeof contents === "string" ? contents : JSON.stringify(contents));
17
+ return file;
18
+ }
19
+ async function listTimingFiles() {
20
+ const entries = await nodeFs.readdir(logsDir);
21
+ return entries.filter((name) => name.endsWith("-timing.json"));
22
+ }
23
+ describe("consumeNpmInstallTimingAttributes", () => {
24
+ it("converts the whitelisted timers from milliseconds to seconds", async () => {
25
+ await writeTimingFile("2026-08-07T12_00_00_000Z", {
26
+ metadata: { version: "11.16.0" },
27
+ timers: {
28
+ idealTree: 230,
29
+ reify: 24500,
30
+ "reify:build": 90,
31
+ "reify:loadTrees": 400,
32
+ "reify:unpack": 23200,
33
+ },
34
+ unfinishedTimers: {},
35
+ });
36
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
37
+ "superblocks.npm.install.build_seconds": 0.09,
38
+ "superblocks.npm.install.ideal_tree_seconds": 0.23,
39
+ "superblocks.npm.install.load_trees_seconds": 0.4,
40
+ "superblocks.npm.install.reify_seconds": 24.5,
41
+ "superblocks.npm.install.unpack_seconds": 23.2,
42
+ });
43
+ });
44
+ // npm records one `reifyNode:node_modules/<package>` timer per package it
45
+ // touched. Emitting those would be unbounded attribute cardinality and would
46
+ // put dependency names into telemetry, so only the fixed whitelist is ever
47
+ // emitted.
48
+ it("never emits a per-package reifyNode timer", async () => {
49
+ await writeTimingFile("2026-08-07T12_00_00_000Z", {
50
+ timers: {
51
+ idealTree: 100,
52
+ "reifyNode:node_modules/@dnd-kit/core": 12,
53
+ "reifyNode:node_modules/lodash": 34,
54
+ "reifyNode:node_modules/react": 56,
55
+ },
56
+ });
57
+ const attributes = await consumeNpmInstallTimingAttributes(logsDir);
58
+ expect(attributes).toEqual({
59
+ "superblocks.npm.install.ideal_tree_seconds": 0.1,
60
+ });
61
+ expect(Object.keys(attributes ?? {}).some((key) => key.includes("reifyNode"))).toBe(false);
62
+ });
63
+ // Which phases npm records depends on what the install did, so a missing
64
+ // timer is normal rather than an error.
65
+ it("omits timers npm did not record", async () => {
66
+ await writeTimingFile("2026-08-07T12_00_00_000Z", {
67
+ timers: { reify: 500 },
68
+ });
69
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
70
+ "superblocks.npm.install.reify_seconds": 0.5,
71
+ });
72
+ });
73
+ // "npm unpacked nothing" is the signal that separates a metadata-only
74
+ // install from one that wrote tens of thousands of files, so a recorded zero
75
+ // is real data and must not be dropped as if it were missing.
76
+ it("emits a recorded zero rather than dropping it", async () => {
77
+ await writeTimingFile("2026-08-07T12_00_00_000Z", {
78
+ timers: { "reify:unpack": 0 },
79
+ });
80
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
81
+ "superblocks.npm.install.unpack_seconds": 0,
82
+ });
83
+ });
84
+ // npm's log ids are fixed-width ISO timestamps, so the newest file is the
85
+ // last one alphabetically.
86
+ it("reads the newest file when older installs left files behind", async () => {
87
+ await writeTimingFile("2026-08-07T11_00_00_000Z", {
88
+ timers: { reify: 1000 },
89
+ });
90
+ await writeTimingFile("2026-08-07T12_00_00_000Z", {
91
+ timers: { reify: 2000 },
92
+ });
93
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
94
+ "superblocks.npm.install.reify_seconds": 2,
95
+ });
96
+ });
97
+ // npm's `logs-max` pruning only covers its debug logs, so timing files would
98
+ // pile up on the app volume forever if nothing removed them.
99
+ it("removes the timing files it read so they cannot accumulate", async () => {
100
+ await writeTimingFile("2026-08-07T11_00_00_000Z", {
101
+ timers: { reify: 1000 },
102
+ });
103
+ await writeTimingFile("2026-08-07T12_00_00_000Z", {
104
+ timers: { reify: 2000 },
105
+ });
106
+ const debugLog = path.join(logsDir, "2026-08-07T12_00_00_000Z-debug-0.log");
107
+ await nodeFs.writeFile(debugLog, "npm debug output");
108
+ await consumeNpmInstallTimingAttributes(logsDir);
109
+ expect(await listTimingFiles()).toEqual([]);
110
+ // npm's debug log is a separate diagnostic that must survive.
111
+ await expect(nodeFs.readFile(debugLog, "utf8")).resolves.toBe("npm debug output");
112
+ });
113
+ it("returns null when the logs dir has no timing file", async () => {
114
+ await nodeFs.writeFile(path.join(logsDir, "2026-08-07T12_00_00_000Z-debug-0.log"), "npm debug output");
115
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toBeNull();
116
+ });
117
+ it("returns null when the logs dir does not exist", async () => {
118
+ expect(await consumeNpmInstallTimingAttributes(path.join(logsDir, "missing"))).toBeNull();
119
+ });
120
+ it("returns null for a file that is not JSON rather than throwing", async () => {
121
+ await writeTimingFile("2026-08-07T12_00_00_000Z", "not json at all");
122
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toBeNull();
123
+ });
124
+ it("returns null when the file carries no timers object", async () => {
125
+ await writeTimingFile("2026-08-07T12_00_00_000Z", { metadata: {} });
126
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toBeNull();
127
+ });
128
+ it("returns null when none of the whitelisted timers are present", async () => {
129
+ await writeTimingFile("2026-08-07T12_00_00_000Z", {
130
+ timers: { "npm:load": 12, "reifyNode:node_modules/lodash": 34 },
131
+ });
132
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toBeNull();
133
+ });
134
+ it("ignores timer values that are not finite numbers", async () => {
135
+ await writeTimingFile("2026-08-07T12_00_00_000Z", {
136
+ timers: { idealTree: "230", reify: null, "reify:unpack": 23200 },
137
+ });
138
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
139
+ "superblocks.npm.install.unpack_seconds": 23.2,
140
+ });
141
+ });
142
+ it("clamps a negative duration so dashboards cannot be skewed", async () => {
143
+ await writeTimingFile("2026-08-07T12_00_00_000Z", {
144
+ timers: { reify: -500 },
145
+ });
146
+ expect(await consumeNpmInstallTimingAttributes(logsDir)).toEqual({
147
+ "superblocks.npm.install.reify_seconds": 0,
148
+ });
149
+ });
150
+ });
151
+ //# sourceMappingURL=npm-install-timing.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-install-timing.test.mjs","sourceRoot":"","sources":["../../src/cli-replacement/npm-install-timing.test.mts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAErE,OAAO,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAE7E,IAAI,OAAe,CAAC;AAEpB,UAAU,CAAC,KAAK,IAAI,EAAE;IACpB,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;AACxE,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,2EAA2E;AAC3E,KAAK,UAAU,eAAe,CAC5B,KAAa,EACb,QAAiB;IAEjB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,cAAc,CAAC,CAAC;IACxD,MAAM,MAAM,CAAC,SAAS,CACpB,IAAI,EACJ,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CACnE,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;YAChC,MAAM,EAAE;gBACN,SAAS,EAAE,GAAG;gBACd,KAAK,EAAE,KAAK;gBACZ,aAAa,EAAE,EAAE;gBACjB,iBAAiB,EAAE,GAAG;gBACtB,cAAc,EAAE,KAAK;aACtB;YACD,gBAAgB,EAAE,EAAE;SACrB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/D,uCAAuC,EAAE,IAAI;YAC7C,4CAA4C,EAAE,IAAI;YAClD,4CAA4C,EAAE,GAAG;YACjD,uCAAuC,EAAE,IAAI;YAC7C,wCAAwC,EAAE,IAAI;SAC/C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,6EAA6E;IAC7E,2EAA2E;IAC3E,WAAW;IACX,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE;gBACN,SAAS,EAAE,GAAG;gBACd,sCAAsC,EAAE,EAAE;gBAC1C,+BAA+B,EAAE,EAAE;gBACnC,8BAA8B,EAAE,EAAE;aACnC;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC;QAEpE,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC;YACzB,4CAA4C,EAAE,GAAG;SAClD,CAAC,CAAC;QACH,MAAM,CACJ,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CACvE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,yEAAyE;IACzE,wCAAwC;IACxC,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;SACvB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/D,uCAAuC,EAAE,GAAG;SAC7C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,sEAAsE;IACtE,6EAA6E;IAC7E,8DAA8D;IAC9D,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE;SAC9B,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/D,wCAAwC,EAAE,CAAC;SAC5C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,2BAA2B;IAC3B,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;SACxB,CAAC,CAAC;QACH,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;SACxB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/D,uCAAuC,EAAE,CAAC;SAC3C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,6EAA6E;IAC7E,6DAA6D;IAC7D,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;SACxB,CAAC,CAAC;QACH,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;SACxB,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,sCAAsC,CAAC,CAAC;QAC5E,MAAM,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QAErD,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC5C,8DAA8D;QAC9D,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAC3D,kBAAkB,CACnB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,MAAM,CAAC,SAAS,CACpB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,sCAAsC,CAAC,EAC1D,kBAAkB,CACnB,CAAC;QAEF,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,CACJ,MAAM,iCAAiC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CACvE,CAAC,QAAQ,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,eAAe,CAAC,0BAA0B,EAAE,iBAAiB,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,eAAe,CAAC,0BAA0B,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QAEpE,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,+BAA+B,EAAE,EAAE,EAAE;SAChE,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE;SACjE,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/D,wCAAwC,EAAE,IAAI;SAC/C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,eAAe,CAAC,0BAA0B,EAAE;YAChD,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE;SACxB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/D,uCAAuC,EAAE,CAAC;SAC3C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -15,6 +15,13 @@ export interface Logger {
15
15
  debug: (...messages: unknown[]) => void;
16
16
  info: (...messages: unknown[]) => void;
17
17
  warn: (...messages: unknown[]) => void;
18
+ /**
19
+ * Emit an INFO-level log whose structured attributes are exported as OTel
20
+ * log attributes (Datadog facets) instead of being flattened into the
21
+ * message body. Plain `info()` joins every argument into one body string, so
22
+ * attributes passed to it are never queryable.
23
+ */
24
+ infoStructured?: (message: string, attributes: LogAttributes) => void;
18
25
  /**
19
26
  * Emit a WARN-level log whose structured attributes are exported as OTel log
20
27
  * attributes (Datadog facets) instead of being flattened into the message
@@ -1 +1 @@
1
- {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/telemetry/logging.ts"],"names":[],"mappings":"AA8DA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;;GAIG;AACH,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAE/D,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACxC,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvC;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IACtE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;CACpD;AAyED,wBAAgB,SAAS,CACvB,cAAc,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,GAChD,MAAM,CAiBR;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAgBtD"}
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/telemetry/logging.ts"],"names":[],"mappings":"AA8DA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;;GAIG;AACH,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAE/D,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACxC,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IACtE;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IACtE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;CACpD;AAqFD,wBAAgB,SAAS,CACvB,cAAc,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,GAChD,MAAM,CAmBR;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAgBtD"}
@@ -70,6 +70,18 @@ const logger = Object.freeze({
70
70
  });
71
71
  winstonLogger.warn(body);
72
72
  },
73
+ infoStructured: (message, attributes) => {
74
+ const body = sanitizeLogMessage(message);
75
+ // Same sanitize-then-emit contract as warnStructured below.
76
+ const safeAttributes = sanitizeLogObject(attributes);
77
+ getTracedLogger().emit({
78
+ severityNumber: SeverityNumber.INFO,
79
+ severityText: "INFO",
80
+ body,
81
+ attributes: safeAttributes,
82
+ });
83
+ winstonLogger.info(body);
84
+ },
73
85
  warnStructured: (message, attributes) => {
74
86
  const body = sanitizeLogMessage(message);
75
87
  // sanitizeLogObject strips secret-named keys and redacts secret values,
@@ -119,6 +131,7 @@ export function getLogger(loggerOverride) {
119
131
  // above, it forwards raw args to the supplied function and does NOT
120
132
  // sanitize or emit OTel attributes. Production callers use the default
121
133
  // logger (and the vite-plugin wrapLogger) which sanitize before emitting.
134
+ infoStructured: (message, attributes) => loggerOverride(message, attributes),
122
135
  warnStructured: (message, attributes) => loggerOverride(message, attributes),
123
136
  error: loggerOverride,
124
137
  };
@@ -1 +1 @@
1
- {"version":3,"file":"logging.js","sourceRoot":"","sources":["../../src/telemetry/logging.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../../src/telemetry/logging.ts"],"names":[],"mappings":"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"}
@@ -115,6 +115,46 @@ describe("telemetry logger error sanitization", () => {
115
115
  expect(winstonErrorMock).toHaveBeenCalledWith("sanitized-message:plain failure");
116
116
  });
117
117
  });
118
+ describe("telemetry logger infoStructured", () => {
119
+ beforeEach(() => {
120
+ vi.clearAllMocks();
121
+ });
122
+ it("emits an INFO record carrying structured attributes (not flattened into the body)", () => {
123
+ const logger = getLogger();
124
+ logger.infoStructured?.("Package installation completed successfully", {
125
+ "superblocks.npm.install.added": 8,
126
+ "superblocks.npm.install.duration_seconds": 32.5,
127
+ "superblocks.npm.install.outcome": "success",
128
+ });
129
+ expect(emitMock).toHaveBeenCalledWith(expect.objectContaining({
130
+ severityText: "INFO",
131
+ body: "sanitized-message:Package installation completed successfully",
132
+ attributes: {
133
+ "superblocks.npm.install.added": 8,
134
+ "superblocks.npm.install.duration_seconds": 32.5,
135
+ "superblocks.npm.install.outcome": "sanitized-object:success",
136
+ },
137
+ }));
138
+ // Winston gets the body only (structured attributes go to OTel, not also
139
+ // to stdout log shippers as a duplicate).
140
+ expect(winstonLoggerMock.info).toHaveBeenCalledWith("sanitized-message:Package installation completed successfully");
141
+ });
142
+ it("strips secret-named attribute keys before emitting", () => {
143
+ const logger = getLogger();
144
+ logger.infoStructured?.("install done", {
145
+ registry: "https://npm.example.com",
146
+ token: "[REDACTED:token]",
147
+ });
148
+ expect(emitMock).toHaveBeenCalledWith(expect.objectContaining({
149
+ attributes: expect.objectContaining({
150
+ registry: "sanitized-object:https://npm.example.com",
151
+ }),
152
+ }));
153
+ expect(emitMock).not.toHaveBeenCalledWith(expect.objectContaining({
154
+ attributes: expect.objectContaining({ token: expect.anything() }),
155
+ }));
156
+ });
157
+ });
118
158
  describe("telemetry logger warnStructured", () => {
119
159
  beforeEach(() => {
120
160
  vi.clearAllMocks();
@@ -1 +1 @@
1
- {"version":3,"file":"logging.test.js","sourceRoot":"","sources":["../../src/telemetry/logging.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logging.test.js","sourceRoot":"","sources":["../../src/telemetry/logging.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superblocksteam/sdk",
3
- "version": "2.0.150-next.0",
3
+ "version": "2.0.150-next.2",
4
4
  "description": "Superblocks JS SDK",
5
5
  "homepage": "https://www.superblocks.com",
6
6
  "license": "Superblocks Community Software License",
@@ -57,11 +57,11 @@
57
57
  "vite-tsconfig-paths": "^6.0.4",
58
58
  "winston": "^3.17.0",
59
59
  "yaml": "^2.7.1",
60
- "@superblocksteam/library-shared": "2.0.150-next.0",
61
- "@superblocksteam/shared": "0.9604.0",
62
- "@superblocksteam/telemetry": "2.0.150-next.0",
63
- "@superblocksteam/util": "2.0.150-next.0",
64
- "@superblocksteam/vite-plugin-file-sync": "2.0.150-next.0"
60
+ "@superblocksteam/telemetry": "2.0.150-next.2",
61
+ "@superblocksteam/util": "2.0.150-next.2",
62
+ "@superblocksteam/vite-plugin-file-sync": "2.0.150-next.2",
63
+ "@superblocksteam/shared": "0.9604.2",
64
+ "@superblocksteam/library-shared": "2.0.150-next.2"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@eslint/js": "^9.39.2",
@@ -89,6 +89,8 @@ import {
89
89
  syncHomeNpmrc,
90
90
  } from "./home-npmrc.mjs";
91
91
  import { normalizeWorkspaceProtocolForNpm } from "./normalize-workspace-protocol.js";
92
+ import { parseNpmInstallSummary } from "./npm-install-summary.mjs";
93
+ import { consumeNpmInstallTimingAttributes } from "./npm-install-timing.mjs";
92
94
  import {
93
95
  didPackageJsonSnapshotChange,
94
96
  packageJsonSnapshot,
@@ -462,6 +464,39 @@ async function normalizePackageJsonForNpm(cwd: string, logger: Logger) {
462
464
  }
463
465
  }
464
466
 
467
+ function emitSuccessTelemetry(logger: Logger, emit: () => void): void {
468
+ try {
469
+ emit();
470
+ } catch (err) {
471
+ try {
472
+ logger.warn(
473
+ "Could not emit package installation success telemetry",
474
+ getErrorMeta(err),
475
+ );
476
+ } catch {
477
+ // Telemetry must not turn a successful install into a failure.
478
+ }
479
+ }
480
+ }
481
+
482
+ /**
483
+ * Plain `info()` joins every argument into one message string, so attributes
484
+ * passed to it never reach Datadog as facets. `infoStructured` emits them as
485
+ * OTel log attributes; the fallback is only for custom Logger implementations
486
+ * that don't provide it.
487
+ */
488
+ function logInstallSuccess(
489
+ logger: Logger,
490
+ message: string,
491
+ attributes: Record<string, boolean | number>,
492
+ ): void {
493
+ if (logger.infoStructured) {
494
+ logger.infoStructured(message, attributes);
495
+ } else {
496
+ logger.info(message, attributes);
497
+ }
498
+ }
499
+
465
500
  export async function installPackages(
466
501
  cwd: string,
467
502
  logger: Logger,
@@ -473,6 +508,10 @@ export async function installPackages(
473
508
  let runInstall:
474
509
  | (() => Promise<{ stdout: string; stderr: string }>)
475
510
  | undefined;
511
+ // Hoisted alongside `runInstall` so the ENOSPC recovery path in the catch can
512
+ // report install duration too. Set as soon as the retryable command exists so
513
+ // every recovery-eligible path has a start time.
514
+ let installStart: number | undefined;
476
515
  try {
477
516
  const pm = await detect({
478
517
  strategies: [
@@ -524,10 +563,21 @@ export async function installPackages(
524
563
  // `--json` makes npm channel the structured error envelope (code +
525
564
  // summary + detail) onto stdout so a failure can be classified into a
526
565
  // DependencyInstallError. Output-only: it does not change resolution,
527
- // only how npm reports it. The success-path `logger.info(stdout)` below
528
- // then logs JSON, which is acceptable.
566
+ // only how npm reports it. On success the same envelope carries the
567
+ // install summary, which the success path below turns into log
568
+ // attributes.
569
+ // `--timing` makes npm record how long each install phase took, which is
570
+ // what tells a slow registry apart from writing tens of thousands of files.
571
+ // It does not go to stdout - npm writes it to a file in its logs dir, which
572
+ // the success path below reads back. It costs no install time (npm keeps
573
+ // these timers either way; the flag only decides whether they get written
574
+ // out at the end), but it does add one line per package to npm's debug log
575
+ // in the same dir - bounded by the `logs-max` pruning that already applies
576
+ // there.
529
577
  const baseArgs =
530
- pm.agent === "npm" ? ["--fund=false", "--audit=false", "--json"] : [];
578
+ pm.agent === "npm"
579
+ ? ["--fund=false", "--audit=false", "--json", "--timing"]
580
+ : [];
531
581
  const installArgs = ignoreScripts
532
582
  ? [...baseArgs, "--ignore-scripts"]
533
583
  : baseArgs;
@@ -583,6 +633,7 @@ export async function installPackages(
583
633
  cwd,
584
634
  env: buildInstallEnv(superblocksNpmrcPath(), logsDir),
585
635
  });
636
+ installStart = Date.now();
586
637
 
587
638
  // Cheap `df` snapshot before the install (statfs only — no directory walk
588
639
  // on the happy path). On a 3Gi live-edit PVC this is the baseline that
@@ -600,8 +651,55 @@ export async function installPackages(
600
651
  }
601
652
 
602
653
  const { stdout } = await runInstall();
603
- logger.info("Package installation completed successfully");
604
- logger.info(stdout);
654
+ const installDurationMs = Date.now() - installStart;
655
+ // npm's `--timing` breakdown lives in a file, so it has to be read back
656
+ // once the install is done. Only npm writes one; reading under pnpm would
657
+ // report a leftover npm file as this install's timings. The `catch` keeps
658
+ // the "telemetry never fails a completed install" invariant at the call
659
+ // site, so it holds even if the reader stops swallowing its own errors.
660
+ const timingAttributes =
661
+ pm.agent === "npm"
662
+ ? await consumeNpmInstallTimingAttributes(logsDir).catch(() => null)
663
+ : null;
664
+ // `--json` is already passed for error classification; on success it also
665
+ // carries the only record of what the install DID. Emit it as attributes
666
+ // rather than as the log message: passing the raw envelope to
667
+ // `logger.info(stdout)` surfaced as an empty line in Datadog, so the counts
668
+ // that size this install were collected and then thrown away.
669
+ emitSuccessTelemetry(logger, () => {
670
+ const summary = parseNpmInstallSummary(stdout);
671
+ const logSuccess = (attributes: Record<string, boolean | number>) =>
672
+ logInstallSuccess(
673
+ logger,
674
+ "Package installation completed successfully",
675
+ attributes,
676
+ );
677
+ // Reuse the existing npm-install namespace and its duration unit. The
678
+ // package counts are log-only sizing data from this separate install path.
679
+ const commonAttributes = {
680
+ "superblocks.npm.install.disk_recovered": false,
681
+ "superblocks.npm.install.duration_seconds": installDurationMs / 1000,
682
+ ...timingAttributes,
683
+ };
684
+ if (summary) {
685
+ logSuccess({
686
+ ...commonAttributes,
687
+ "superblocks.npm.install.added": summary.added,
688
+ "superblocks.npm.install.removed": summary.removed,
689
+ "superblocks.npm.install.changed": summary.changed,
690
+ "superblocks.npm.install.audited": summary.audited,
691
+ "superblocks.npm.install.summary_parsed": true,
692
+ });
693
+ } else {
694
+ // Free-form output is not a safe OTel attribute. Keep duration queryable
695
+ // and send non-empty output through the regular local/logging path.
696
+ logSuccess({
697
+ ...commonAttributes,
698
+ "superblocks.npm.install.summary_parsed": false,
699
+ });
700
+ if (stdout.trim() !== "") logger.info(stdout);
701
+ }
702
+ });
605
703
  } catch (error) {
606
704
  // `util.promisify(child_process.exec)` preserves `.stdout`/`.stderr` on
607
705
  // the rejected error separately; with `--json`, the structured npm error
@@ -626,7 +724,12 @@ export async function installPackages(
626
724
  // only autopsy we can get of a PVC that `reclaimPolicy: Delete` destroys
627
725
  // at teardown. `runInstall` is only set once the command was resolved; if
628
726
  // the failure happened before that, there's nothing to retry.
629
- if (serverError.category === "disk_full" && runInstall) {
727
+ if (
728
+ serverError.category === "disk_full" &&
729
+ runInstall &&
730
+ installStart !== undefined
731
+ ) {
732
+ const startedAt = installStart;
630
733
  let recovery: Awaited<ReturnType<typeof recoverFromDiskFull>> | undefined;
631
734
  try {
632
735
  recovery = await recoverFromDiskFull(cwd, runInstall, logger);
@@ -639,11 +742,26 @@ export async function installPackages(
639
742
  });
640
743
  }
641
744
  if (recovery) {
642
- devServerMetrics.recordDiskRecovery({ recovered: recovery.recovered });
745
+ emitSuccessTelemetry(logger, () => {
746
+ devServerMetrics.recordDiskRecovery({
747
+ recovered: recovery.recovered,
748
+ });
749
+ });
643
750
  if (recovery.recovered) {
644
- logger.info(
645
- "Package installation completed successfully after disk recovery",
646
- );
751
+ // Recovered installs previously emitted no install telemetry at all,
752
+ // so the slowest installs on the fleet were the ones missing from the
753
+ // data. Duration spans every attempt including the reclaim.
754
+ emitSuccessTelemetry(logger, () => {
755
+ logInstallSuccess(
756
+ logger,
757
+ "Package installation completed successfully after disk recovery",
758
+ {
759
+ "superblocks.npm.install.duration_seconds":
760
+ (Date.now() - startedAt) / 1000,
761
+ "superblocks.npm.install.disk_recovered": true,
762
+ },
763
+ );
764
+ });
647
765
  return;
648
766
  }
649
767
  // Reclassify the final attempt so the surfaced error reflects the last