@userreason/wizard 0.3.2 → 0.3.3

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.
package/README.md CHANGED
@@ -197,10 +197,11 @@ creating a session or local effects.
197
197
  Malformed protocol data and already-started setups never fall back silently.
198
198
  Server rollout flags remain off by default; publication is a separate release.
199
199
 
200
- The browser owns workspace/site selection, optional choices, local-plan approval,
200
+ The browser owns workspace/site selection, optional choices, installation options,
201
201
  finish and cancellation. Source analysis, suggested drafts and the Agent test
202
202
  remain implemented but are hidden and skipped while their rollout flags are off. The local runner executes only approved typed effects
203
- using the separate owner-only setup capability. It does not read or replace
203
+ using the separate owner-only setup capability. Press **Continue** on the setup
204
+ options to begin installation; there is no separate local-change review screen. It does not read or replace
204
205
  normal CLI credentials. Stopping the local process leaves the setup resumable;
205
206
  cancelling in the browser does not undo completed edits or delete created drafts.
206
207
  Terminal results list verified, failed and manual outcomes separately.
@@ -221,7 +222,7 @@ skill never grants ongoing CLI access. Authorize continuing access separately
221
222
  with `userreason login --open` when wanted. Standalone CLI survey tools remain
222
223
  available outside onboarding.
223
224
 
224
- The production profile for wizard 0.3.2 selects `@userreason/js@0.5.3` and
225
+ The production profile for wizard 0.3.3 selects `@userreason/js@0.5.3` and
225
226
  `@userreason/cli@0.2.1`. New installs use those exact versions; an installed
226
227
  stable patch in the same release line is reused. Earlier SDK 0.4 and CLI 0.1
227
228
  releases are upgraded when installation is selected. Browser setup is the default and requires a server advertising the capability.
