@getmonoceros/workbench 1.20.0 → 1.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -3259,8 +3259,8 @@ function removeRepoFromDoc(doc, urlOrPath) {
3259
3259
  if (!isMap2(item)) return false;
3260
3260
  const url = item.get("url");
3261
3261
  if (url === urlOrPath) return true;
3262
- const path24 = item.get("path");
3263
- const effectivePath = typeof path24 === "string" ? path24 : typeof url === "string" ? deriveRepoName(url) : void 0;
3262
+ const path25 = item.get("path");
3263
+ const effectivePath = typeof path25 === "string" ? path25 : typeof url === "string" ? deriveRepoName(url) : void 0;
3264
3264
  return effectivePath === urlOrPath;
3265
3265
  });
3266
3266
  if (idx < 0) return false;
@@ -3372,7 +3372,7 @@ async function runAddRepo(input) {
3372
3372
  "Missing repo URL. Usage: monoceros add-repo <containername> <url>."
3373
3373
  );
3374
3374
  }
3375
- const path24 = (input.path ?? deriveRepoName(url)).trim();
3375
+ const path25 = (input.path ?? deriveRepoName(url)).trim();
3376
3376
  const hasName = typeof input.gitName === "string" && input.gitName.trim().length > 0;
3377
3377
  const hasEmail = typeof input.gitEmail === "string" && input.gitEmail.trim().length > 0;
