@vibesdotdev/infra-deploy 0.0.1

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 (183) hide show
  1. package/README.md +125 -0
  2. package/SPEC.md +181 -0
  3. package/dist/cli/alerts/infra-alerts-create.cli-command.descriptor.d.ts +39 -0
  4. package/dist/cli/alerts/infra-alerts-create.cli-command.descriptor.d.ts.map +1 -0
  5. package/dist/cli/alerts/infra-alerts-create.cli-command.descriptor.js +61 -0
  6. package/dist/cli/alerts/infra-alerts-create.cli-command.descriptor.js.map +1 -0
  7. package/dist/cli/alerts/infra-alerts-create.cli-command.impl.d.ts +13 -0
  8. package/dist/cli/alerts/infra-alerts-create.cli-command.impl.d.ts.map +1 -0
  9. package/dist/cli/alerts/infra-alerts-create.cli-command.impl.js +109 -0
  10. package/dist/cli/alerts/infra-alerts-create.cli-command.impl.js.map +1 -0
  11. package/dist/cli/alerts/infra-alerts-delete.cli-command.descriptor.d.ts +31 -0
  12. package/dist/cli/alerts/infra-alerts-delete.cli-command.descriptor.d.ts.map +1 -0
  13. package/dist/cli/alerts/infra-alerts-delete.cli-command.descriptor.js +36 -0
  14. package/dist/cli/alerts/infra-alerts-delete.cli-command.descriptor.js.map +1 -0
  15. package/dist/cli/alerts/infra-alerts-delete.cli-command.impl.d.ts +11 -0
  16. package/dist/cli/alerts/infra-alerts-delete.cli-command.impl.d.ts.map +1 -0
  17. package/dist/cli/alerts/infra-alerts-delete.cli-command.impl.js +67 -0
  18. package/dist/cli/alerts/infra-alerts-delete.cli-command.impl.js.map +1 -0
  19. package/dist/cli/alerts/infra-alerts-list.cli-command.descriptor.d.ts +21 -0
  20. package/dist/cli/alerts/infra-alerts-list.cli-command.descriptor.d.ts.map +1 -0
  21. package/dist/cli/alerts/infra-alerts-list.cli-command.descriptor.js +27 -0
  22. package/dist/cli/alerts/infra-alerts-list.cli-command.descriptor.js.map +1 -0
  23. package/dist/cli/alerts/infra-alerts-list.cli-command.impl.d.ts +12 -0
  24. package/dist/cli/alerts/infra-alerts-list.cli-command.impl.d.ts.map +1 -0
  25. package/dist/cli/alerts/infra-alerts-list.cli-command.impl.js +74 -0
  26. package/dist/cli/alerts/infra-alerts-list.cli-command.impl.js.map +1 -0
  27. package/dist/cli/alerts/infra-alerts.cli-group.descriptor.d.ts +12 -0
  28. package/dist/cli/alerts/infra-alerts.cli-group.descriptor.d.ts.map +1 -0
  29. package/dist/cli/alerts/infra-alerts.cli-group.descriptor.js +12 -0
  30. package/dist/cli/alerts/infra-alerts.cli-group.descriptor.js.map +1 -0
  31. package/dist/cli/audit/infra-audit.cli-command.descriptor.d.ts +21 -0
  32. package/dist/cli/audit/infra-audit.cli-command.descriptor.d.ts.map +1 -0
  33. package/dist/cli/audit/infra-audit.cli-command.descriptor.js +28 -0
  34. package/dist/cli/audit/infra-audit.cli-command.descriptor.js.map +1 -0
  35. package/dist/cli/audit/infra-audit.cli-command.impl.d.ts +18 -0
  36. package/dist/cli/audit/infra-audit.cli-command.impl.d.ts.map +1 -0
  37. package/dist/cli/audit/infra-audit.cli-command.impl.js +219 -0
  38. package/dist/cli/audit/infra-audit.cli-command.impl.js.map +1 -0
  39. package/dist/cli/infra-deploy.cli-group.descriptor.d.ts +12 -0
  40. package/dist/cli/infra-deploy.cli-group.descriptor.d.ts.map +1 -0
  41. package/dist/cli/infra-deploy.cli-group.descriptor.js +12 -0
  42. package/dist/cli/infra-deploy.cli-group.descriptor.js.map +1 -0
  43. package/dist/cli/infra.cli-group.descriptor.d.ts +11 -0
  44. package/dist/cli/infra.cli-group.descriptor.d.ts.map +1 -0
  45. package/dist/cli/infra.cli-group.descriptor.js +11 -0
  46. package/dist/cli/infra.cli-group.descriptor.js.map +1 -0
  47. package/dist/cli/list/infra-deploy.list.cli-command.descriptor.d.ts +34 -0
  48. package/dist/cli/list/infra-deploy.list.cli-command.descriptor.d.ts.map +1 -0
  49. package/dist/cli/list/infra-deploy.list.cli-command.descriptor.js +29 -0
  50. package/dist/cli/list/infra-deploy.list.cli-command.descriptor.js.map +1 -0
  51. package/dist/cli/list/infra-deploy.list.cli-command.impl.d.ts +5 -0
  52. package/dist/cli/list/infra-deploy.list.cli-command.impl.d.ts.map +1 -0
  53. package/dist/cli/list/infra-deploy.list.cli-command.impl.js +110 -0
  54. package/dist/cli/list/infra-deploy.list.cli-command.impl.js.map +1 -0
  55. package/dist/cli/logs/infra-logs.cli-command.descriptor.d.ts +39 -0
  56. package/dist/cli/logs/infra-logs.cli-command.descriptor.d.ts.map +1 -0
  57. package/dist/cli/logs/infra-logs.cli-command.descriptor.js +64 -0
  58. package/dist/cli/logs/infra-logs.cli-command.descriptor.js.map +1 -0
  59. package/dist/cli/logs/infra-logs.cli-command.impl.d.ts +5 -0
  60. package/dist/cli/logs/infra-logs.cli-command.impl.d.ts.map +1 -0
  61. package/dist/cli/logs/infra-logs.cli-command.impl.js +323 -0
  62. package/dist/cli/logs/infra-logs.cli-command.impl.js.map +1 -0
  63. package/dist/cli/logs/stream-worker-tail.d.ts +62 -0
  64. package/dist/cli/logs/stream-worker-tail.d.ts.map +1 -0
  65. package/dist/cli/logs/stream-worker-tail.js +165 -0
  66. package/dist/cli/logs/stream-worker-tail.js.map +1 -0
  67. package/dist/cli/npm/infra-npm-publish.cli-command.descriptor.d.ts +27 -0
  68. package/dist/cli/npm/infra-npm-publish.cli-command.descriptor.d.ts.map +1 -0
  69. package/dist/cli/npm/infra-npm-publish.cli-command.descriptor.js +75 -0
  70. package/dist/cli/npm/infra-npm-publish.cli-command.descriptor.js.map +1 -0
  71. package/dist/cli/npm/infra-npm-publish.cli-command.impl.d.ts +5 -0
  72. package/dist/cli/npm/infra-npm-publish.cli-command.impl.d.ts.map +1 -0
  73. package/dist/cli/npm/infra-npm-publish.cli-command.impl.js +383 -0
  74. package/dist/cli/npm/infra-npm-publish.cli-command.impl.js.map +1 -0
  75. package/dist/cli/npm/infra-npm.cli-group.descriptor.d.ts +12 -0
  76. package/dist/cli/npm/infra-npm.cli-group.descriptor.d.ts.map +1 -0
  77. package/dist/cli/npm/infra-npm.cli-group.descriptor.js +12 -0
  78. package/dist/cli/npm/infra-npm.cli-group.descriptor.js.map +1 -0
  79. package/dist/cli/observability/infra-observability-set.cli-command.descriptor.d.ts +25 -0
  80. package/dist/cli/observability/infra-observability-set.cli-command.descriptor.d.ts.map +1 -0
  81. package/dist/cli/observability/infra-observability-set.cli-command.descriptor.js +57 -0
  82. package/dist/cli/observability/infra-observability-set.cli-command.descriptor.js.map +1 -0
  83. package/dist/cli/observability/infra-observability-set.cli-command.impl.d.ts +17 -0
  84. package/dist/cli/observability/infra-observability-set.cli-command.impl.d.ts.map +1 -0
  85. package/dist/cli/observability/infra-observability-set.cli-command.impl.js +152 -0
  86. package/dist/cli/observability/infra-observability-set.cli-command.impl.js.map +1 -0
  87. package/dist/cli/observability/infra-observability-status.cli-command.descriptor.d.ts +21 -0
  88. package/dist/cli/observability/infra-observability-status.cli-command.descriptor.d.ts.map +1 -0
  89. package/dist/cli/observability/infra-observability-status.cli-command.descriptor.js +35 -0
  90. package/dist/cli/observability/infra-observability-status.cli-command.descriptor.js.map +1 -0
  91. package/dist/cli/observability/infra-observability-status.cli-command.impl.d.ts +17 -0
  92. package/dist/cli/observability/infra-observability-status.cli-command.impl.d.ts.map +1 -0
  93. package/dist/cli/observability/infra-observability-status.cli-command.impl.js +99 -0
  94. package/dist/cli/observability/infra-observability-status.cli-command.impl.js.map +1 -0
  95. package/dist/cli/observability/infra-observability.cli-group.descriptor.d.ts +12 -0
  96. package/dist/cli/observability/infra-observability.cli-group.descriptor.d.ts.map +1 -0
  97. package/dist/cli/observability/infra-observability.cli-group.descriptor.js +12 -0
  98. package/dist/cli/observability/infra-observability.cli-group.descriptor.js.map +1 -0
  99. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.d.ts +27 -0
  100. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.d.ts.map +1 -0
  101. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.js +35 -0
  102. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.js.map +1 -0
  103. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.impl.d.ts +5 -0
  104. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.impl.d.ts.map +1 -0
  105. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.impl.js +99 -0
  106. package/dist/cli/regenerate/infra-deploy.regenerate.cli-command.impl.js.map +1 -0
  107. package/dist/cli/rum/infra-rum-status.cli-command.descriptor.d.ts +21 -0
  108. package/dist/cli/rum/infra-rum-status.cli-command.descriptor.d.ts.map +1 -0
  109. package/dist/cli/rum/infra-rum-status.cli-command.descriptor.js +27 -0
  110. package/dist/cli/rum/infra-rum-status.cli-command.descriptor.js.map +1 -0
  111. package/dist/cli/rum/infra-rum-status.cli-command.impl.d.ts +12 -0
  112. package/dist/cli/rum/infra-rum-status.cli-command.impl.d.ts.map +1 -0
  113. package/dist/cli/rum/infra-rum-status.cli-command.impl.js +88 -0
  114. package/dist/cli/rum/infra-rum-status.cli-command.impl.js.map +1 -0
  115. package/dist/cli/rum/infra-rum.cli-group.descriptor.d.ts +12 -0
  116. package/dist/cli/rum/infra-rum.cli-group.descriptor.d.ts.map +1 -0
  117. package/dist/cli/rum/infra-rum.cli-group.descriptor.js +12 -0
  118. package/dist/cli/rum/infra-rum.cli-group.descriptor.js.map +1 -0
  119. package/dist/cli/run/infra-deploy.run.cli-command.descriptor.d.ts +27 -0
  120. package/dist/cli/run/infra-deploy.run.cli-command.descriptor.d.ts.map +1 -0
  121. package/dist/cli/run/infra-deploy.run.cli-command.descriptor.js +49 -0
  122. package/dist/cli/run/infra-deploy.run.cli-command.descriptor.js.map +1 -0
  123. package/dist/cli/run/infra-deploy.run.cli-command.impl.d.ts +5 -0
  124. package/dist/cli/run/infra-deploy.run.cli-command.impl.d.ts.map +1 -0
  125. package/dist/cli/run/infra-deploy.run.cli-command.impl.js +272 -0
  126. package/dist/cli/run/infra-deploy.run.cli-command.impl.js.map +1 -0
  127. package/dist/cli/shared/discover-deployments.d.ts +41 -0
  128. package/dist/cli/shared/discover-deployments.d.ts.map +1 -0
  129. package/dist/cli/shared/discover-deployments.js +95 -0
  130. package/dist/cli/shared/discover-deployments.js.map +1 -0
  131. package/dist/config-loader.d.ts +24 -0
  132. package/dist/config-loader.d.ts.map +1 -0
  133. package/dist/config-loader.js +135 -0
  134. package/dist/config-loader.js.map +1 -0
  135. package/dist/index.d.ts +5 -0
  136. package/dist/index.d.ts.map +1 -0
  137. package/dist/index.js +4 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/infra-deploy.plugin.d.ts +3 -0
  140. package/dist/infra-deploy.plugin.d.ts.map +1 -0
  141. package/dist/infra-deploy.plugin.js +59 -0
  142. package/dist/infra-deploy.plugin.js.map +1 -0
  143. package/dist/regenerate.d.ts +55 -0
  144. package/dist/regenerate.d.ts.map +1 -0
  145. package/dist/regenerate.js +206 -0
  146. package/dist/regenerate.js.map +1 -0
  147. package/package.json +85 -0
  148. package/src/cli/alerts/infra-alerts-create.cli-command.descriptor.ts +61 -0
  149. package/src/cli/alerts/infra-alerts-create.cli-command.impl.ts +131 -0
  150. package/src/cli/alerts/infra-alerts-delete.cli-command.descriptor.ts +36 -0
  151. package/src/cli/alerts/infra-alerts-delete.cli-command.impl.ts +75 -0
  152. package/src/cli/alerts/infra-alerts-list.cli-command.descriptor.ts +27 -0
  153. package/src/cli/alerts/infra-alerts-list.cli-command.impl.ts +88 -0
  154. package/src/cli/alerts/infra-alerts.cli-group.descriptor.ts +12 -0
  155. package/src/cli/audit/infra-audit.cli-command.descriptor.ts +28 -0
  156. package/src/cli/audit/infra-audit.cli-command.impl.ts +293 -0
  157. package/src/cli/infra-deploy.cli-group.descriptor.ts +12 -0
  158. package/src/cli/infra.cli-group.descriptor.ts +11 -0
  159. package/src/cli/list/infra-deploy.list.cli-command.descriptor.ts +29 -0
  160. package/src/cli/list/infra-deploy.list.cli-command.impl.ts +125 -0
  161. package/src/cli/logs/infra-logs.cli-command.descriptor.ts +65 -0
  162. package/src/cli/logs/infra-logs.cli-command.impl.ts +354 -0
  163. package/src/cli/logs/stream-worker-tail.ts +202 -0
  164. package/src/cli/npm/infra-npm-publish.cli-command.descriptor.ts +75 -0
  165. package/src/cli/npm/infra-npm-publish.cli-command.impl.ts +474 -0
  166. package/src/cli/npm/infra-npm.cli-group.descriptor.ts +12 -0
  167. package/src/cli/observability/infra-observability-set.cli-command.descriptor.ts +57 -0
  168. package/src/cli/observability/infra-observability-set.cli-command.impl.ts +173 -0
  169. package/src/cli/observability/infra-observability-status.cli-command.descriptor.ts +35 -0
  170. package/src/cli/observability/infra-observability-status.cli-command.impl.ts +124 -0
  171. package/src/cli/observability/infra-observability.cli-group.descriptor.ts +12 -0
  172. package/src/cli/regenerate/infra-deploy.regenerate.cli-command.descriptor.ts +36 -0
  173. package/src/cli/regenerate/infra-deploy.regenerate.cli-command.impl.ts +103 -0
  174. package/src/cli/rum/infra-rum-status.cli-command.descriptor.ts +27 -0
  175. package/src/cli/rum/infra-rum-status.cli-command.impl.ts +112 -0
  176. package/src/cli/rum/infra-rum.cli-group.descriptor.ts +12 -0
  177. package/src/cli/run/infra-deploy.run.cli-command.descriptor.ts +49 -0
  178. package/src/cli/run/infra-deploy.run.cli-command.impl.ts +330 -0
  179. package/src/cli/shared/discover-deployments.ts +127 -0
  180. package/src/config-loader.ts +179 -0
  181. package/src/index.ts +11 -0
  182. package/src/infra-deploy.plugin.ts +83 -0
  183. package/src/regenerate.ts +230 -0
