@tiangong-ai/cli 0.0.61 → 0.0.63

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 (216) hide show
  1. package/AGENTS.md +17 -6
  2. package/CONTRIBUTING.md +5 -5
  3. package/README.md +417 -36
  4. package/dist/cli.js +2 -2
  5. package/dist/data/builtins.js +33 -5
  6. package/dist/data/builtins.js.map +1 -1
  7. package/dist/data/catalog.js +46 -0
  8. package/dist/data/catalog.js.map +1 -1
  9. package/dist/data/commands.js +15 -1
  10. package/dist/data/commands.js.map +1 -1
  11. package/dist/data/connectors/airnow-hourly-observations.js +60 -10
  12. package/dist/data/connectors/airnow-hourly-observations.js.map +1 -1
  13. package/dist/data/connectors/epa-eis-records.js +16 -2
  14. package/dist/data/connectors/epa-eis-records.js.map +1 -1
  15. package/dist/data/connectors/gdelt-doc-search.js +54 -18
  16. package/dist/data/connectors/gdelt-doc-search.js.map +1 -1
  17. package/dist/data/connectors/gdelt-file-feeds.js +20 -11
  18. package/dist/data/connectors/gdelt-file-feeds.js.map +1 -1
  19. package/dist/data/connectors/gdelt-web-ngrams.d.ts +2 -0
  20. package/dist/data/connectors/gdelt-web-ngrams.js +350 -0
  21. package/dist/data/connectors/gdelt-web-ngrams.js.map +1 -0
  22. package/dist/data/connectors/gdelt-web-ngrams.schemas.d.ts +188 -0
  23. package/dist/data/connectors/gdelt-web-ngrams.schemas.js +138 -0
  24. package/dist/data/connectors/gdelt-web-ngrams.schemas.js.map +1 -0
  25. package/dist/data/connectors/nasa-firms-fire.js +4 -0
  26. package/dist/data/connectors/nasa-firms-fire.js.map +1 -1
  27. package/dist/data/connectors/open-meteo-air-quality.js +27 -22
  28. package/dist/data/connectors/open-meteo-air-quality.js.map +1 -1
  29. package/dist/data/connectors/open-meteo-air-quality.schemas.d.ts +4 -1
  30. package/dist/data/connectors/open-meteo-air-quality.schemas.js +21 -1
  31. package/dist/data/connectors/open-meteo-air-quality.schemas.js.map +1 -1
  32. package/dist/data/connectors/open-meteo-flood.js +28 -23
  33. package/dist/data/connectors/open-meteo-flood.js.map +1 -1
  34. package/dist/data/connectors/open-meteo-flood.schemas.d.ts +4 -1
  35. package/dist/data/connectors/open-meteo-flood.schemas.js +21 -1
  36. package/dist/data/connectors/open-meteo-flood.schemas.js.map +1 -1
  37. package/dist/data/connectors/open-meteo-historical-weather.js +26 -21
  38. package/dist/data/connectors/open-meteo-historical-weather.js.map +1 -1
  39. package/dist/data/connectors/open-meteo-historical-weather.schemas.d.ts +4 -1
  40. package/dist/data/connectors/open-meteo-historical-weather.schemas.js +21 -1
  41. package/dist/data/connectors/open-meteo-historical-weather.schemas.js.map +1 -1
  42. package/dist/data/connectors/openaq-air-quality.js +50 -12
  43. package/dist/data/connectors/openaq-air-quality.js.map +1 -1
  44. package/dist/data/connectors/openaq-air-quality.schemas.d.ts +0 -4
  45. package/dist/data/connectors/openaq-air-quality.schemas.js +2 -2
  46. package/dist/data/connectors/openaq-air-quality.schemas.js.map +1 -1
  47. package/dist/data/connectors/youtube-public-content.js +76 -6
  48. package/dist/data/connectors/youtube-public-content.js.map +1 -1
  49. package/dist/data/connectors/youtube-public-content.schemas.d.ts +63 -3
  50. package/dist/data/connectors/youtube-public-content.schemas.js +56 -2
  51. package/dist/data/connectors/youtube-public-content.schemas.js.map +1 -1
  52. package/dist/data/contracts.d.ts +22 -1
  53. package/dist/data/runtime/bounded-http.d.ts +2 -0
  54. package/dist/data/runtime/bounded-http.js +221 -59
  55. package/dist/data/runtime/bounded-http.js.map +1 -1
  56. package/dist/data/runtime/execute.d.ts +2 -0
  57. package/dist/data/runtime/execute.js +82 -60
  58. package/dist/data/runtime/execute.js.map +1 -1
  59. package/dist/data/runtime/http-timing.d.ts +15 -0
  60. package/dist/data/runtime/http-timing.js +59 -0
  61. package/dist/data/runtime/http-timing.js.map +1 -0
  62. package/dist/data/runtime/http-transport.d.ts +1 -0
  63. package/dist/data/runtime/http-transport.js +27 -0
  64. package/dist/data/runtime/http-transport.js.map +1 -0
  65. package/dist/data/schemas/catalog.v1.json +46 -0
  66. package/dist/data/schemas/discovery.v1.json +12 -0
  67. package/dist/data/schemas/error.v1.json +1 -0
  68. package/dist/data/schemas/manifest.v1.json +19 -1
  69. package/dist/research/orchestration.js +233 -10
  70. package/dist/research/orchestration.js.map +1 -1
  71. package/dist/research/setup-command.js +37 -6
  72. package/dist/research/setup-command.js.map +1 -1
  73. package/dist/research/workspace/audit-bundle.js +28 -8
  74. package/dist/research/workspace/audit-bundle.js.map +1 -1
  75. package/dist/research/workspace/broker.js +25 -4
  76. package/dist/research/workspace/broker.js.map +1 -1
  77. package/dist/research/workspace/constants.d.ts +1 -0
  78. package/dist/research/workspace/constants.js +1 -0
  79. package/dist/research/workspace/constants.js.map +1 -1
  80. package/dist/research/workspace/content-evidence.d.ts +1 -0
  81. package/dist/research/workspace/content-evidence.js +1 -1
  82. package/dist/research/workspace/content-evidence.js.map +1 -1
  83. package/dist/research/workspace/credentials.js +2 -1
  84. package/dist/research/workspace/credentials.js.map +1 -1
  85. package/dist/research/workspace/data-evidence-adapter.d.ts +71 -0
  86. package/dist/research/workspace/data-evidence-adapter.js +269 -59
  87. package/dist/research/workspace/data-evidence-adapter.js.map +1 -1
  88. package/dist/research/workspace/data-evidence-view.d.ts +58 -0
  89. package/dist/research/workspace/data-evidence-view.js +411 -0
  90. package/dist/research/workspace/data-evidence-view.js.map +1 -0
  91. package/dist/research/workspace/evidence-ledger.js +32 -29
  92. package/dist/research/workspace/evidence-ledger.js.map +1 -1
  93. package/dist/research/workspace/evidence.d.ts +28 -0
  94. package/dist/research/workspace/evidence.js +48 -0
  95. package/dist/research/workspace/evidence.js.map +1 -1
  96. package/dist/research/workspace/executor.d.ts +27 -1
  97. package/dist/research/workspace/executor.js +180 -20
  98. package/dist/research/workspace/executor.js.map +1 -1
  99. package/dist/research/workspace/external-skills.d.ts +1 -0
  100. package/dist/research/workspace/external-skills.js +4 -2
  101. package/dist/research/workspace/external-skills.js.map +1 -1
  102. package/dist/research/workspace/investigation-attempt.d.ts +159 -0
  103. package/dist/research/workspace/investigation-attempt.js +619 -0
  104. package/dist/research/workspace/investigation-attempt.js.map +1 -0
  105. package/dist/research/workspace/investigation-audit.d.ts +20 -0
  106. package/dist/research/workspace/investigation-audit.js +306 -0
  107. package/dist/research/workspace/investigation-audit.js.map +1 -0
  108. package/dist/research/workspace/investigation-candidate.d.ts +84 -0
  109. package/dist/research/workspace/investigation-candidate.js +156 -0
  110. package/dist/research/workspace/investigation-candidate.js.map +1 -0
  111. package/dist/research/workspace/investigation-certification.d.ts +39 -0
  112. package/dist/research/workspace/investigation-certification.js +152 -0
  113. package/dist/research/workspace/investigation-certification.js.map +1 -0
  114. package/dist/research/workspace/investigation-close.d.ts +47 -0
  115. package/dist/research/workspace/investigation-close.js +153 -0
  116. package/dist/research/workspace/investigation-close.js.map +1 -0
  117. package/dist/research/workspace/investigation-lineage.d.ts +8 -0
  118. package/dist/research/workspace/investigation-lineage.js +10 -0
  119. package/dist/research/workspace/investigation-lineage.js.map +1 -0
  120. package/dist/research/workspace/investigation-observer.d.ts +22 -0
  121. package/dist/research/workspace/investigation-observer.js +122 -0
  122. package/dist/research/workspace/investigation-observer.js.map +1 -0
  123. package/dist/research/workspace/investigation-promotion.d.ts +129 -0
  124. package/dist/research/workspace/investigation-promotion.js +316 -0
  125. package/dist/research/workspace/investigation-promotion.js.map +1 -0
  126. package/dist/research/workspace/investigation-requirements.d.ts +5 -0
  127. package/dist/research/workspace/investigation-requirements.js +32 -0
  128. package/dist/research/workspace/investigation-requirements.js.map +1 -0
  129. package/dist/research/workspace/investigation-resources.d.ts +12 -0
  130. package/dist/research/workspace/investigation-resources.js +78 -0
  131. package/dist/research/workspace/investigation-resources.js.map +1 -0
  132. package/dist/research/workspace/investigation-source-export.d.ts +6 -0
  133. package/dist/research/workspace/investigation-source-export.js +68 -0
  134. package/dist/research/workspace/investigation-source-export.js.map +1 -0
  135. package/dist/research/workspace/investigation-store.d.ts +9 -0
  136. package/dist/research/workspace/investigation-store.js +55 -0
  137. package/dist/research/workspace/investigation-store.js.map +1 -0
  138. package/dist/research/workspace/investigation.d.ts +424 -0
  139. package/dist/research/workspace/investigation.js +716 -0
  140. package/dist/research/workspace/investigation.js.map +1 -0
  141. package/dist/research/workspace/native-process-supervisor.d.ts +1 -0
  142. package/dist/research/workspace/native-process-supervisor.js +97 -0
  143. package/dist/research/workspace/native-process-supervisor.js.map +1 -0
  144. package/dist/research/workspace/native-run.d.ts +79 -6
  145. package/dist/research/workspace/native-run.js +293 -51
  146. package/dist/research/workspace/native-run.js.map +1 -1
  147. package/dist/research/workspace/preflight.d.ts +3 -0
  148. package/dist/research/workspace/preflight.js +11 -6
  149. package/dist/research/workspace/preflight.js.map +1 -1
  150. package/dist/research/workspace/project-authority.js +2 -0
  151. package/dist/research/workspace/project-authority.js.map +1 -1
  152. package/dist/research/workspace/project-budget.d.ts +41 -0
  153. package/dist/research/workspace/project-budget.js +265 -0
  154. package/dist/research/workspace/project-budget.js.map +1 -0
  155. package/dist/research/workspace/project-mutations.d.ts +1 -1
  156. package/dist/research/workspace/project-mutations.js +27 -3
  157. package/dist/research/workspace/project-mutations.js.map +1 -1
  158. package/dist/research/workspace/projects.d.ts +66 -0
  159. package/dist/research/workspace/projects.js +181 -3
  160. package/dist/research/workspace/projects.js.map +1 -1
  161. package/dist/research/workspace/provider-budget.d.ts +3 -0
  162. package/dist/research/workspace/provider-budget.js +45 -0
  163. package/dist/research/workspace/provider-budget.js.map +1 -0
  164. package/dist/research/workspace/provider-state.d.ts +1 -0
  165. package/dist/research/workspace/provider-state.js +20 -0
  166. package/dist/research/workspace/provider-state.js.map +1 -0
  167. package/dist/research/workspace/publication-lineage.d.ts +34 -0
  168. package/dist/research/workspace/publication-lineage.js +165 -0
  169. package/dist/research/workspace/publication-lineage.js.map +1 -0
  170. package/dist/research/workspace/publication-workflow.d.ts +24 -0
  171. package/dist/research/workspace/publication-workflow.js +118 -14
  172. package/dist/research/workspace/publication-workflow.js.map +1 -1
  173. package/dist/research/workspace/review-executor.d.ts +6 -1
  174. package/dist/research/workspace/review-executor.js +17 -3
  175. package/dist/research/workspace/review-executor.js.map +1 -1
  176. package/dist/research/workspace/runtime.d.ts +12 -1
  177. package/dist/research/workspace/runtime.js +143 -19
  178. package/dist/research/workspace/runtime.js.map +1 -1
  179. package/dist/research/workspace/scientific-amendment.d.ts +103 -0
  180. package/dist/research/workspace/scientific-amendment.js +537 -0
  181. package/dist/research/workspace/scientific-amendment.js.map +1 -0
  182. package/dist/research/workspace/scientific-fulfillment-audit.d.ts +20 -2
  183. package/dist/research/workspace/scientific-fulfillment-audit.js +87 -7
  184. package/dist/research/workspace/scientific-fulfillment-audit.js.map +1 -1
  185. package/dist/research/workspace/scientific-fulfillment.d.ts +10 -1
  186. package/dist/research/workspace/scientific-fulfillment.js +20 -6
  187. package/dist/research/workspace/scientific-fulfillment.js.map +1 -1
  188. package/dist/research/workspace/scientific-review-execution.js +162 -22
  189. package/dist/research/workspace/scientific-review-execution.js.map +1 -1
  190. package/dist/research/workspace/scientific-review.d.ts +2 -1
  191. package/dist/research/workspace/scientific-review.js +33 -2
  192. package/dist/research/workspace/scientific-review.js.map +1 -1
  193. package/dist/research/workspace/setup-catalog.js +13 -13
  194. package/dist/research/workspace/setup-catalog.js.map +1 -1
  195. package/dist/research/workspace/setup-release.d.ts +22 -0
  196. package/dist/research/workspace/setup-release.js +426 -0
  197. package/dist/research/workspace/setup-release.js.map +1 -0
  198. package/dist/research/workspace/setup-runtime-integrity.d.ts +2 -0
  199. package/dist/research/workspace/setup-runtime-integrity.js +31 -0
  200. package/dist/research/workspace/setup-runtime-integrity.js.map +1 -0
  201. package/dist/research/workspace/setup-upgrade.d.ts +17 -0
  202. package/dist/research/workspace/setup-upgrade.js +784 -0
  203. package/dist/research/workspace/setup-upgrade.js.map +1 -0
  204. package/dist/research/workspace/setup.d.ts +31 -39
  205. package/dist/research/workspace/setup.js +228 -19
  206. package/dist/research/workspace/setup.js.map +1 -1
  207. package/dist/research/workspace/task-acceptance.d.ts +8 -1
  208. package/dist/research/workspace/task-acceptance.js +37 -5
  209. package/dist/research/workspace/task-acceptance.js.map +1 -1
  210. package/dist/research/workspace/task-audit.d.ts +5 -1
  211. package/dist/research/workspace/task-audit.js +33 -18
  212. package/dist/research/workspace/task-audit.js.map +1 -1
  213. package/dist/research/workspace/types.d.ts +44 -0
  214. package/dist/research/workspace/workspace.js +34 -4
  215. package/dist/research/workspace/workspace.js.map +1 -1
  216. package/package.json +5 -4