3378
3378
  if (hasName !== hasEmail) {
@@ -3409,7 +3409,7 @@ async function runAddRepo(input) {
3409
3409
  const providerToWrite = !canonical && explicitProvider ? explicitProvider : void 0;
3410
3410
  const entry2 = {
3411
3411
  url,
3412
- path: path24,
3412
+ path: path25,
3413
3413
  ...hasName && hasEmail ? {
3414
3414
  gitUser: {
3415
3415
  name: input.gitName.trim(),
@@ -4913,8 +4913,13 @@ function generateAgentsMd(input) {
4913
4913
  lines.push("## Conventions and pitfalls");
4914
4914
  lines.push("");
4915
4915
  lines.push(
4916
- `- Workspace path: \`/workspaces/${input.containerName}/projects/<repo>/\`.`,
4917
- " Cloned repos are git repositories \u2014 commit normally.",
4916
+ `- **Build everything under \`/workspaces/${input.containerName}/projects/\`.**`,
4917
+ " That is the project workspace \u2014 create new apps and scaffolding there",
4918
+ " (e.g. `projects/<app>/`), and `cd` into it before generating files. Do",
4919
+ ` **not** put project files at the workspace root \`/workspaces/${input.containerName}\`:`,
4920
+ " it holds Monoceros-managed directories (`.devcontainer/`, `home/`,",
4921
+ " `data/`, `logs/`), not your code. Cloned repos already live at",
4922
+ " `projects/<repo>/` and are git repositories \u2014 commit normally.",
4918
4923
  "- You run as the `node` user. `sudo` is available but its effects do",
4919
4924
  " not persist across rebuilds.",
4920
4925
  "- A bare `EXPOSE` directive has no effect on host reachability. Ports",
@@ -6407,7 +6412,7 @@ var CLI_VERSION;
6407
6412
  var init_version = __esm({
6408
6413
  "src/version.ts"() {
6409
6414
  "use strict";
6410
- CLI_VERSION = true ? "1.20.0" : "dev";
6415
+ CLI_VERSION = true ? "1.20.2" : "dev";
6411
6416
  }
6412
6417
  });
6413
6418
 
@@ -8802,9 +8807,52 @@ var init_browser_bridge = __esm({
8802
8807
  }
8803
8808
  });
8804
8809
 
8805
- // src/devcontainer/shell.ts
8806
- import { existsSync as existsSync14 } from "fs";
8810
+ // src/devcontainer/claude-trust.ts
8811
+ import { existsSync as existsSync14, promises as fsp3 } from "fs";
8807
8812
  import path22 from "path";
8813
+ function resolveContainerCwd(name, cwd) {
8814
+ const workspace = `/workspaces/${name}`;
8815
+ if (!cwd) return workspace;
8816
+ return path22.posix.isAbsolute(cwd) ? cwd : path22.posix.join(workspace, cwd);
8817
+ }
8818
+ async function preApproveClaudeProject(opts) {
8819
+ const file = path22.join(opts.root, "home", ".claude.json");
8820
+ if (!existsSync14(file)) return;
8821
+ try {
8822
+ const raw = await fsp3.readFile(file, "utf8");
8823
+ const config = raw.trim() ? JSON.parse(raw) : {};
8824
+ if (typeof config !== "object" || config === null) return;
8825
+ const dir = resolveContainerCwd(opts.name, opts.cwd);
8826
+ if (typeof config.projects !== "object" || config.projects === null) {
8827
+ config.projects = {};
8828
+ }
8829
+ if (typeof config.projects[dir] !== "object" || config.projects[dir] === null) {
8830
+ config.projects[dir] = {};
8831
+ }
8832
+ const entry2 = config.projects[dir];
8833
+ if (entry2.hasTrustDialogAccepted === true && entry2.hasClaudeMdExternalIncludesApproved === true && entry2.hasClaudeMdExternalIncludesWarningShown === true) {
8834
+ return;
8835
+ }
8836
+ entry2.hasTrustDialogAccepted = true;
8837
+ entry2.hasClaudeMdExternalIncludesApproved = true;
8838
+ entry2.hasClaudeMdExternalIncludesWarningShown = true;
8839
+ if (typeof entry2.projectOnboardingSeenCount !== "number") {
8840
+ entry2.projectOnboardingSeenCount = 1;
8841
+ }
8842
+ await fsp3.writeFile(file, `${JSON.stringify(config, null, 2)}
8843
+ `);
8844
+ } catch {
8845
+ }
8846
+ }
8847
+ var init_claude_trust = __esm({
8848
+ "src/devcontainer/claude-trust.ts"() {
8849
+ "use strict";
8850
+ }
8851
+ });
8852
+
8853
+ // src/devcontainer/shell.ts
8854
+ import { existsSync as existsSync15 } from "fs";
8855
+ import path23 from "path";
8808
8856
  async function runShell(opts) {
8809
8857
  assertContainerExists(opts.root);
8810
8858
  const spawnFn = opts.spawn ?? spawnDevcontainer;
@@ -8827,7 +8875,7 @@ async function runShell(opts) {
8827
8875
  );
8828
8876
  }
8829
8877
  function assertContainerExists(root) {
8830
- if (!existsSync14(path22.join(root, ".devcontainer"))) {
8878
+ if (!existsSync15(path23.join(root, ".devcontainer"))) {
8831
8879
  throw new Error(
8832
8880
  `No .devcontainer/ at ${root}. Run \`monoceros apply <name>\` first.`
8833
8881
  );
@@ -8873,6 +8921,13 @@ async function runInContainer(opts) {
8873
8921
  { quiet: true }
8874
8922
  );
8875
8923
  if (upCode !== 0) return upCode;
8924
+ if (opts.name) {
8925
+ await preApproveClaudeProject({
8926
+ root: opts.root,
8927
+ name: opts.name,
8928
+ ...opts.cwd ? { cwd: opts.cwd } : {}
8929
+ });
8930
+ }
8876
8931
  const bridge = opts.name && process.stdout.isTTY ? await startBrowserBridge({
8877
8932
  name: opts.name,
8878
8933
  root: opts.root,
@@ -8902,6 +8957,7 @@ var init_run = __esm({
8902
8957
  "src/devcontainer/run.ts"() {
8903
8958
  "use strict";
8904
8959
  init_browser_bridge();
8960
+ init_claude_trust();
8905
8961
  init_cli();
8906
8962
  init_shell();
8907
8963
  }
@@ -9137,11 +9193,11 @@ var init_stop = __esm({
9137
9193
  });
9138
9194
 
9139
9195
  // src/tunnel/resolve.ts
9140
- import { existsSync as existsSync15 } from "fs";
9141
- import path23 from "path";
9196
+ import { existsSync as existsSync16 } from "fs";
9197
+ import path24 from "path";
9142
9198
  async function resolveTunnelTarget(opts) {
9143
9199
  const ymlPath = containerConfigPath(opts.name, opts.monocerosHome);
9144
- if (!existsSync15(ymlPath)) {
9200
+ if (!existsSync16(ymlPath)) {
9145
9201
  throw new Error(
9146
9202
  `No yml profile for '${opts.name}' at ${ymlPath}. Run \`monoceros init ${opts.name}\` first.`
9147
9203
  );
@@ -9149,13 +9205,13 @@ async function resolveTunnelTarget(opts) {
9149
9205
  const parsed = await readConfig(ymlPath);
9150
9206
  const config = parsed.config;
9151
9207
  const containerRoot = containerDir(opts.name, opts.monocerosHome);
9152
- if (!existsSync15(containerRoot)) {
9208
+ if (!existsSync16(containerRoot)) {
9153
9209
  throw new Error(
9154
9210
  `Container '${opts.name}' is not materialised at ${containerRoot}. Run \`monoceros apply ${opts.name}\` first.`
9155
9211
  );
9156
9212
  }
9157
- const composePath = path23.join(containerRoot, ".devcontainer", "compose.yaml");
9158
- const isCompose = existsSync15(composePath);
9213
+ const composePath = path24.join(containerRoot, ".devcontainer", "compose.yaml");
9214
+ const isCompose = existsSync16(composePath);
9159
9215
  const parsedTarget = parseTargetArg(opts.target, config);
9160
9216
  const docker = opts.docker ?? defaultDockerExec;
9161
9217
  if (isCompose) {
@@ -9574,7 +9630,7 @@ var init_tunnel = __esm({
9574
9630
  });
9575
9631
 
9576
9632
  // src/upgrade/index.ts
9577
- import { existsSync as existsSync16, promises as fs17 } from "fs";
9633
+ import { existsSync as existsSync17, promises as fs17 } from "fs";
9578
9634
  import { consola as consola34 } from "consola";
9579
9635
  async function fetchRuntimeVersions() {
9580
9636
  const tokenUrl = `https://ghcr.io/token?service=ghcr.io&scope=repository:${RUNTIME_REPO}:pull`;
@@ -9633,7 +9689,7 @@ async function runUpgrade(opts) {
9633
9689
  );
9634
9690
  }
9635
9691
  const ymlPath = containerConfigPath(opts.name, home);
9636
- if (!existsSync16(ymlPath)) {
9692
+ if (!existsSync17(ymlPath)) {
9637
9693
  throw new Error(
9638
9694
  `No such config: ${ymlPath}. Run \`monoceros init <template> ${opts.name}\` first.`
9639
9695
  );
@@ -10063,25 +10119,25 @@ function detectHelpRequest(argv, main2) {
10063
10119
  const separatorIdx = argv.indexOf("--");
10064
10120
  if (helpIdx === -1) return null;
10065
10121
  if (separatorIdx !== -1 && separatorIdx < helpIdx) return null;
10066
- const path24 = [];
10122
+ const path25 = [];
10067
10123
  const tokens = argv.slice(
10068
10124
  0,
10069
10125
  separatorIdx === -1 ? argv.length : separatorIdx
10070
10126
  );
10071
10127
  let cursor = main2;
10072
10128
  const mainName = (main2.meta ?? {}).name ?? "monoceros";
10073
- path24.push(mainName);
10129
+ path25.push(mainName);
10074
10130
  for (const tok of tokens) {
10075
10131
  if (tok.startsWith("-")) continue;
10076
10132
  const subs = cursor.subCommands ?? {};
10077
10133
  if (tok in subs) {
10078
10134
  cursor = subs[tok];
10079
- path24.push(tok);
10135
+ path25.push(tok);
10080
10136
  continue;
10081
10137
  }
10082
10138
  break;
10083
10139
  }
10084
- return { path: path24, cmd: cursor };
10140
+ return { path: path25, cmd: cursor };
10085
10141
  }
10086
10142
  async function maybeRenderHelp(argv, main2) {
10087
10143
  const hit = detectHelpRequest(argv, main2);