@@ -0,0 +1,474 @@
1
+ import { getVibesRuntime } from '@vibesdotdev/runtime';
2
+ import type { VibesRuntime } from '@vibesdotdev/runtime/api/runtime';
3
+ import type { UIContext } from '@vibesdotdev/cli/providers';
4
+ import { resolveCurrentEnvironmentConfig } from '@vibesdotdev/config/environment/current';
5
+ import { spawnSync } from 'node:child_process';
6
+ import { chmod, cp, mkdir, mkdtemp, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises';
7
+ import { tmpdir } from 'node:os';
8
+ import { basename, dirname, isAbsolute, join, resolve } from 'node:path';
9
+
10
+ type SecretsStoreDescriptor = {
11
+ id: string;
12
+ backend?: string;
13
+ priority?: number;
14
+ tiers?: string[];
15
+ };
16
+
17
+ type SecretsStoreImplementation = {
18
+ get(environment: string, key: string): Promise<string | undefined>;
19
+ };
20
+
21
+ type PackageJson = {
22
+ name?: string;
23
+ version?: string;
24
+ dependencies?: Record<string, string>;
25
+ devDependencies?: Record<string, string>;
26
+ peerDependencies?: Record<string, string>;
27
+ optionalDependencies?: Record<string, string>;
28
+ publishConfig?: {
29
+ registry?: string;
30
+ access?: string;
31
+ tag?: string;
32
+ };
33
+ };
34
+
35
+ type PublishResult = {
36
+ name: string;
37
+ version: string;
38
+ packageDir: string;
39
+ tarball: string;
40
+ dryRun: boolean;
41
+ ok: boolean;
42
+ };
43
+
44
+ function readString(value: unknown): string | undefined {
45
+ return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
46
+ }
47
+
48
+ function readBoolean(value: unknown): boolean {
49
+ return value === true || value === 'true' || value === 'yes';
50
+ }
51
+
52
+ function normalizePaths(value: unknown): string[] {
53
+ if (Array.isArray(value)) return value.filter((item): item is string => typeof item === 'string');
54
+ if (typeof value === 'string' && value.length > 0) return [value];
55
+ return [process.cwd()];
56
+ }
57
+
58
+ async function resolveSecretsEnvironment(environmentOverride?: string): Promise<{
59
+ name: string;
60
+ tier: string;
61
+ }> {
62
+ if (environmentOverride) {
63
+ const knownTiers = new Set(['local', 'dev', 'staging', 'production']);
64
+ if (knownTiers.has(environmentOverride)) {
65
+ return { name: environmentOverride, tier: environmentOverride };
66
+ }
67
+ try {
68
+ const envConfig = await resolveCurrentEnvironmentConfig();
69
+ return { name: environmentOverride, tier: envConfig.tier ?? 'local' };
70
+ } catch {
71
+ return { name: environmentOverride, tier: 'local' };
72
+ }
73
+ }
74
+
75
+ try {
76
+ const envConfig = await resolveCurrentEnvironmentConfig();
77
+ return { name: envConfig.name, tier: envConfig.tier ?? 'local' };
78
+ } catch {
79
+ return { name: 'local', tier: 'local' };
80
+ }
81
+ }
82
+
83
+ async function resolveTokenFromSecrets(
84
+ runtime: VibesRuntime,
85
+ key: string,
86
+ options: { environment?: string; backend?: string }
87
+ ): Promise<{ value?: string; source?: string; environment: string; tier: string }> {
88
+ const envValue = process.env[key];
89
+ if (envValue && envValue.length > 0) {
90
+ return { value: envValue, source: 'process.env', environment: 'process', tier: 'process' };
91
+ }
92
+
93
+ const environment = await resolveSecretsEnvironment(options.environment);
94
+ if (!runtime.hasKind('secrets/store')) {
95
+ return { environment: environment.name, tier: environment.tier };
96
+ }
97
+
98
+ const descriptors = (runtime.assets('secrets/store').descriptors() as SecretsStoreDescriptor[])
99
+ .filter((descriptor) => {
100
+ if (options.backend) return descriptor.id === options.backend;
101
+ if (descriptor.backend === 'encrypted-local') return true;
102
+ if (!descriptor.tiers || descriptor.tiers.length === 0) return true;
103
+ return descriptor.tiers.includes(environment.tier);
104
+ })
105
+ .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
106
+
107
+ for (const descriptor of descriptors) {
108
+ const store = (await runtime
109
+ .query('secrets/store')
110
+ .withId(descriptor.id)
111
+ .resolve()) as SecretsStoreImplementation;
112
+ const value = await store.get(environment.name, key);
113
+ if (value && value.length > 0) {
114
+ return {
115
+ value,
116
+ source: descriptor.id,
117
+ environment: environment.name,
118
+ tier: environment.tier
119
+ };
120
+ }
121
+ }
122
+
123
+ return { environment: environment.name, tier: environment.tier };
124
+ }
125
+
126
+ async function readPackageJson(packageDir: string): Promise<PackageJson & { name: string; version: string }> {
127
+ const raw = await readFile(join(packageDir, 'package.json'), 'utf8');
128
+ const parsed = JSON.parse(raw) as PackageJson;
129
+ if (!parsed.name || !parsed.version) {
130
+ throw new Error(`${packageDir}/package.json must include name and version`);
131
+ }
132
+ return { ...parsed, name: parsed.name, version: parsed.version };
133
+ }
134
+
135
+ async function pathExists(path: string): Promise<boolean> {
136
+ try {
137
+ await stat(path);
138
+ return true;
139
+ } catch {
140
+ return false;
141
+ }
142
+ }
143
+
144
+ async function findWorkspaceRoot(startDir: string): Promise<string> {
145
+ let current = resolve(startDir);
146
+ while (true) {
147
+ const packagePath = join(current, 'package.json');
148
+ if (await pathExists(packagePath)) {
149
+ try {
150
+ const parsed = JSON.parse(await readFile(packagePath, 'utf8')) as { workspaces?: unknown };
151
+ if (parsed.workspaces) return current;
152
+ } catch {
153
+ // Keep walking; malformed package.json will be reported elsewhere.
154
+ }
155
+ }
156
+ const parent = dirname(current);
157
+ if (parent === current) return resolve(startDir);
158
+ current = parent;
159
+ }
160
+ }
161
+
162
+ async function collectWorkspaceVersions(workspaceRoot: string): Promise<Map<string, string>> {
163
+ const versions = new Map<string, string>();
164
+ const roots = ['packages', 'libraries', 'apps'].map((entry) => join(workspaceRoot, entry));
165
+
166
+ async function walk(dir: string): Promise<void> {
167
+ let entries;
168
+ try {
169
+ entries = await readdir(dir, { withFileTypes: true });
170
+ } catch {
171
+ return;
172
+ }
173
+
174
+ const packagePath = join(dir, 'package.json');
175
+ if (await pathExists(packagePath)) {
176
+ try {
177
+ const parsed = JSON.parse(await readFile(packagePath, 'utf8')) as PackageJson;
178
+ if (parsed.name && parsed.version) versions.set(parsed.name, parsed.version);
179
+ } catch {
180
+ // Ignore here; the package being published is parsed separately.
181
+ }
182
+ return;
183
+ }
184
+
185
+ for (const entry of entries) {
186
+ if (!entry.isDirectory()) continue;
187
+ if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === 'dist') continue;
188
+ await walk(join(dir, entry.name));
189
+ }
190
+ }
191
+
192
+ for (const root of roots) await walk(root);
193
+ return versions;
194
+ }
195
+
196
+ function rewriteWorkspaceDependencyVersions(pkg: PackageJson, versions: Map<string, string>): PackageJson {
197
+ const fields = ['dependencies', 'peerDependencies', 'optionalDependencies'] as const;
198
+ const next: PackageJson = { ...pkg };
199
+
200
+ for (const field of fields) {
201
+ const deps = next[field];
202
+ if (!deps) continue;
203
+ next[field] = { ...deps };
204
+ for (const [name, range] of Object.entries(deps)) {
205
+ if (!range.startsWith('workspace:')) continue;
206
+ const version = versions.get(name);
207
+ if (!version) {
208
+ throw new Error(`Cannot rewrite ${name}@${range}; workspace package version not found`);
209
+ }
210
+ next[field]![name] = version;
211
+ }
212
+ }
213
+
214
+ delete next.devDependencies;
215
+ return next;
216
+ }
217
+
218
+ async function stagePackageForPublish(options: {
219
+ packageDir: string;
220
+ stageDir: string;
221
+ versions: Map<string, string>;
222
+ }): Promise<void> {
223
+ await cp(options.packageDir, options.stageDir, {
224
+ recursive: true,
225
+ filter: (source) => {
226
+ const name = basename(source);
227
+ return ![
228
+ 'node_modules',
229
+ '.git',
230
+ '.turbo',
231
+ '.svelte-kit'
232
+ ].includes(name) && !name.endsWith('.tgz');
233
+ }
234
+ });
235
+
236
+ const packagePath = join(options.stageDir, 'package.json');
237
+ const pkg = JSON.parse(await readFile(packagePath, 'utf8')) as PackageJson;
238
+ const rewritten = rewriteWorkspaceDependencyVersions(pkg, options.versions);
239
+ await writeFile(packagePath, `${JSON.stringify(rewritten, null, 2)}\n`);
240
+ }
241
+
242
+ function npmBin(): string {
243
+ return process.platform === 'win32' ? 'npm.cmd' : 'npm';
244
+ }
245
+
246
+ function runNpm(args: string[], options: { cwd: string; env?: NodeJS.ProcessEnv }): void {
247
+ const child = spawnSync(npmBin(), args, {
248
+ cwd: options.cwd,
249
+ stdio: 'inherit',
250
+ env: options.env ?? process.env
251
+ });
252
+ if (child.error) throw child.error;
253
+ if (child.status !== 0) {
254
+ throw new Error(`npm ${args.join(' ')} failed with exit ${child.status ?? 'unknown'}`);
255
+ }
256
+ }
257
+
258
+ async function newestTarball(dir: string): Promise<string> {
259
+ const entries = await readdir(dir);
260
+ const tarballs = entries.filter((entry) => entry.endsWith('.tgz')).sort();
261
+ if (tarballs.length !== 1) {
262
+ throw new Error(`Expected one packed tarball in ${dir}, found ${tarballs.length}`);
263
+ }
264
+ return join(dir, tarballs[0]);
265
+ }
266
+
267
+ function authConfigLine(registry: string): string {
268
+ const url = new URL(registry);
269
+ const path = url.pathname.endsWith('/') ? url.pathname : `${url.pathname}/`;
270
+ return `//${url.host}${path}:_authToken`;
271
+ }
272
+
273
+ function sanitizeNpmEnv(extra: Record<string, string>): NodeJS.ProcessEnv {
274
+ const env: NodeJS.ProcessEnv = { ...process.env };
275
+ delete env.NPM_TOKEN;
276
+ delete env.NODE_AUTH_TOKEN;
277
+ delete env.NPM_CONFIG_USERCONFIG;
278
+ delete env.NPM_CONFIG_REGISTRY;
279
+ for (const [key, value] of Object.entries(extra)) env[key] = value;
280
+ return env;
281
+ }
282
+
283
+ async function writeTempNpmrc(options: {
284
+ path: string;
285
+ registry: string;
286
+ scope?: string;
287
+ token?: string;
288
+ }): Promise<void> {
289
+ const lines = [
290
+ `registry=${options.registry}`,
291
+ options.scope ? `${options.scope}:registry=${options.registry}` : undefined,
292
+ options.token ? `${authConfigLine(options.registry)}=${options.token}` : undefined
293
+ ].filter((line): line is string => Boolean(line));
294
+ await writeFile(options.path, `${lines.join('\n')}\n`, { mode: 0o600 });
295
+ await chmod(options.path, 0o600);
296
+ }
297
+
298
+ function publishArgs(options: {
299
+ tarball: string;
300
+ registry: string;
301
+ access?: string;
302
+ tag?: string;
303
+ otp?: string;
304
+ provenance: boolean;
305
+ dryRun: boolean;
306
+ }): string[] {
307
+ const args = ['publish', options.tarball, '--registry', options.registry];
308
+ if (options.access) args.push('--access', options.access);
309
+ if (options.tag) args.push('--tag', options.tag);
310
+ if (options.otp) args.push('--otp', options.otp);
311
+ if (options.provenance) args.push('--provenance');
312
+ if (options.dryRun) args.push('--dry-run');
313
+ return args;
314
+ }
315
+
316
+ async function publishPackage(options: {
317
+ packageDir: string;
318
+ registry: string;
319
+ scope?: string;
320
+ access?: string;
321
+ tag?: string;
322
+ otp?: string;
323
+ provenance: boolean;
324
+ dryRun: boolean;
325
+ token?: string;
326
+ ui: UIContext;
327
+ versions: Map<string, string>;
328
+ }): Promise<PublishResult> {
329
+ const packageDir = isAbsolute(options.packageDir)
330
+ ? options.packageDir
331
+ : resolve(process.cwd(), options.packageDir);
332
+ const pkg = await readPackageJson(packageDir);
333
+ const registry = options.registry || pkg.publishConfig?.registry || 'https://registry.npmjs.org';
334
+ const access = options.access ?? pkg.publishConfig?.access;
335
+ const tag = options.tag ?? pkg.publishConfig?.tag;
336
+ const tempRoot = await mkdtemp(join(tmpdir(), 'vibes-npm-publish-'));
337
+ const packDir = join(tempRoot, 'pack');
338
+ const stageDir = join(tempRoot, 'stage');
339
+ const npmrcPath = join(tempRoot, 'npmrc');
340
+ const homeDir = join(tempRoot, 'home');
341
+
342
+ try {
343
+ await mkdir(packDir, { recursive: true });
344
+ await mkdir(homeDir, { recursive: true });
345
+ await stagePackageForPublish({ packageDir, stageDir, versions: options.versions });
346
+ await writeTempNpmrc({
347
+ path: npmrcPath,
348
+ registry,
349
+ scope: options.scope,
350
+ token: options.token
351
+ });
352
+
353
+ options.ui.info(`Packing ${pkg.name}@${pkg.version} from ${packageDir}`);
354
+ runNpm(['pack', '--ignore-scripts', '--pack-destination', packDir], { cwd: stageDir });
355
+ const tarball = await newestTarball(packDir);
356
+
357
+ const env = sanitizeNpmEnv({
358
+ NPM_CONFIG_USERCONFIG: npmrcPath,
359
+ HOME: homeDir,
360
+ USERPROFILE: homeDir
361
+ });
362
+ const args = publishArgs({
363
+ tarball,
364
+ registry,
365
+ access,
366
+ tag,
367
+ otp: options.otp,
368
+ provenance: options.provenance,
369
+ dryRun: options.dryRun
370
+ });
371
+ options.ui.info(
372
+ `${options.dryRun ? 'Dry-running publish' : 'Publishing'} ${pkg.name}@${pkg.version} to ${registry}`
373
+ );
374
+ runNpm(args, { cwd: tempRoot, env });
375
+
376
+ return {
377
+ name: pkg.name,
378
+ version: pkg.version,
379
+ packageDir,
380
+ tarball: basename(tarball),
381
+ dryRun: options.dryRun,
382
+ ok: true
383
+ };
384
+ } finally {
385
+ await rm(tempRoot, { recursive: true, force: true });
386
+ }
387
+ }
388
+
389
+ export default {
390
+ async execute(args: Record<string, unknown>, opts: Record<string, unknown>): Promise<void> {
391
+ const runtime = getVibesRuntime();
392
+ const ui = (await runtime.context('cli/ui')) as UIContext;
393
+ const output = readString(opts.output) ?? 'text';
394
+ const dryRun = readBoolean(opts.dryRun);
395
+ const yes = readBoolean(opts.yes);
396
+ const tokenKey = readString(opts.tokenKey) ?? 'NPM_TOKEN';
397
+ const registry = readString(opts.registry) ?? 'https://registry.npmjs.org';
398
+ const scope = readString(opts.scope);
399
+ const packagePaths = normalizePaths(args.paths);
400
+ const workspaceRoot = await findWorkspaceRoot(process.cwd());
401
+ const versions = await collectWorkspaceVersions(workspaceRoot);
402
+
403
+ if (!dryRun && !yes) {
404
+ ui.error('Refusing to publish without --yes. Use --dry-run to test without publishing.');
405
+ process.exitCode = 1;
406
+ return;
407
+ }
408
+
409
+ let token: string | undefined;
410
+ let tokenSource: string | undefined;
411
+ let tokenEnvironment = 'local';
412
+ let tokenTier = 'local';
413
+ if (!dryRun) {
414
+ const resolved = await resolveTokenFromSecrets(runtime, tokenKey, {
415
+ environment: readString(opts.environment),
416
+ backend: readString(opts.backend)
417
+ });
418
+ token = resolved.value;
419
+ tokenSource = resolved.source;
420
+ tokenEnvironment = resolved.environment;
421
+ tokenTier = resolved.tier;
422
+ if (!token) {
423
+ ui.error(
424
+ `Missing ${tokenKey}. Store it with \`vibes secrets set ${tokenKey} --environment ${tokenEnvironment}\` and rerun.`
425
+ );
426
+ ui.info('Create a publish token at https://www.npmjs.com/settings/tokens');
427
+ process.exitCode = 1;
428
+ return;
429
+ }
430
+ ui.info(`Resolved ${tokenKey} from ${tokenSource} (${tokenEnvironment}/${tokenTier}).`);
431
+ }
432
+
433
+ const results: PublishResult[] = [];
434
+ try {
435
+ for (const packagePath of packagePaths) {
436
+ results.push(
437
+ await publishPackage({
438
+ packageDir: packagePath,
439
+ registry,
440
+ scope,
441
+ access: readString(opts.access),
442
+ tag: readString(opts.tag),
443
+ otp: readString(opts.otp),
444
+ provenance: readBoolean(opts.provenance),
445
+ dryRun,
446
+ token,
447
+ ui,
448
+ versions
449
+ })
450
+ );
451
+ }
452
+ } catch (error) {
453
+ const message = error instanceof Error ? error.message : String(error);
454
+ if (output === 'json') {
455
+ ui.json({ ok: false, error: message, results });
456
+ } else {
457
+ ui.error(message);
458
+ }
459
+ process.exitCode = 1;
460
+ return;
461
+ }
462
+
463
+ if (output === 'json') {
464
+ ui.json({ ok: true, dryRun, results });
465
+ return;
466
+ }
467
+
468
+ ui.success(
469
+ dryRun
470
+ ? `npm publish dry-run completed for ${results.length} package(s).`
471
+ : `Published ${results.length} npm package(s).`
472
+ );
473
+ }
474
+ };
@@ -0,0 +1,12 @@
1
+ import { createRuntimeAsset } from '@vibesdotdev/runtime';
2
+
3
+ export default createRuntimeAsset({
4
+ id: 'infra-npm',
5
+ kind: 'cli/group',
6
+ name: 'npm',
7
+ description: 'npm registry publishing commands',
8
+ parent: 'infra',
9
+ surfaces: ['cli'],
10
+ hardware: ['consumer', 'cloud'],
11
+ enabled: true
12
+ });
@@ -0,0 +1,57 @@
1
+ import { createRuntimeAsset } from '@vibesdotdev/runtime';
2
+
3
+ export default createRuntimeAsset({
4
+ id: 'infra-observability.set',
5
+ kind: 'cli/command',
6
+ name: 'set',
7
+ description: 'Update observability config (sampling, logs/traces enabled) on Worker(s)',
8
+ group: 'infra-observability',
9
+ options: [
10
+ {
11
+ flags: '--worker <name>',
12
+ description: 'Scope to a single Worker (omit for fleet-wide apply)'
13
+ },
14
+ {
15
+ flags: '--filter <glob>',
16
+ description: 'Glob to narrow the fleet apply (e.g. "vibes-*")'
17
+ },
18
+ {
19
+ flags: '--sampling <rate>',
20
+ description: 'Logs head sampling rate (0..1; e.g. 0.1 for 10%)'
21
+ },
22
+ {
23
+ flags: '--logs <enabled>',
24
+ description: 'Enable/disable logs (true|false)'
25
+ },
26
+ {
27
+ flags: '--traces <enabled>',
28
+ description: 'Enable/disable traces (true|false)'
29
+ },
30
+ {
31
+ flags: '--provider <id>',
32
+ description: 'Provider impl id (default: cloudflare-workers-observability)'
33
+ },
34
+ {
35
+ flags: '--environment <name>',
36
+ description: 'Vibes environment for secret resolution (local|dev|staging|production)'
37
+ },
38
+ {
39
+ flags: '--dry-run',
40
+ description: 'Show what would change; do not write',
41
+ default: false
42
+ },
43
+ {
44
+ flags: '-y, --yes',
45
+ description: 'Skip confirmation prompt for multi-worker changes',
46
+ default: false
47
+ },
48
+ {
49
+ flags: '-o, --output <format>',
50
+ description: 'Output format (text|json)',
51
+ default: 'text'
52
+ }
53
+ ],
54
+ surfaces: ['cli'],
55
+ hardware: ['consumer', 'cloud'],
56
+ enabled: true
57
+ });