@dzhechkov/cloudru-hub 0.1.14 → 0.1.16

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.
@@ -0,0 +1,84 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "horizonHours": "24",
4
+ "currency": "RUB",
5
+ "vatBasis": "included",
6
+ "workload": {
7
+ "replicas": 3,
8
+ "cpuPerReplica": "1",
9
+ "ramGBPerReplica": "1",
10
+ "survivingReplicas": 2,
11
+ "failedNodes": 1
12
+ },
13
+ "equivalence": {
14
+ "status": "unknown",
15
+ "reason": "Application placement, availability and performance equivalence have not been verified.",
16
+ "assumptions": ["Both scenarios run the same three replicas for the full 24-hour horizon."]
17
+ },
18
+ "scenarios": [
19
+ {
20
+ "id": "vm",
21
+ "kind": "vm",
22
+ "nodes": { "count": 3, "cpu": "2", "ramGB": "4", "reservedCpu": "0", "reservedRamGB": "0", "cpuShare": "1" },
23
+ "controlPlaneCount": 0,
24
+ "resources": { "storageGB": "60", "publicIpCount": 3, "snatGatewayCount": 0, "loadBalancerCount": 0, "trafficGB": null },
25
+ "categories": {
26
+ "compute": { "status": "priced", "items": [{
27
+ "id": "vm-2cpu-4gb", "description": "Three active 2vCPU/4GB VM instances",
28
+ "quantity": "3", "unit": "instance-hour", "rateRub": "2.9707",
29
+ "tariff": { "url": "https://cdn.cloud.ru/docs/legal/tariffs/evolution/current-version/evolution-compute.pdf", "version": "261014", "asOf": "2026-10-21", "vatBasis": "included", "pageOrRow": "VM 2vCPU/4GB row 18", "sha256": "a459226e73c8db4dc650307f3f07d99d9f17be31e0e22cd65c7a360dc1685dc5" }
30
+ }] },
31
+ "controlPlane": { "status": "not-used", "reason": "VM scenario has no separately billed control-plane service." },
32
+ "storage": { "status": "priced", "items": [{
33
+ "id": "ssd-60gb", "description": "Assumed 60GB billed SSD allocation across the VM scenario",
34
+ "quantity": "60", "unit": "GB-hour", "rateRub": "0.01586",
35
+ "tariff": { "url": "https://cdn.cloud.ru/docs/legal/tariffs/evolution/current-version/evolution-compute.pdf", "version": "261014", "asOf": "2026-10-21", "vatBasis": "included", "pageOrRow": "SSD row 85", "sha256": "a459226e73c8db4dc650307f3f07d99d9f17be31e0e22cd65c7a360dc1685dc5" }
36
+ }] },
37
+ "publicIp": { "status": "priced", "items": [{
38
+ "id": "vm-public-ip", "description": "Three assumed active public IP allocations",
39
+ "quantity": "3", "unit": "IP-hour", "rateRub": "0.2074",
40
+ "tariff": { "url": "https://cdn.cloud.ru/docs/legal/tariffs/evolution/current-version/evolution-compute.pdf", "version": "261014", "asOf": "2026-10-21", "vatBasis": "included", "pageOrRow": "Public IP row 2", "sha256": "a459226e73c8db4dc650307f3f07d99d9f17be31e0e22cd65c7a360dc1685dc5" }
41
+ }] },
42
+ "snat": { "status": "not-used", "reason": "No SNAT gateway is declared in this VM scenario." },
43
+ "loadBalancer": { "status": "not-used", "reason": "No load balancer is declared; direct public IP exposure is assumed." },
44
+ "traffic": { "status": "unpriced", "reason": "Traffic quantity and applicable tariff are unknown; do not assume zero traffic cost." }
45
+ }
46
+ },
47
+ {
48
+ "id": "k8s",
49
+ "kind": "k8s",
50
+ "nodes": { "count": 3, "cpu": "2", "ramGB": "4", "reservedCpu": "0", "reservedRamGB": "0", "cpuShare": "1" },
51
+ "controlPlaneCount": 1,
52
+ "resources": { "storageGB": "80", "publicIpCount": 2, "snatGatewayCount": 1, "loadBalancerCount": 0, "trafficGB": null },
53
+ "categories": {
54
+ "compute": { "status": "priced", "items": [{
55
+ "id": "worker-2cpu-4gb", "description": "Three active 2vCPU/4GB Kubernetes workers",
56
+ "quantity": "3", "unit": "instance-hour", "rateRub": "2.9768",
57
+ "tariff": { "url": "https://cdn.cloud.ru/docs/legal/tariffs/evolution/current-version/managed-kubernetes.pdf", "version": "260918", "asOf": "2026-10-21", "vatBasis": "included", "pageOrRow": "Worker 2vCPU/4GB row 6", "sha256": "5493f6da595b67482277ca420512db8f7f953375536a6169db8d1b282f24f345" }
58
+ }] },
59
+ "controlPlane": { "status": "priced", "items": [{
60
+ "id": "zonal-master", "description": "One billed zonal control-plane service instance",
61
+ "quantity": "1", "unit": "instance-hour", "rateRub": "8.601",
62
+ "tariff": { "url": "https://cdn.cloud.ru/docs/legal/tariffs/evolution/current-version/managed-kubernetes.pdf", "version": "260918", "asOf": "2026-10-21", "vatBasis": "included", "pageOrRow": "Zonal master 2vCPU/4GB row 42", "sha256": "5493f6da595b67482277ca420512db8f7f953375536a6169db8d1b282f24f345" }
63
+ }] },
64
+ "storage": { "status": "priced", "items": [{
65
+ "id": "ssd-80gb", "description": "Assumed 80GB billed SSD allocation across the Kubernetes scenario",
66
+ "quantity": "80", "unit": "GB-hour", "rateRub": "0.01586",
67
+ "tariff": { "url": "https://cdn.cloud.ru/docs/legal/tariffs/evolution/current-version/managed-kubernetes.pdf", "version": "260918", "asOf": "2026-10-21", "vatBasis": "included", "pageOrRow": "SSD row 39", "sha256": "5493f6da595b67482277ca420512db8f7f953375536a6169db8d1b282f24f345" }
68
+ }] },
69
+ "publicIp": { "status": "priced", "items": [{
70
+ "id": "k8s-public-ip", "description": "Two assumed active public IP allocations",
71
+ "quantity": "2", "unit": "IP-hour", "rateRub": "0.2074",
72
+ "tariff": { "url": "https://cdn.cloud.ru/docs/legal/tariffs/evolution/current-version/managed-kubernetes.pdf", "version": "260918", "asOf": "2026-10-21", "vatBasis": "included", "pageOrRow": "Public IP row 40", "sha256": "5493f6da595b67482277ca420512db8f7f953375536a6169db8d1b282f24f345" }
73
+ }] },
74
+ "snat": { "status": "priced", "items": [{
75
+ "id": "public-snat", "description": "One assumed active public SNAT gateway",
76
+ "quantity": "1", "unit": "gateway-hour", "rateRub": "0.2074",
77
+ "tariff": { "url": "https://cdn.cloud.ru/docs/legal/tariffs/evolution/current-version/evolution-compute.pdf", "version": "261014", "asOf": "2026-10-21", "vatBasis": "included", "pageOrRow": "Public SNAT row 3", "sha256": "a459226e73c8db4dc650307f3f07d99d9f17be31e0e22cd65c7a360dc1685dc5" }
78
+ }] },
79
+ "loadBalancer": { "status": "not-used", "reason": "No load balancer is declared; the assumed application architecture avoids it." },
80
+ "traffic": { "status": "unpriced", "reason": "Traffic quantity and applicable tariff are unknown; do not assume zero traffic cost." }
81
+ }
82
+ }
83
+ ]
84
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/cloudru-hub",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "licenseHold": {
5
5
  "adr": "features/hermes-claude-adaptation/03_adr/001-licence-and-provenance-precondition.md",