package/dist/bin.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { createRequire as createWizardRequire } from 'node:module'; import { fileURLToPath as wizardFileURLToPath } from 'node:url'; import { dirname as wizardDirname } from 'node:path'; const require = createWizardRequire(import.meta.url); const __filename = wizardFileURLToPath(import.meta.url); const __dirname = wizardDirname(__filename);
3
3
  import {
4
4
  runBrowserWizard
5
- } from "./chunk-CSZW2ULJ.js";
5
+ } from "./chunk-FWEZ2ZWN.js";
6
6
  import {
7
7
  clearInstallation,
8
8
  resolveInstallation,
@@ -26,7 +26,7 @@ import {
26
26
  beginFirstSurveyPreparation,
27
27
  offerFirstSurvey
28
28
  } from "./chunk-ZHJV247H.js";
29
- import "./chunk-Q5U5UOQN.js";
29
+ import "./chunk-5EAHX5BX.js";
30
30
  import "./chunk-4INLEQE2.js";
31
31
  import {
32
32
  offerAgentSkill,
@@ -41,8 +41,9 @@ import {
41
41
  import { basename } from "node:path";
42
42
 
43
43
  // src/setup-plan.ts
44
- import { randomUUID } from "node:crypto";
45
- import { lstat, readdir, readFile } from "node:fs/promises";
44
+ import { createHash, randomUUID } from "node:crypto";
45
+ import { constants } from "node:fs";
46
+ import { lstat, open, readdir } from "node:fs/promises";
46
47
  import { join, relative } from "node:path";
47
48
  var relativeName = (project, path) => relative(project.directory, path).replaceAll("\\", "/");
48
49
  var metadata = (files) => files.map((file2) => ({ path: file2.path, before_hash: file2.before === null ? null : setupHash(file2.before), after_hash: setupHash(file2.after) }));
@@ -170,10 +171,27 @@ async function prepare(project, session, profile, config, operations = [], manua
170
171
  }
171
172
  return { wire: { project_fingerprint: session.project_fingerprint, choices_digest: setupDigest(session.choices), effects: operations.map((item) => item.effect), ...manual.length ? { manual_steps: manual } : {} }, operations };
172
173
  }
173
- async function snapshot(project) {
174
+ async function snapshotFile(path, expected, signal) {
175
+ const handle = await open(path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
176
+ try {
177
+ const before = await handle.stat();
178
+ if (!before.isFile() || before.dev !== expected.dev || before.ino !== expected.ino)
179
+ throw new SetupError("setup_files_changed", "A project file changed while checking package installation.");
180
+ const hash = createHash("sha256");
181
+ for await (const chunk of handle.createReadStream({ autoClose: false, signal })) hash.update(chunk);
182
+ const after = await handle.stat();
183
+ if (before.size !== after.size || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs)
184
+ throw new SetupError("setup_files_changed", "A project file changed while checking package installation.");
185
+ return hash.digest("hex");
186
+ } finally {
187
+ await handle.close();
188
+ }
189
+ }
190
+ async function snapshot(project, signal) {
174
191
  const result = {}, stack = [""];
175
- let entries = 0, bytes = 0;
192
+ let entries = 0;
176
193
  while (stack.length) {
194
+ signal.throwIfAborted();
177
195
  const folder = stack.pop();
178
196
  for (const entry of await readdir(join(project.directory, folder), { withFileTypes: true })) {
179
197
  if (++entries > 2e4) throw new SetupError("setup_files_changed", "Project scanning exceeds the bounded review budget.");
@@ -185,11 +203,7 @@ async function snapshot(project) {
185
203
  continue;
186
204
  }
187
205
  if (info.isDirectory()) stack.push(path);
188
- else if (info.isFile()) {
189
- bytes += info.size;
190
- if (info.size > 2e7 || bytes > 64e6) throw new SetupError("setup_files_changed", "Project scanning exceeds the bounded byte budget.");
191
- result[path] = setupHash(await readFile(join(project.directory, path)));
192
- }
206
+ else if (info.isFile()) result[path] = await snapshotFile(join(project.directory, path), info, signal);
193
207
  }
194
208
  }
195
209
  return result;
@@ -224,7 +238,7 @@ function setupRuntime(project, apiOrigin, selectedProfile = packageProfile()) {
224
238
  }
225
239
  if (operation.effect.package_manager !== current.packageManager) throw new SetupError("setup_command_mismatch", "The package manager differs from the reviewed command.");
226
240
  for (const item of operation.effect.packages) if (item.version !== (item.name === "@userreason/js" ? profile.sdkVersion : profile.cliVersion)) throw new SetupError("setup_package_version", "The approved package version differs from this local package profile.");
227
- const before = await snapshot(project);
241
+ const before = await snapshot(project, signal);
228
242
  for (const file2 of operation.files.filter((file3) => file3.path !== "package.json")) await writeSetupFile(project.directory, file2);
229
243
  for (const item of operation.effect.packages) {
230
244
  signal.throwIfAborted();
@@ -234,7 +248,7 @@ function setupRuntime(project, apiOrigin, selectedProfile = packageProfile()) {
234
248
  const actual = await readSetupFile(project.directory, manifest.path);
235
249
  if (!actual || setupDigest(JSON.parse(actual)) !== setupDigest(JSON.parse(manifest.after))) throw new Error("The package manager made unexpected manifest changes");
236
250
  await writeSetupFile(project.directory, { ...manifest, before: actual });
237
- const after = await snapshot(project), allowed = /* @__PURE__ */ new Set([...operation.files.map((file2) => file2.path), ...(operation.effect.managed_outputs ?? []).map((file2) => file2.path)]);
251
+ const after = await snapshot(project, signal), allowed = /* @__PURE__ */ new Set([...operation.files.map((file2) => file2.path), ...(operation.effect.managed_outputs ?? []).map((file2) => file2.path)]);
238
252
  for (const path of /* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])) if (!allowed.has(path) && before[path] !== after[path]) throw new Error("The package manager changed an unreviewed project file");
239
253
  return "verified";
240
254
  },
@@ -3,7 +3,7 @@ import {
3
3
  connectSetup,
4
4
  resumeSetup,
5
5
  runSetup
6
- } from "./chunk-Q5U5UOQN.js";
6
+ } from "./chunk-5EAHX5BX.js";
7
7
  import {
8
8
  clean,
9
9
  openBrowser
@@ -46,14 +46,14 @@ async function runBrowserWizard(input) {
46
46
  let connected;
47
47
  try {
48
48
  connected = input.resumeId ? await resumeSetup(apiOrigin, input.resumeId, project, { signal, measurementDisabled: input.measurementDisabled }) : await connectSetup(apiOrigin, project, async (url, code) => {
49
- terminal.block("Continue in your browser", [url, `Verification code: ${code}`, input.development ? "Choose your workspace, site and installation options in the browser." : "Review the project, local changes and source permissions there."]);
49
+ terminal.block("Continue in your browser", [url, `Verification code: ${code}`, "Choose your workspace, site and installation options in the browser."]);
50
50
  if (!input.noOpen && !await openBrowser(url)) terminal.info("Open the link above to continue.");
51
51
  }, {
52
52
  signal,
53
53
  browserOrigin: input.browserOrigin,
54
- automaticSetup: input.development,
54
+ automaticSetup: true,
55
55
  measurementDisabled: input.measurementDisabled,
56
- ...input.development ? { launcher: { wizard_version: input.version, api_origin: apiOrigin, ...input.profile.kind === "local-development" ? { registry: input.profile.registry } : {} } } : {}
56
+ launcher: { wizard_version: input.version, api_origin: apiOrigin, ...input.profile.kind === "local-development" ? { registry: input.profile.registry } : {} }
57
57
  });
58
58
  } catch (error) {
59
59
  if (!input.resumeId && error instanceof BrowserSetupUnavailable) return false;
@@ -5,8 +5,8 @@ import {
5
5
  setupResumeCommand,
6
6
  setupSampleCommand,
7
7
  setupSummary
8
- } from "./chunk-CSZW2ULJ.js";
9
- import "./chunk-Q5U5UOQN.js";
8
+ } from "./chunk-FWEZ2ZWN.js";
9
+ import "./chunk-5EAHX5BX.js";
10
10
  import "./chunk-4INLEQE2.js";
11
11
  import "./chunk-SB3AYQWG.js";
12
12
  import "./chunk-LEJFE4U5.js";
package/dist/setup.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  resumeSetup,
7
7
  runSetup,
8
8
  setupRuntime
9
- } from "./chunk-Q5U5UOQN.js";
9
+ } from "./chunk-5EAHX5BX.js";
10
10
  import "./chunk-4INLEQE2.js";
11
11
  import "./chunk-SB3AYQWG.js";
12
12
  import "./chunk-LEJFE4U5.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@userreason/wizard",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Authenticated UserReason SDK installation wizard",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",