@mesh-tech/mesh-cli 0.43.2 → 0.44.0

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.
@@ -53,7 +53,14 @@ This section is what makes the skill worth loading.
53
53
  ```bash
54
54
  cd __APP_PATH__
55
55
  pnpm install
56
- mesh dev # run locally
56
+
57
+ # Local-only platform (mesh.json platform "local", or none set)
58
+ mesh start # the local Mesh platform (once; Docker)
59
+ mesh dev # run the app against it
57
60
  mesh hub dev # watch this session's runs in a local Hub
61
+
62
+ # Deployed platform
63
+ mesh stack init # personal dev stack (deploy: false)
58
64
  mesh deploy up # deploy via the stack's deployer role
65
+ mesh dev # run locally against the platform
59
66
  ```
@@ -1051,7 +1051,7 @@ async function cliReferenceStaleness(repoRoot) {
1051
1051
  { createProgram },
1052
1052
  { extractCliReference, renderCliReferenceMarkdown }
1053
1053
  ] = await Promise.all([
1054
- import("./mesh.program-GEKNV2LY.js"),
1054
+ import("./mesh.program-NOBVA3JS.js"),
1055
1055
  import("./mesh.cli-reference-H3TOPIET.js")
1056
1056
  ]);
1057
1057
  const outPath = path3.join(repoRoot, "docs/portal/generated/cli-reference.md");