6
6
  "note": "SATISFIED hold. Timur is credited for substantial Cloud.ru API testing. The 2026-10-20 correction is in the historical grant record. This field keeps the dz guard licence-hold rule checking LICENSE, THIRD_PARTY_NOTICES and SPDX on every publish."
@@ -26,9 +26,9 @@
26
26
  ],
27
27
  "cloudruHub": {
28
28
  "binaryHashes": {
29
- "linux-x64": "4463b09323c9dfe0c32d618d335734a947e7fab0a75d07a7bea089b97a97c9b6"
29
+ "linux-x64": "94fdba4fe4d1a71e684be998c3d2f94f374ff4e4054db2683bcc04d72bfabc03"
30
30
  },
31
- "engineVersion": "cloudru-vm 0.2.6-20261020",
31
+ "engineVersion": "cloudru-vm 0.2.7-20261029",
32
32
  "platformPackages": {
33
33
  "linux-x64": "@dzhechkov/cloudru-vm-linux-x64"
34
34
  }
@@ -53,15 +53,12 @@
53
53
  "yaml": "^2.9.0"
54
54
  },
55
55
  "optionalDependencies": {
56
- "@dzhechkov/cloudru-vm-linux-x64": "0.2.6"
57
- },
58
- "scripts": {
59
- "test": "node --test 'test/*.test.mjs'"
56
+ "@dzhechkov/cloudru-vm-linux-x64": "0.2.7"
60
57
  },