@@ -0,0 +1,426 @@
1
+ import { spawn } from "node:child_process";
2
+ import { tmpdir } from "node:os";
3
+ import { CliError } from "../../errors.js";
4
+ const REGISTRY_URL = "https://registry.npmjs.org";
5
+ // npm-registry-fetch prefers the scoped registry over opts.registry, so a
6
+ // HOME/.npmrc could silently retarget @tiangong-ai; both pins ride along as
7
+ // constant argv on every query.
8
+ const SCOPED_REGISTRY_PIN = "--@tiangong-ai:registry=https://registry.npmjs.org";
9
+ const STRICT_SSL_PIN = "--strict-ssl=true";
10
+ const RESEARCH_CLI_PACKAGE_NAME = "@tiangong-ai/cli";
11
+ const RELEASE_QUERY_TIMEOUT_MS = 30_000;
12
+ const RELEASE_KILL_GRACE_MS = 5_000;
13
+ const EXIT_STREAM_GRACE_MS = 1_000;
14
+ const MAX_RELEASE_QUERY_OUTPUT_BYTES = 1024 * 1024;
15
+ const EXACT_STABLE_SEMVER_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
16
+ const GIT_HEAD_PATTERN = /^[0-9a-f]{40}$/;
17
+ const SHA512_INTEGRITY_PATTERN = /^sha512-[A-Za-z0-9+/]+={0,2}$/;
18
+ const CANDIDATE_INVALID_CODE = "RESEARCH_SETUP_CANDIDATE_INVALID";
19
+ const QUERY_FAILED_REASON = "RESEARCH_SETUP_RELEASE_QUERY_FAILED";
20
+ const METADATA_INVALID_REASON = "RESEARCH_SETUP_RELEASE_METADATA_INVALID";
21
+ const INSTALLED_INCOMPARABLE_REASON = "RESEARCH_SETUP_RELEASE_INSTALLED_INCOMPARABLE";
22
+ // Only variables the pinned npm view query actually needs are forwarded;
23
+ // ambient npm_config_* and unrelated ambient variables never reach the child.
24
+ const CHILD_ENVIRONMENT_ALLOWLIST = [
25
+ "PATH",
26
+ "HOME",
27
+ "TMPDIR",
28
+ "HTTP_PROXY",
29
+ "HTTPS_PROXY",
30
+ "NO_PROXY",
31
+ "http_proxy",
32
+ "https_proxy",
33
+ "no_proxy",
34
+ "SSL_CERT_FILE",
35
+ "SSL_CERT_DIR",
36
+ "NODE_EXTRA_CA_CERTS",
37
+ "npm_config_cafile",
38
+ ];
39
+ function buildChildEnvironment(environment) {
40
+ const source = environment ?? process.env;
41
+ const child = {};
42
+ for (const key of CHILD_ENVIRONMENT_ALLOWLIST) {
43
+ const value = source[key];
44
+ if (typeof value === "string" && value.length > 0) {
45
+ child[key] = value;
46
+ }
47
+ }
48
+ return child;
49
+ }
50
+ function isObject(value) {
51
+ return typeof value === "object" && value !== null && !Array.isArray(value);
52
+ }
53
+ function parseStableSemver(value) {
54
+ const match = EXACT_STABLE_SEMVER_PATTERN.exec(value);
55
+ if (!match)
56
+ return null;
57
+ const parsed = [0, 0, 0];
58
+ for (let index = 1; index <= 3; index += 1) {
59
+ const part = match[index];
60
+ // Longer parts would round during Number conversion and silently corrupt
61
+ // the newer/same/older comparison.
62
+ if (part.length > 10)
63
+ return null;
64
+ const numeric = Number(part);
65
+ if (!Number.isSafeInteger(numeric))
66
+ return null;
67
+ parsed[index - 1] = numeric;
68
+ }
69
+ return parsed;
70
+ }
71
+ function compareStableSemver(candidate, installed) {
72
+ for (let index = 0; index < candidate.length; index += 1) {
73
+ if (candidate[index] > installed[index])
74
+ return "newer";
75
+ if (candidate[index] < installed[index])
76
+ return "older";
77
+ }
78
+ return "same";
79
+ }
80
+ function isVerifiedSha512Integrity(integrity) {
81
+ if (!SHA512_INTEGRITY_PATTERN.test(integrity))
82
+ return false;
83
+ return Buffer.from(integrity.slice("sha512-".length), "base64").length === 64;
84
+ }
85
+ function isPinnedRegistryTarball(tarball, version) {
86
+ if (typeof tarball !== "string")
87
+ return false;
88
+ let url;
89
+ try {
90
+ url = new URL(tarball);
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ if (url.protocol !== "https:")
96
+ return false;
97
+ if (url.username !== "" || url.password !== "")
98
+ return false;
99
+ if (url.host !== "registry.npmjs.org")
100
+ return false;
101
+ // Query/fragment components could smuggle signed URLs or tokens past the
102
+ // identity check, so only the bare pinned path is accepted.
103
+ if (url.search !== "" || url.hash !== "")
104
+ return false;
105
+ let pathname;
106
+ try {
107
+ pathname = decodeURIComponent(url.pathname);
108
+ }
109
+ catch {
110
+ return false;
111
+ }
112
+ return pathname === `/${RESEARCH_CLI_PACKAGE_NAME}/-/cli-${version}.tgz`;
113
+ }
114
+ function verifiedReleaseMetadata(stdout, requestedVersion) {
115
+ let value;
116
+ try {
117
+ value = JSON.parse(stdout);
118
+ }
119
+ catch {
120
+ return null;
121
+ }
122
+ if (!isObject(value))
123
+ return null;
124
+ // `npm view ... --json` emits the dist fields as flat dot-path keys; the
125
+ // nested-dist spelling never appears on the real interface.
126
+ const gitHead = value.gitHead;
127
+ const integrity = value["dist.integrity"];
128
+ const name = value.name;
129
+ const tarball = value["dist.tarball"];
130
+ const version = value.version;
131
+ if (name !== RESEARCH_CLI_PACKAGE_NAME)
132
+ return null;
133
+ if (typeof version !== "string" || version !== requestedVersion)
134
+ return null;
135
+ if (typeof gitHead !== "string" || !GIT_HEAD_PATTERN.test(gitHead))
136
+ return null;
137
+ if (typeof integrity !== "string" || !isVerifiedSha512Integrity(integrity))
138
+ return null;
139
+ if (!isPinnedRegistryTarball(tarball, requestedVersion))
140
+ return null;
141
+ return { version, integrity, tarball, gitHead };
142
+ }
143
+ const defaultSetupReleaseRunner = (input) => new Promise((resolvePromise) => {
144
+ // Windows npm is npm.cmd, which shell:false spawn cannot execute; the
145
+ // fixed cmd.exe branch forwards only constant argv plus the
146
+ // regex-validated exact version and accepts no additional parameters.
147
+ const windowsShell = process.platform === "win32";
148
+ const file = windowsShell ? "cmd.exe" : input.command;
149
+ const args = windowsShell ? ["/d", "/s", "/c", input.command, ...input.args] : input.args;
150
+ const stdoutChunks = [];
151
+ const stderrChunks = [];
152
+ let capturedBytes = 0;
153
+ let truncated = false;
154
+ let settled = false;
155
+ let terminating = false;
156
+ let timedOut = false;
157
+ let streamAbandoned = false;
158
+ const activeTimers = new Set();
159
+ // On POSIX the child leads its own process group, so a descendant that
160
+ // inherited the stdio pipes can be reached without ever signalling a pid
161
+ // we do not own.
162
+ const child = spawn(file, args, {
163
+ cwd: input.cwd,
164
+ env: input.environment,
165
+ detached: !windowsShell,
166
+ shell: false,
167
+ stdio: ["ignore", "pipe", "pipe"],
168
+ });
169
+ const later = (callback, delayMs) => {
170
+ const timer = setTimeout(() => {
171
+ activeTimers.delete(timer);
172
+ callback();
173
+ }, delayMs);
174
+ activeTimers.add(timer);
175
+ timer.unref();
176
+ };
177
+ // Both streams share one byte budget; chunks are concatenated once at
178
+ // settle instead of per-chunk, avoiding quadratic copies.
179
+ const capture = (chunks, chunk) => {
180
+ if (truncated)
181
+ return;
182
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
183
+ const remaining = MAX_RELEASE_QUERY_OUTPUT_BYTES - capturedBytes;
184
+ if (remaining <= 0) {
185
+ truncated = true;
186
+ return;
187
+ }
188
+ const take = bytes.length > remaining ? bytes.subarray(0, remaining) : bytes;
189
+ if (take.length > 0) {
190
+ chunks.push(take);
191
+ capturedBytes += take.length;
192
+ }
193
+ if (take.length < bytes.length)
194
+ truncated = true;
195
+ };
196
+ const killOwnedGroup = (signal) => {
197
+ if (windowsShell || typeof child.pid !== "number")
198
+ return;
199
+ try {
200
+ process.kill(-child.pid, signal);
201
+ }
202
+ catch {
203
+ // The process group is already gone.
204
+ }
205
+ };
206
+ // Windows has no process groups; the fixed taskkill targets only our own
207
+ // child pid's tree. One taskkill per query at most; the reference is kept
208
+ // so finish can guarantee the helper never outlives the bounded query.
209
+ let treeKill;
210
+ const killOwnedTreeOnWindows = () => {
211
+ if (!windowsShell || typeof child.pid !== "number" || treeKill)
212
+ return;
213
+ treeKill = spawn("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
214
+ cwd: input.cwd,
215
+ env: input.environment,
216
+ shell: false,
217
+ stdio: "ignore",
218
+ windowsHide: true,
219
+ });
220
+ const fallbackKillChild = () => {
221
+ if (settled)
222
+ return;
223
+ try {
224
+ child.kill("SIGKILL");
225
+ }
226
+ catch {
227
+ // The child already exited.
228
+ }
229
+ };
230
+ treeKill.on("error", fallbackKillChild);
231
+ treeKill.on("close", fallbackKillChild);
232
+ };
233
+ // One finite force/settle watchdog: whatever happens to the child events,
234
+ // the query settles at most one grace period after termination began.
235
+ const forceSettle = () => {
236
+ if (settled)
237
+ return;
238
+ killOwnedGroup("SIGKILL");
239
+ try {
240
+ child.kill("SIGKILL");
241
+ }
242
+ catch {
243
+ // The child already exited.
244
+ }
245
+ streamAbandoned = true;
246
+ finish(124);
247
+ };
248
+ const terminateChild = () => {
249
+ if (terminating || settled)
250
+ return;
251
+ terminating = true;
252
+ if (windowsShell) {
253
+ // Start the tree kill while the root pid still exists: on real
254
+ // Windows a preceding root kill terminates cmd.exe immediately and
255
+ // taskkill /T would lose the still-running npm descendants. The root
256
+ // kill only happens as the bounded fallback in the watchdog and the
257
+ // taskkill completion/error handlers.
258
+ killOwnedTreeOnWindows();
259
+ }
260
+ else {
261
+ try {
262
+ child.kill("SIGTERM");
263
+ }
264
+ catch {
265
+ // The child already exited.
266
+ }
267
+ killOwnedGroup("SIGTERM");
268
+ later(() => {
269
+ killOwnedGroup("SIGKILL");
270
+ if (!settled) {
271
+ try {
272
+ child.kill("SIGKILL");
273
+ }
274
+ catch {
275
+ // The child already exited.
276
+ }
277
+ }
278
+ }, RELEASE_KILL_GRACE_MS);
279
+ }
280
+ later(forceSettle, RELEASE_KILL_GRACE_MS + EXIT_STREAM_GRACE_MS);
281
+ };
282
+ child.stdout?.on("data", (chunk) => {
283
+ capture(stdoutChunks, chunk);
284
+ if (truncated)
285
+ terminateChild();
286
+ });
287
+ child.stderr?.on("data", (chunk) => {
288
+ capture(stderrChunks, chunk);
289
+ if (truncated)
290
+ terminateChild();
291
+ });
292
+ later(() => {
293
+ timedOut = true;
294
+ terminateChild();
295
+ }, input.timeoutMs);
296
+ const finish = (exitCode) => {
297
+ if (settled)
298
+ return;
299
+ settled = true;
300
+ for (const timer of activeTimers)
301
+ clearTimeout(timer);
302
+ activeTimers.clear();
303
+ if (windowsShell) {
304
+ // Only a terminating/abandoned query can still own live tree members;
305
+ // a clean close means every pipe-holding process is already gone.
306
+ if (terminating || streamAbandoned) {
307
+ try {
308
+ child.kill("SIGKILL");
309
+ }
310
+ catch {
311
+ // The child already exited.
312
+ }
313
+ }
314
+ // The helper was spawned by this query and must never outlive it.
315
+ if (treeKill &&
316
+ typeof treeKill.pid === "number" &&
317
+ treeKill.pid > 0 &&
318
+ treeKill.exitCode === null &&
319
+ !treeKill.killed) {
320
+ try {
321
+ treeKill.kill("SIGKILL");
322
+ }
323
+ catch {
324
+ // The helper already exited.
325
+ }
326
+ }
327
+ }
328
+ else {
329
+ // Harmless ESRCH on a clean close; on an abandoned stream this is
330
+ // what reaps a descendant that inherited the pipes.
331
+ killOwnedGroup("SIGKILL");
332
+ }
333
+ child.stdout?.destroy();
334
+ child.stderr?.destroy();
335
+ resolvePromise({
336
+ exitCode: timedOut || truncated || streamAbandoned ? 124 : exitCode,
337
+ stdout: Buffer.concat(stdoutChunks).toString("utf8"),
338
+ stderr: Buffer.concat(stderrChunks).toString("utf8"),
339
+ });
340
+ };
341
+ child.on("error", (error) => {
342
+ capture(stderrChunks, error.message);
343
+ finish(127);
344
+ });
345
+ child.on("close", (code) => finish(code ?? 1));
346
+ // Node emits "close" only once every stdio stream has ended. A descendant
347
+ // that inherited the pipes can hold them open long after the root exited,
348
+ // so the root's exit starts one bounded grace; if close has not arrived by
349
+ // then the buffered output is abandoned as untrusted and the query settles.
350
+ child.on("exit", () => {
351
+ later(() => {
352
+ if (settled)
353
+ return;
354
+ streamAbandoned = true;
355
+ finish(124);
356
+ }, EXIT_STREAM_GRACE_MS);
357
+ });
358
+ });
359
+ export async function inspectExactResearchCliRelease(candidateVersion, options) {
360
+ const candidate = parseStableSemver(candidateVersion);
361
+ if (!candidate) {
362
+ throw new CliError("The requested exact CLI candidate version is not a supported bounded stable semver release identifier.", { code: CANDIDATE_INVALID_CODE, exitCode: 2 });
363
+ }
364
+ const base = {
365
+ packageName: RESEARCH_CLI_PACKAGE_NAME,
366
+ requestedVersion: candidateVersion,
367
+ installedVersion: options.installedVersion,
368
+ registry: REGISTRY_URL,
369
+ };
370
+ const installed = parseStableSemver(options.installedVersion);
371
+ if (!installed) {
372
+ return {
373
+ ...base,
374
+ status: "unavailable",
375
+ metadata: null,
376
+ reason: INSTALLED_INCOMPARABLE_REASON,
377
+ };
378
+ }
379
+ const runner = options.runner ?? defaultSetupReleaseRunner;
380
+ let queryResult;
381
+ try {
382
+ queryResult = await runner({
383
+ command: "npm",
384
+ args: [
385
+ "view",
386
+ `${RESEARCH_CLI_PACKAGE_NAME}@${candidateVersion}`,
387
+ "name",
388
+ "version",
389
+ "dist.integrity",
390
+ "dist.tarball",
391
+ "gitHead",
392
+ "--json",
393
+ "--registry",
394
+ REGISTRY_URL,
395
+ SCOPED_REGISTRY_PIN,
396
+ STRICT_SSL_PIN,
397
+ ],
398
+ cwd: tmpdir(),
399
+ environment: buildChildEnvironment(options.environment),
400
+ timeoutMs: RELEASE_QUERY_TIMEOUT_MS,
401
+ });
402
+ }
403
+ catch {
404
+ return { ...base, status: "unavailable", metadata: null, reason: QUERY_FAILED_REASON };
405
+ }
406
+ if (queryResult.exitCode !== 0) {
407
+ return { ...base, status: "unavailable", metadata: null, reason: QUERY_FAILED_REASON };
408
+ }
409
+ // Runner-provided output is subject to the same combined budget as process
410
+ // output; oversized results are untrusted and never parsed or echoed.
411
+ if (Buffer.byteLength(queryResult.stdout, "utf8") + Buffer.byteLength(queryResult.stderr, "utf8") >
412
+ MAX_RELEASE_QUERY_OUTPUT_BYTES) {
413
+ return { ...base, status: "unavailable", metadata: null, reason: QUERY_FAILED_REASON };
414
+ }
415
+ const metadata = verifiedReleaseMetadata(queryResult.stdout, candidateVersion);
416
+ if (!metadata) {
417
+ return { ...base, status: "unavailable", metadata: null, reason: METADATA_INVALID_REASON };
418
+ }
419
+ return {
420
+ ...base,
421
+ status: compareStableSemver(candidate, installed),
422
+ metadata,
423
+ reason: null,
424
+ };
425
+ }
426
+ //# sourceMappingURL=setup-release.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-release.js","sourceRoot":"","sources":["../../../src/research/workspace/setup-release.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function researchSetupRuntimeSha256(): Promise<string>;
2
+ export declare function assertResearchSetupRuntimeIntegrity(expected: string): Promise<void>;
@@ -0,0 +1,31 @@
1
+ import { join } from "node:path";
2
+ import { CliError } from "../../errors.js";
3
+ import { packageRoot } from "./constants.js";
4
+ import { canonicalJson, hashRegularTree, sha256File, sha256Text } from "./storage.js";
5
+ // Upgrade-only binding of the CLI's declared package identity and executable
6
+ // distribution. Excludes node_modules, source checkout, caches, and owner data.
7
+ // This is content integrity, not a publisher signature or dependency attestation.
8
+ export async function researchSetupRuntimeSha256() {
9
+ const root = packageRoot();
10
+ const [manifest, bin, dist] = await Promise.all([
11
+ sha256File(join(root, "package.json")),
12
+ hashRegularTree(join(root, "bin")),
13
+ hashRegularTree(join(root, "dist")),
14
+ ]);
15
+ return sha256Text(canonicalJson({ algorithm: "cli-package-bin-dist-sha256-v1", manifest, bin, dist }));
16
+ }
17
+ export async function assertResearchSetupRuntimeIntegrity(expected) {
18
+ const observed = await researchSetupRuntimeSha256();
19
+ if (observed !== expected) {
20
+ throw new CliError("The running CLI bytes differ from the reviewed upgrade candidate.", {
21
+ code: "RESEARCH_SETUP_CLI_INTEGRITY_MISMATCH",
22
+ exitCode: 3,
23
+ details: {
24
+ expectedSha256: expected,
25
+ observedSha256: observed,
26
+ minimumAction: "Use the exact reviewed CLI distribution, or generate and review a fresh candidate with the selected distribution. Do not rewrite the existing candidate.",
27
+ },
28
+ });
29
+ }
30
+ }
31
+ //# sourceMappingURL=setup-runtime-integrity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-runtime-integrity.js","sourceRoot":"","sources":["../../../src/research/workspace/setup-runtime-integrity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtF,6EAA6E;AAC7E,gFAAgF;AAChF,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAC9C,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC9C,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QACtC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;KACpC,CAAC,CAAC;IACH,OAAO,UAAU,CACf,aAAa,CAAC,EAAE,SAAS,EAAE,gCAAgC,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CACpF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,QAAgB;IACxE,MAAM,QAAQ,GAAG,MAAM,0BAA0B,EAAE,CAAC;IACpD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,QAAQ,CAAC,mEAAmE,EAAE;YACtF,IAAI,EAAE,uCAAuC;YAC7C,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE;gBACP,cAAc,EAAE,QAAQ;gBACxB,cAAc,EAAE,QAAQ;gBACxB,aAAa,EACX,0JAA0J;aAC7J;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type ApplyResearchSetupOptions, type ApplyResearchSetupResult, type ResearchSetupPlan } from "./setup.js";
2
+ export declare function applyManagedSetupUpgrade(plan: ResearchSetupPlan, options: ApplyResearchSetupOptions): Promise<ApplyResearchSetupResult>;
3
+ export declare function rollbackResearchSetupUpgrade(candidatePath: string, workspace: string, options?: {
4
+ checkpoint?: (point: string) => Promise<void>;
5
+ }): Promise<{
6
+ schemaVersion: number;
7
+ status: string;
8
+ replayed: boolean;
9
+ planSha256: string;
10
+ parentPlanSha256: string;
11
+ } | {
12
+ replayed?: never;
13
+ schemaVersion: number;
14
+ status: string;
15
+ planSha256: string;
16
+ parentPlanSha256: string;
17
+ }>;