@@ -12,7 +12,7 @@ import {
12
12
  cliReferenceStaleness,
13
13
  resolveCliRuntime,
14
14
  runPortalCommand
15
- } from "./mesh.chunk-OOWKJR4H.js";
15
+ } from "./mesh.chunk-OQA2UBOD.js";
16
16
  import {
17
17
  registerAppCommands,
18
18
  registerCreateAppCommand
@@ -1542,7 +1542,7 @@ var DOCS_PREVIEW_PORT = "4410";
1542
1542
  var CLI_REFERENCE_PATH = "docs/portal/generated/cli-reference.md";
1543
1543
  async function renderCliReference() {
1544
1544
  const [{ createProgram: createProgram2 }, { extractCliReference, renderCliReferenceMarkdown }] = await Promise.all([
1545
- import("./mesh.program-GEKNV2LY.js"),
1545
+ import("./mesh.program-NOBVA3JS.js"),
1546
1546
  import("./mesh.cli-reference-H3TOPIET.js")
1547
1547
  ]);
1548
1548
  return renderCliReferenceMarkdown(extractCliReference(createProgram2()));
@@ -1614,7 +1614,7 @@ function registerDocsCommand(program) {
1614
1614
  "Serve the Mesh docs locally \u2014 detached in a tmux session by default; the working tree in a mesh-platform checkout, or the published @mesh-tech/docs artifact (role-gated registry) anywhere else"
1615
1615
  ).option("-v, --version <version>", "docs version to serve (== the @mesh-tech/* baseline it describes); default: latest", void 0).option("-p, --port <port>", "port to serve on (0 picks a free one)", "4400").option("--dev", "in a checkout: run the Zudoku dev server (HMR) in the foreground, for authoring", false).option("--foreground", "serve in the foreground (the agent/CI path; automatic when not a TTY)", false).action(
1616
1616
  (opts) => guarded(async () => {
1617
- const { runDocsStart } = await import("./mesh.start-HE6P3TCS.js");
1617
+ const { runDocsStart } = await import("./mesh.start-JDSYIRZI.js");
1618
1618
  await runDocsStart({
1619
1619
  repoRoot: findRepoRoot(process.cwd()),
1620
1620
  version: opts.version,
@@ -1626,13 +1626,13 @@ function registerDocsCommand(program) {
1626
1626
  );
1627
1627
  docs.command("stop").description(`Stop the detached docs server (the tmux session "${"mesh-docs"}")`).action(
1628
1628
  () => guarded(async () => {
1629
- const { runDocsStop } = await import("./mesh.start-HE6P3TCS.js");
1629
+ const { runDocsStop } = await import("./mesh.start-JDSYIRZI.js");
1630
1630
  runDocsStop();
1631
1631
  })()
1632
1632
  );
1633
1633
  docs.command("serve-static", { hidden: true }).option("--root <dir>", "built site root", "").option("--port <port>", "port", "4400").action(
1634
1634
  (opts) => guarded(async () => {
1635
- const { runDocsServeStatic } = await import("./mesh.start-HE6P3TCS.js");
1635
+ const { runDocsServeStatic } = await import("./mesh.start-JDSYIRZI.js");
1636
1636
  await runDocsServeStatic(opts);
1637
1637
  })()
1638
1638
  );
@@ -1675,7 +1675,7 @@ function registerDocsCommand(program) {
1675
1675
  );
1676
1676
  docs.command("list").description("List the published docs versions (each is an @mesh-tech/* baseline)").action(
1677
1677
  () => guarded(async () => {
1678
- const { runDocsList } = await import("./mesh.start-HE6P3TCS.js");
1678
+ const { runDocsList } = await import("./mesh.start-JDSYIRZI.js");
1679
1679
  await runDocsList();
1680
1680
  })()
1681
1681
  );
@@ -6959,7 +6959,7 @@ const target = ${JSON.stringify(targetPath)};
6959
6959
  const explicitProcessArtifact = ${JSON.stringify(explicitProcessArtifact ?? null)};
6960
6960
  const stat = statSync(target);
6961
6961
  const files = stat.isDirectory()
6962
- ? readdirSync(target).filter(f => f.endsWith(".ts") && f !== "index.ts").map(f => join(target, f))
6962
+ ? readdirSync(target).filter(f => f.endsWith(".ts") && f !== "index.ts" && !/\\.(test|spec|d)\\.ts$/.test(f)).map(f => join(target, f))
6963
6963
  : [target];
6964
6964
 
6965
6965
  const results = [];
@@ -7005,7 +7005,7 @@ ${DISCOVERY_HELPERS_SRC}
7005
7005
  const target = ${JSON.stringify(targetPath)};
7006
7006
  const stat = statSync(target);
7007
7007
  const files = stat.isDirectory()
7008
- ? readdirSync(target).filter(f => f.endsWith(".ts") && f !== "index.ts").map(f => join(target, f))
7008
+ ? readdirSync(target).filter(f => f.endsWith(".ts") && f !== "index.ts" && !/\\.(test|spec|d)\\.ts$/.test(f)).map(f => join(target, f))
7009
7009
  : [target];
7010
7010
 
7011
7011
  const results = [];
@@ -7059,7 +7059,7 @@ const target = ${JSON.stringify(targetPath)};
7059
7059
  const explicitProcessArtifact = ${JSON.stringify(explicitProcessArtifact ?? null)};
7060
7060
  const stat = statSync(target);
7061
7061
  const files = stat.isDirectory()
7062
- ? readdirSync(target).filter(f => f.endsWith(".ts") && f !== "index.ts").map(f => join(target, f))
7062
+ ? readdirSync(target).filter(f => f.endsWith(".ts") && f !== "index.ts" && !/\\.(test|spec|d)\\.ts$/.test(f)).map(f => join(target, f))
7063
7063
  : [target];
7064
7064
 
7065
7065
  const results = [];
@@ -7093,22 +7093,7 @@ process.stdout.write(JSON.stringify(results));
7093
7093
  return null;
7094
7094
  }
7095
7095
  }
7096
- async function uploadToS3(bucket, appName, workflows) {
7097
- const { S3Client, PutObjectCommand } = await import("@aws-sdk/client-s3");
7098
- const s3 = new S3Client({ region: process.env.AWS_REGION ?? "us-east-2" });
7099
- for (const wf of workflows) {
7100
- const key = `workflow-ir/${appName}/${wf.workflowType}.json`;
7101
- const body = JSON.stringify(wf.ir, null, 2);
7102
- logInfo(` Uploading s3://${bucket}/${key} (${body.length} bytes)`);
7103
- await s3.send(
7104
- new PutObjectCommand({
7105
- Bucket: bucket,
7106
- Key: key,
7107
- Body: body,
7108
- ContentType: "application/json"
7109
- })
7110
- );
7111
- }
7096
+ function workflowIrFiles(appName, workflows, root) {
7112
7097
  const manifest = {
7113
7098
  extractedAt: (/* @__PURE__ */ new Date()).toISOString(),
7114
7099
  app: appName,
@@ -7116,23 +7101,33 @@ async function uploadToS3(bucket, appName, workflows) {
7116
7101
  workflows.map((wf) => [
7117
7102
  wf.workflowType,
7118
7103
  {
7119
- sourceFile: wf.sourceFile,
7104
+ sourceFile: path14.relative(root, wf.sourceFile) || path14.basename(wf.sourceFile),
7120
7105
  nodeCount: wf.ir.nodes.length,
7121
7106
  edgeCount: wf.ir.edges.length
7122
7107
  }
7123
7108
  ])
7124
7109
  )
7125
7110
  };
7126
- const manifestKey = `workflow-ir/${appName}/_manifest.json`;
7127
- logInfo(` Uploading s3://${bucket}/${manifestKey}`);
7128
- await s3.send(
7129
- new PutObjectCommand({
7130
- Bucket: bucket,
7131
- Key: manifestKey,
7132
- Body: JSON.stringify(manifest, null, 2),
7133
- ContentType: "application/json"
7134
- })
7135
- );
7111
+ return [
7112
+ ...workflows.map((wf) => ({ name: `${wf.workflowType}.json`, body: JSON.stringify(wf.ir, null, 2) })),
7113
+ { name: "_manifest.json", body: JSON.stringify(manifest, null, 2) }
7114
+ ];
7115
+ }
7116
+ async function uploadToS3(bucket, appName, files) {
7117
+ const { S3Client, PutObjectCommand } = await import("@aws-sdk/client-s3");
7118
+ const s3 = new S3Client({ region: process.env.AWS_REGION ?? "us-east-2", followRegionRedirects: true });
7119
+ for (const file of files) {
7120
+ const key = `workflow-ir/${appName}/${file.name}`;
7121
+ logInfo(` Uploading s3://${bucket}/${key} (${file.body.length} bytes)`);
7122
+ await s3.send(
7123
+ new PutObjectCommand({
7124
+ Bucket: bucket,
7125
+ Key: key,
7126
+ Body: file.body,
7127
+ ContentType: "application/json"
7128
+ })
7129
+ );
7130
+ }
7136
7131
  }
7137
7132
  function parseNameList(value) {
7138
7133
  return value ? value.split(",").map((name) => name.trim()).filter((name) => name.length > 0) : void 0;
@@ -7144,6 +7139,9 @@ function registerWorkflowCommands(program) {
7144
7139
  ).option("--app <name>", "Application name (used as S3 key prefix)").option(
7145
7140
  "--upload <bucket>",
7146
7141
  "S3 bucket to upload extracted IR (requires --app)"
7142
+ ).option(
7143
+ "--out <dir>",
7144
+ "Write the files the upload would write (one JSON per workflow type, plus _manifest.json) to a directory (requires --app)"
7147
7145
  ).option(
7148
7146
  "--process <path>",
7149
7147
  "Path to a process artifact JSON file (docs/plans/2026-07-05-process-artifact-design.md \xA71); renders substeps/actors/outcomes in place of a BUSINESS_STAGES map. Absent this flag, a sibling process/*.process.json is auto-discovered per workflow file."
@@ -7185,15 +7183,29 @@ function registerWorkflowCommands(program) {
7185
7183
  ` ${wf.workflowType} (${wf.ir.nodes.length} nodes, ${wf.ir.edges.length} edges)`
7186
7184
  );
7187
7185
  }
7188
- if (opts.upload && opts.app) {
7186
+ if ((opts.upload || opts.out) && !opts.app) {
7187
+ logError("--upload and --out need --app (the IR's key prefix)");
7188
+ process.exitCode = 1;
7189
+ return;
7190
+ }
7191
+ const root = fs13.statSync(resolvedPath).isDirectory() ? resolvedPath : path14.dirname(resolvedPath);
7192
+ const files = opts.app ? workflowIrFiles(opts.app, results, root) : [];
7193
+ if (opts.out) {
7194
+ const outDir = path14.resolve(opts.out);
7195
+ fs13.mkdirSync(outDir, { recursive: true });
7196
+ for (const file of files) fs13.writeFileSync(path14.join(outDir, file.name), file.body);
7197
+ logSuccess(`Wrote ${files.length} file(s) to ${outDir}`);
7198
+ }
7199
+ if (opts.upload) {
7189
7200
  logInfo(
7190
7201
  `Uploading ${results.length} workflow IR(s) to s3://${opts.upload}/workflow-ir/${opts.app}/`
7191
7202
  );
7192
- await uploadToS3(opts.upload, opts.app, results);
7203
+ await uploadToS3(opts.upload, opts.app, files);
7193
7204
  logSuccess("Upload complete");
7194
- } else if (opts.upload || opts.app) {
7195
- logWarn("Both --app and --upload required for S3 upload");
7196
- } else {
7205
+ } else if (opts.app && !opts.out) {
7206
+ logWarn("--app does nothing without --upload or --out");
7207
+ }
7208
+ if (!opts.upload && !opts.out) {
7197
7209
  console.log(JSON.stringify(results.map((r) => r.ir), null, 2));
7198
7210
  }
7199
7211
  } catch (error) {