61
58
  "repository": {
62
59
  "type": "git",
63
60
  "url": "git+https://github.com/djd1m/dz-harness.git",
64
- "directory": "packages/@dzhechkov/cloudru-hub"
61
+ "directory": "packages/cloudru-hub"
65
62
  },
66
63
  "homepage": "https://aicoding.space",
67
64
  "bugs": {
@@ -69,5 +66,8 @@
69
66
  },
70
67
  "publishConfig": {
71
68
  "access": "public"
69
+ },
70
+ "scripts": {
71
+ "test": "node --test 'test/*.test.mjs'"
72
72
  }
73
- }
73
+ }
package/sbom.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "hashes": [
16
16
  {
17
17
  "alg": "SHA-256",
18
- "content": "4d6d0e6f47b09b017a32e4f3287c0669821e61569835c397245e5077435f5b15"
18
+ "content": "56ba17ee84afe937d3f13c17387b26090e42217b1c8ffd9eee175a5512a14091"
19
19
  }
20
20
  ]
21
21
  },
@@ -35,7 +35,7 @@
35
35
  "hashes": [
36
36
  {
37
37
  "alg": "SHA-256",
38
- "content": "2c25bbd9659f1a02e2a7a5413de8673e8735d67e583458fdede75dfd032b6106"
38
+ "content": "bfd1c00de39c986cebad2e3fb00fa072ad0b4ecb3cb07f744920bf80474ecb47"
39
39
  }
40
40
  ]
41
41
  },
@@ -75,7 +75,7 @@
75
75
  "hashes": [
76
76
  {
77
77
  "alg": "SHA-256",
78
- "content": "6f4557d97b90936ef153dc90eac4bdceb6846b6d08d8aec45c86baac328cca60"
78
+ "content": "32845b9cc1ad64f2f6a8d4eeb8b90bf36710590d25db4234e6813793ef63c5d4"
79
79
  }
80
80
  ]
81
81
  },
@@ -85,7 +85,7 @@
85
85
  "hashes": [
86
86
  {
87
87
  "alg": "SHA-256",
88
- "content": "9abb3ca6347b0cd6cd51b23649c59e0a0c816e6c12a325f573b392affa350d0b"
88
+ "content": "a4bf5a2e76d4f9bd686bec704919ab3380bb22ff46a399b058dc5b3e71a64dd1"
89
89
  }
90
90
  ]
91
91
  },
@@ -95,7 +95,17 @@
95
95
  "hashes": [
96
96
  {
97
97
  "alg": "SHA-256",
98
- "content": "dff98bb859dfbbf8ed2fb6f16f17b767444cc2172ecc7684ca3df8188c95707c"
98
+ "content": "6864bb944ebf780454d266fe7ad47e9cec12969fb66fa9e9a1963b547944e10f"
99
+ }
100
+ ]
101
+ },
102
+ {
103
+ "type": "file",
104
+ "name": "docs/COST-COMPARE.md",
105
+ "hashes": [
106
+ {
107
+ "alg": "SHA-256",
108
+ "content": "80b4d7ac3868f17d93565274cd6736fe5f2bd7fb059cbed0c2f0afe3f4924317"
99
109
  }
100
110
  ]
101
111
  },
@@ -105,7 +115,7 @@
105
115
  "hashes": [
106
116
  {
107
117
  "alg": "SHA-256",
108
- "content": "3605797972f9a7c79c13fbcce0cd9ac8b8fb3a8249abbab938f2b1a45f515420"
118
+ "content": "00a5c9acc3999c5e07f230ba63bc1a0e202d62c8d15d2204620feca762eece8f"
109
119
  }
110
120
  ]
111
121
  },
@@ -115,7 +125,27 @@
115
125
  "hashes": [
116
126
  {
117
127
  "alg": "SHA-256",
118
- "content": "de6f709e820fbb831f390e274238b28ba938644670a8db04fd50d1fa0d86da75"
128
+ "content": "7f5cc32d5f089c66246f8349f86fc72dfe6397de7a63edf51692da8583231b41"
129
+ }
130
+ ]
131
+ },
132
+ {
133
+ "type": "file",
134
+ "name": "docs/WEB-IMAGE.md",
135
+ "hashes": [
136
+ {
137
+ "alg": "SHA-256",
138
+ "content": "690e092bafddc862c20ebd5ff0358a4c57f84881153c235a146e258563459f27"
139
+ }
140
+ ]
141
+ },
142
+ {
143
+ "type": "file",
144
+ "name": "docs/cost-compare.example.json",
145
+ "hashes": [
146
+ {
147
+ "alg": "SHA-256",
148
+ "content": "7eafb1ff555fb5443ded1a2c578b17eae6e73e3056efb9cbb5129b424c8c5097"
119
149
  }
120
150
  ]
121
151
  },
@@ -129,7 +159,7 @@
129
159
  },
130
160
  {
131
161
  "name": "dz:canonical-json-sha256-v2",
132
- "value": "d906ed1871af834274d77dbd3a345b168604456b15360f009a9474778273b11f"
162
+ "value": "94247888df4287a6077204c369ccb685a51b1d943635d51c6228dc1f8fe54635"
133
163
  }
134
164
  ]
135
165
  },
@@ -149,7 +179,17 @@
149
179
  "hashes": [
150
180
  {
151
181
  "alg": "SHA-256",
152
- "content": "a22f3fcced6e9970e7bed6b935fc03637b6d4b8d3cd6cc65a2685595a6549c1c"
182
+ "content": "590265903b3a242b3d9c1367801ce6ce10e23e18abbc28938c5a26f735ea7d75"
183
+ }
184
+ ]
185
+ },
186
+ {
187
+ "type": "file",
188
+ "name": "src/cost-compare.js",
189
+ "hashes": [
190
+ {
191
+ "alg": "SHA-256",
192
+ "content": "6084ecd7f7fc53bbd441fb9e91dcd7c7bd5c409d1d4e95613fad0fd0735b7b05"
153
193
  }
154
194
  ]
155
195
  },
@@ -189,7 +229,7 @@
189
229
  "hashes": [
190
230
  {
191
231
  "alg": "SHA-256",
192
- "content": "c928db48febfb4a79884ce1830365a8302122a55fb5d6ada8e771c049396ca89"
232
+ "content": "90af414aabda1c48c82c9c2ecf0dbe4d7dd4744486efdce0d8367182b6a67a38"
193
233
  }
194
234
  ]
195
235
  },
@@ -199,7 +239,17 @@
199
239
  "hashes": [
200
240
  {
201
241
  "alg": "SHA-256",
202
- "content": "014c2effd1e843d870ae1af4f93f5c82faff9972e9f6ca028ed39d47ec33ee3a"
242
+ "content": "950543b85a7ed2c8e1660b40c2bb50192663e5fe62f8287b9b76ac3f8178c263"
243
+ }
244
+ ]
245
+ },
246
+ {
247
+ "type": "file",
248
+ "name": "src/k8s-image-manifest.js",
249
+ "hashes": [
250
+ {
251
+ "alg": "SHA-256",
252
+ "content": "8a2c519e9bc6677c867758f4b9b56146f2832ee07a5bfd4fefed3317f0d9cf73"
203
253
  }
204
254
  ]
205
255
  },
@@ -229,7 +279,7 @@
229
279
  "hashes": [
230
280
  {
231
281
  "alg": "SHA-256",
232
- "content": "4f95cfb9576c411232503b26053ece6d8d186e4b337beff9bd4afd249f74a014"
282
+ "content": "60a5db44db9518835f98f23aa104b86c3621f0b0c030196c2130715f5c19c219"
233
283
  }
234
284
  ]
235
285
  },
@@ -239,7 +289,7 @@
239
289
  "hashes": [
240
290
  {
241
291
  "alg": "SHA-256",
242
- "content": "89229c882b6a3f5bb9ee542b31d1a40374b91879747582a3e82e8aadc72decb3"
292
+ "content": "0a66e73476d5f5624908f05f621b150efa51217fc9418938ca126dc0dc2b9518"
243
293
  }
244
294
  ]
245
295
  },
@@ -269,7 +319,17 @@
269
319
  "hashes": [
270
320
  {
271
321
  "alg": "SHA-256",
272
- "content": "026e3031180ce9227b4d31775b9c886b10ad0cb418ed0754aed75b12ded84e31"
322
+ "content": "413ddf6d9a4f709d80bce9011094d95bbe56f12c391f72be235c4482a1b40450"
323
+ }
324
+ ]
325
+ },
326
+ {
327
+ "type": "file",
328
+ "name": "test/cost-compare.test.mjs",
329
+ "hashes": [
330
+ {
331
+ "alg": "SHA-256",
332
+ "content": "b354913220bf725ec6b8a708b7851e2f5779a3c594cd411732d19acad9001870"
273
333
  }
274
334
  ]
275
335
  },
@@ -279,7 +339,7 @@
279
339
  "hashes": [
280
340
  {
281
341
  "alg": "SHA-256",
282
- "content": "d72e4363fd50d0fcc65fd23b40601516bd73368c3659f2a55a394c4d1ed3f85c"
342
+ "content": "3aaf3cdf27c57be9121d7d1727335d0a97064659b3201d34d1e27f5aed631434"
283
343
  }
284
344
  ]
285
345
  },
@@ -319,7 +379,7 @@
319
379
  "hashes": [
320
380
  {
321
381
  "alg": "SHA-256",
322
- "content": "af04d1941fb7aed2cc51b05f65ffed1c440d4d23a7fb26e13261d45e07b0a1f8"
382
+ "content": "acc30164bbafc2d46b404ff8ae87caf42e301e15dd005c424654ee0225af6efd"
323
383
  }
324
384
  ]
325
385
  },
@@ -359,7 +419,7 @@
359
419
  "hashes": [
360
420
  {
361
421
  "alg": "SHA-256",
362
- "content": "9ad83ba418dee86ef680575a0cc7da4af4be3ae995c00f23f84b336838fbda47"
422
+ "content": "b447a8755c67bcbfc3db63c909235f34414721139c7bc7fdf0658ab0638e7980"
363
423
  }
364
424
  ]
365
425
  },
@@ -369,7 +429,7 @@
369
429
  "hashes": [
370
430
  {
371
431
  "alg": "SHA-256",
372
- "content": "45406dabeee0635ede5cda3d2f4144c5c13886d624287fd223b01252d2859b87"
432
+ "content": "e99200ccdd8368260af18532478addc08e3b6195986cecf68b669e9dc639d119"
373
433
  }
374
434
  ]
375
435
  }
package/src/cli.js CHANGED
@@ -3,14 +3,21 @@
3
3
  // Zero dependencies, CommonJS, boots from any cwd (dz release smoke contract).
4
4
 
5
5
  const { spawn, spawnSync } = require('child_process');
6
- const { resolveEngine } = require('./resolve');
7
- const { loadClassification, loadSnapshot, coverageGaps } = require('./classification');
8
- const { install } = require('./install');
9
- const { runSafeMcp } = require('./safe-mcp');
10
- const { issueApproval } = require('./deploy-approval');
11
- const { issueK8sApproval } = require('./k8s-approval');
12
- const { compileSkill, writeCompiled } = require('./dialects');
13
6
  const PKG = require('../package.json');
7
+ let resolveEngine, loadClassification, loadSnapshot, coverageGaps, install, runSafeMcp;
8
+ let issueApproval, issueK8sApproval, compileSkill, writeCompiled;
9
+ let legacyLoaded = false;
10
+ function loadLegacyCommands() {
11
+ if (legacyLoaded) return;
12
+ ({ resolveEngine } = require('./resolve'));
13
+ ({ loadClassification, loadSnapshot, coverageGaps } = require('./classification'));
14
+ ({ install } = require('./install'));
15
+ ({ runSafeMcp } = require('./safe-mcp'));
16
+ ({ issueApproval } = require('./deploy-approval'));
17
+ ({ issueK8sApproval } = require('./k8s-approval'));
18
+ ({ compileSkill, writeCompiled } = require('./dialects'));
19
+ legacyLoaded = true;
20
+ }
14
21
 
15
22
  function showHelp(write) {
16
23
  write(`cloudru-hub ${PKG.version} — unofficial Cloud.ru Evolution launcher (NOT affiliated with Cloud.ru)
@@ -31,7 +38,10 @@ Commands:
31
38
  Authorize one exact VM plan for ten minutes within a RUB/month cap.
32
39
  Static sites require the artifact digest shown by deploy_plan.
33
40
  k8s-approve --cluster-id <uuid> --namespace <name> --manifest <file> --manifest-sha256 <digest>
34
- Authorize one exact three-resource Snake manifest on an existing cluster.
41
+ [--profile snake|web-image]
42
+ Authorize one exact bounded manifest on an existing cluster.
43
+ cost-compare --input <json> [--json]
44
+ Offline VM vs Kubernetes cost worksheet; no engine or credentials.
35
45
  install --target <t> claude-code: permissions + executed hook probe;
36
46
  codex|opencode|pi: project MCP config using mcp-safe;
37
47
  hermes: guarded $HERMES_HOME/config.yaml entry using mcp-safe;
@@ -139,6 +149,9 @@ function cmdMcp() {
139
149
  }
140
150
 
141
151
  function main(argv, write = (s) => process.stdout.write(s + '\n')) {
152
+ // This command validates its raw flags before the permissive legacy parser sees them.
153
+ if (argv[0] === 'cost-compare') return require('./cost-compare').run(argv.slice(1), write);
154
+ loadLegacyCommands();
142
155
  const { flags, opts, positional } = parseArgs(argv);
143
156
  const cmd = positional[0] || 'help';
144
157
  if (flags.has('help') || flags.has('h') || cmd === 'help') { showHelp(write); return 0; }
@@ -178,7 +191,7 @@ function main(argv, write = (s) => process.stdout.write(s + '\n')) {
178
191
  case 'k8s-approve': {
179
192
  try {
180
193
  const approval = issueK8sApproval(opts.get('cluster-id'), opts.get('namespace'),
181
- opts.get('manifest'), opts.get('manifest-sha256'));
194
+ opts.get('manifest'), opts.get('manifest-sha256'), process.env, Date.now(), opts.get('profile') || 'snake');
182
195
  write(flags.has('json') ? JSON.stringify(approval, null, 2) :
183
196
  `approved ${approval.approvalId}: cluster ${approval.clusterId}, namespace ${approval.namespace}, SHA-256 ${approval.manifestSha256}; expires ${new Date(approval.expiresAt).toISOString()}`);
184
197
  return 0;