@solidnumber/cli 2.3.0 → 2.4.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.
Files changed (46) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/ai.d.ts.map +1 -1
  3. package/dist/commands/ai.js +10 -1
  4. package/dist/commands/ai.js.map +1 -1
  5. package/dist/commands/bids.d.ts +19 -0
  6. package/dist/commands/bids.d.ts.map +1 -0
  7. package/dist/commands/bids.js +310 -0
  8. package/dist/commands/bids.js.map +1 -0
  9. package/dist/commands/context.d.ts.map +1 -1
  10. package/dist/commands/context.js +17 -1
  11. package/dist/commands/context.js.map +1 -1
  12. package/dist/commands/install.d.ts.map +1 -1
  13. package/dist/commands/install.js +18 -6
  14. package/dist/commands/install.js.map +1 -1
  15. package/dist/commands/schema.js +29 -0
  16. package/dist/commands/schema.js.map +1 -1
  17. package/dist/commands/version.d.ts +38 -0
  18. package/dist/commands/version.d.ts.map +1 -0
  19. package/dist/commands/version.js +78 -0
  20. package/dist/commands/version.js.map +1 -0
  21. package/dist/index.js +30 -0
  22. package/dist/index.js.map +1 -1
  23. package/dist/lib/doctor-env.js +1 -1
  24. package/dist/lib/doctor-env.js.map +1 -1
  25. package/dist/lib/error-codes.d.ts +13 -0
  26. package/dist/lib/error-codes.d.ts.map +1 -1
  27. package/dist/lib/error-codes.js +36 -0
  28. package/dist/lib/error-codes.js.map +1 -1
  29. package/dist/lib/json-output.d.ts +22 -6
  30. package/dist/lib/json-output.d.ts.map +1 -1
  31. package/dist/lib/json-output.js +33 -1
  32. package/dist/lib/json-output.js.map +1 -1
  33. package/dist/lib/render-llms.d.ts +64 -0
  34. package/dist/lib/render-llms.d.ts.map +1 -0
  35. package/dist/lib/render-llms.js +115 -0
  36. package/dist/lib/render-llms.js.map +1 -0
  37. package/dist/lib/tenant-guard.d.ts +17 -0
  38. package/dist/lib/tenant-guard.d.ts.map +1 -1
  39. package/dist/lib/tenant-guard.js +33 -0
  40. package/dist/lib/tenant-guard.js.map +1 -1
  41. package/dist/lib/tenant-warn.d.ts +37 -0
  42. package/dist/lib/tenant-warn.d.ts.map +1 -0
  43. package/dist/lib/tenant-warn.js +92 -0
  44. package/dist/lib/tenant-warn.js.map +1 -0
  45. package/package.json +3 -1
  46. package/platform-docs/llms.txt +122 -15
@@ -1,10 +1,17 @@
1
1
  /**
2
- * --json output control (T11.3).
2
+ * --json output control.
3
3
  *
4
- * Three sources of truth, checked in order:
5
- * 1. The subcommand's own --json option (existing behavior, unchanged)
6
- * 2. The program-level --json option (NEW set at root)
7
- * 3. SOLID_JSON=1 env var (for piped/scripted usage)
4
+ * Sources of truth, checked in order:
5
+ * 1. Local subcommand --json option (existing behavior)
6
+ * 2. Local subcommand --no-json (explicit human override)
7
+ * 3. Program-level --json option
8
+ * 4. SOLID_JSON=1 env var
9
+ * 5. SOLID_NO_JSON=1 env var (explicit human override)
10
+ * 6. **NEW:** auto-detect — when stdout is NOT a TTY (piped, redirected,
11
+ * called by an agent over MCP, run inside CI), default to JSON.
12
+ * Agents read structured output; humans read prose. The TTY signal
13
+ * is the cleanest discriminator and matches the convention modern
14
+ * AI-first CLIs (gh, terraform JSON output, etc.) lean on.
8
15
  *
9
16
  * Commands that already check `options.json` keep working — the new
10
17
  * helpers are for (a) unifying detection across sources and (b) a
@@ -12,9 +19,18 @@
12
19
  */
13
20
  import { Command } from 'commander';
14
21
  export declare function setProgramJson(on: boolean): void;
22
+ /** True when stdout is not a TTY (pipe, redirect, agent, CI). */
23
+ export declare function isNonTty(): boolean;
15
24
  /**
16
- * True if any of: subcommand --json, program --json, SOLID_JSON env.
25
+ * True if any signal asks for JSON, including the auto-detect (non-TTY).
17
26
  * Pass the local command's options to honor the most specific flag.
27
+ *
28
+ * Jest carve-out: `typeof jest !== 'undefined'` only when this code runs
29
+ * inside a jest worker; child_process.execSync('node dist/...') does NOT
30
+ * inherit that global, so smoke tests that spawn the CLI and pass --json
31
+ * still get JSON. The carve-out keeps the 1000+ in-process unit tests in
32
+ * human-output mode (which is what they were written against) without
33
+ * needing an env var that would bleed into spawned subprocesses.
18
34
  */
19
35
  export declare function isJsonOutput(localOptions?: {
20
36
  json?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"json-output.d.ts","sourceRoot":"","sources":["../../src/lib/json-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAEhD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,YAAY,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAKjG;AAED,uFAAuF;AACvF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAI5C;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAInE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,YAAY,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,CAO/F"}
1
+ {"version":3,"file":"json-output.d.ts","sourceRoot":"","sources":["../../src/lib/json-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAEhD;AASD,iEAAiE;AACjE,wBAAgB,QAAQ,IAAI,OAAO,CAGlC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,YAAY,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAajG;AAED,uFAAuF;AACvF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAI5C;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAInE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,YAAY,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,CAO/F"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setProgramJson = setProgramJson;
4
+ exports.isNonTty = isNonTty;
4
5
  exports.isJsonOutput = isJsonOutput;
5
6
  exports.emitJson = emitJson;
6
7
  exports.activateProgramJsonIfRequested = activateProgramJsonIfRequested;
@@ -9,17 +10,48 @@ let programJson = false;
9
10
  function setProgramJson(on) {
10
11
  programJson = Boolean(on);
11
12
  }
13
+ /** True when the user has explicitly opted out of JSON. */
14
+ function explicitHumanOptOut(localOptions) {
15
+ if (localOptions && localOptions.json === false)
16
+ return true;
17
+ if (process.env.SOLID_NO_JSON && /^(1|true|yes|on)$/i.test(process.env.SOLID_NO_JSON))
18
+ return true;
19
+ return false;
20
+ }
21
+ /** True when stdout is not a TTY (pipe, redirect, agent, CI). */
22
+ function isNonTty() {
23
+ // process.stdout.isTTY is undefined when not a TTY, true when it is.
24
+ return process.stdout.isTTY !== true;
25
+ }
12
26
  /**
13
- * True if any of: subcommand --json, program --json, SOLID_JSON env.
27
+ * True if any signal asks for JSON, including the auto-detect (non-TTY).
14
28
  * Pass the local command's options to honor the most specific flag.
29
+ *
30
+ * Jest carve-out: `typeof jest !== 'undefined'` only when this code runs
31
+ * inside a jest worker; child_process.execSync('node dist/...') does NOT
32
+ * inherit that global, so smoke tests that spawn the CLI and pass --json
33
+ * still get JSON. The carve-out keeps the 1000+ in-process unit tests in
34
+ * human-output mode (which is what they were written against) without
35
+ * needing an env var that would bleed into spawned subprocesses.
15
36
  */
16
37
  function isJsonOutput(localOptions) {
17
38
  if (localOptions && localOptions.json === true)
18
39
  return true;
40
+ if (explicitHumanOptOut(localOptions))
41
+ return false;
19
42
  if (programJson)
20
43
  return true;
21
44
  if (process.env.SOLID_JSON && /^(1|true|yes|on)$/i.test(process.env.SOLID_JSON))
22
45
  return true;
46
+ // Jest in-process — preserve the legacy human-mode default. JEST_WORKER_ID
47
+ // is set on every jest worker but does NOT propagate to subprocesses
48
+ // spawned via execSync/execFileSync that override env, which is exactly
49
+ // the boundary we want.
50
+ if (process.env.JEST_WORKER_ID !== undefined)
51
+ return false;
52
+ // Auto-detect: agents and scripts pipe; humans use TTYs.
53
+ if (isNonTty())
54
+ return true;
23
55
  return false;
24
56
  }
25
57
  /** Emit JSON to stdout (pretty-printed) and return true so caller can early-return. */
@@ -1 +1 @@
1
- {"version":3,"file":"json-output.js","sourceRoot":"","sources":["../../src/lib/json-output.ts"],"names":[],"mappings":";;AAgBA,wCAEC;AAMD,oCAKC;AAGD,4BAIC;AAMD,wEAIC;AAOD,0CAOC;AA9CD,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,SAAgB,cAAc,CAAC,EAAW;IACxC,WAAW,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAAC,YAA2D;IACtF,IAAI,YAAY,IAAK,YAAoB,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrE,IAAI,WAAW;QAAE,OAAO,IAAI,CAAC;IAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7F,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uFAAuF;AACvF,SAAgB,QAAQ,CAAC,IAAa;IACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAgB,8BAA8B,CAAC,IAAc;IAC3D,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,cAAc,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAA+B,YAAe,EAAE,GAAa;IAC1F,IAAK,YAAoB,CAAC,IAAI;QAAE,OAAO,YAAY,CAAC;IACpD,MAAM,UAAU,GAAG,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;IACvD,IAAI,WAAW,IAAI,UAAU,IAAI,YAAY,EAAE,EAAE,CAAC;QAChD,OAAO,EAAE,GAAG,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"json-output.js","sourceRoot":"","sources":["../../src/lib/json-output.ts"],"names":[],"mappings":";;AAuBA,wCAEC;AAUD,4BAGC;AAaD,oCAaC;AAGD,4BAIC;AAMD,wEAIC;AAOD,0CAOC;AA1ED,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,SAAgB,cAAc,CAAC,EAAW;IACxC,WAAW,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,2DAA2D;AAC3D,SAAS,mBAAmB,CAAC,YAA2D;IACtF,IAAI,YAAY,IAAK,YAAoB,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACtE,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QAAE,OAAO,IAAI,CAAC;IACnG,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iEAAiE;AACjE,SAAgB,QAAQ;IACtB,qEAAqE;IACrE,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;AACvC,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,YAAY,CAAC,YAA2D;IACtF,IAAI,YAAY,IAAK,YAAoB,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrE,IAAI,mBAAmB,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,WAAW;QAAE,OAAO,IAAI,CAAC;IAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7F,2EAA2E;IAC3E,qEAAqE;IACrE,wEAAwE;IACxE,wBAAwB;IACxB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC3D,yDAAyD;IACzD,IAAI,QAAQ,EAAE;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uFAAuF;AACvF,SAAgB,QAAQ,CAAC,IAAa;IACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAgB,8BAA8B,CAAC,IAAc;IAC3D,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,cAAc,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAA+B,YAAe,EAAE,GAAa;IAC1F,IAAK,YAAoB,CAAC,IAAI;QAAE,OAAO,YAAY,CAAC;IACpD,MAAM,UAAU,GAAG,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;IACvD,IAAI,WAAW,IAAI,UAAU,IAAI,YAAY,EAAE,EAAE,CAAC;QAChD,OAAO,EAAE,GAAG,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * render-llms — pure rendering of the auto-generated CLI section that
3
+ * gets stamped into platform-docs/llms.txt at build time.
4
+ *
5
+ * No I/O, no commander, no exec. Takes a verb manifest (the same shape
6
+ * `solid schema verbs --json` emits) and returns the markdown string
7
+ * that goes between the AUTO:BEGIN / AUTO:END markers.
8
+ *
9
+ * Why a pure renderer:
10
+ * 1. Unit-testable without booting the CLI.
11
+ * 2. Same renderer can power a future
12
+ * `solid schema docs --format=llms` command, so the doc shape
13
+ * lives in one place.
14
+ *
15
+ * Drift killer: every claim in the rendered section comes straight off
16
+ * the verb manifest. Group counts, subcommand counts, missing verbs,
17
+ * version — all auto-derived. The hand-maintained variant of this
18
+ * section had drifted to ~1/3 truth by v2.3.2 (see ANGL feedback,
19
+ * 2026-05-07).
20
+ */
21
+ export interface ManifestOption {
22
+ flags: string;
23
+ description: string;
24
+ }
25
+ export interface ManifestVerb {
26
+ verb: string;
27
+ path: string;
28
+ description: string;
29
+ depth: number;
30
+ subcommands: string[];
31
+ is_leaf: boolean;
32
+ options?: ManifestOption[];
33
+ }
34
+ export interface VerbManifest {
35
+ version: string;
36
+ cli_version: string;
37
+ count: number;
38
+ verbs: ManifestVerb[];
39
+ }
40
+ export interface RenderInput {
41
+ manifest: VerbManifest;
42
+ /** ISO date — embedded so agents can spot stale tarballs. */
43
+ generated_at: string;
44
+ }
45
+ export interface RenderedSections {
46
+ /** Replaces content between CLI:AUTO:BEGIN and CLI:AUTO:END. */
47
+ cli: string;
48
+ /** Replaces content between CLI:Q&A:BEGIN and CLI:Q&A:END (the FAQ line). */
49
+ faq_cli: string;
50
+ }
51
+ export declare function renderCliSection(input: RenderInput): string;
52
+ export declare function renderCliFaqAnswer(manifest: VerbManifest): string;
53
+ export interface ApplyOptions {
54
+ /** Throw if a marker pair is missing (instead of silently leaving doc unchanged). */
55
+ strict?: boolean;
56
+ }
57
+ export declare function applyToTemplate(template: string, sections: RenderedSections, opts?: ApplyOptions): string;
58
+ export declare const MARKERS: {
59
+ readonly CLI_BEGIN: "<!-- CLI:AUTO:BEGIN -->";
60
+ readonly CLI_END: "<!-- CLI:AUTO:END -->";
61
+ readonly FAQ_BEGIN: "<!-- CLI:Q&A:BEGIN -->";
62
+ readonly FAQ_END: "<!-- CLI:Q&A:END -->";
63
+ };
64
+ //# sourceMappingURL=render-llms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-llms.d.ts","sourceRoot":"","sources":["../../src/lib/render-llms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,YAAY,CAAC;IACvB,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;CACjB;AAyBD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAkC3D;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CASjE;AAOD,MAAM,WAAW,YAAY;IAC3B,qFAAqF;IACrF,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,IAAI,GAAE,YAAiB,GAAG,MAAM,CAG7G;AAgBD,eAAO,MAAM,OAAO;;;;;CAKV,CAAC"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * render-llms — pure rendering of the auto-generated CLI section that
4
+ * gets stamped into platform-docs/llms.txt at build time.
5
+ *
6
+ * No I/O, no commander, no exec. Takes a verb manifest (the same shape
7
+ * `solid schema verbs --json` emits) and returns the markdown string
8
+ * that goes between the AUTO:BEGIN / AUTO:END markers.
9
+ *
10
+ * Why a pure renderer:
11
+ * 1. Unit-testable without booting the CLI.
12
+ * 2. Same renderer can power a future
13
+ * `solid schema docs --format=llms` command, so the doc shape
14
+ * lives in one place.
15
+ *
16
+ * Drift killer: every claim in the rendered section comes straight off
17
+ * the verb manifest. Group counts, subcommand counts, missing verbs,
18
+ * version — all auto-derived. The hand-maintained variant of this
19
+ * section had drifted to ~1/3 truth by v2.3.2 (see ANGL feedback,
20
+ * 2026-05-07).
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.MARKERS = void 0;
24
+ exports.renderCliSection = renderCliSection;
25
+ exports.renderCliFaqAnswer = renderCliFaqAnswer;
26
+ exports.applyToTemplate = applyToTemplate;
27
+ /** Top-level groups (depth 0) sorted alphabetically. */
28
+ function topLevelGroups(manifest) {
29
+ return manifest.verbs.filter((v) => v.depth === 0).sort((a, b) => a.verb.localeCompare(b.verb));
30
+ }
31
+ /** Top-level leaves (depth 0, no subcommands) — vibe, ask_owner, etc. */
32
+ function topLevelLeaves(manifest) {
33
+ return topLevelGroups(manifest).filter((v) => v.is_leaf);
34
+ }
35
+ /** Top-level groups that DO have subcommands. */
36
+ function topLevelGroupsWithSubs(manifest) {
37
+ return topLevelGroups(manifest).filter((v) => !v.is_leaf);
38
+ }
39
+ /** Direct children of a depth-0 group. */
40
+ function childrenOf(manifest, parent) {
41
+ return manifest.verbs
42
+ .filter((v) => v.depth === parent.depth + 1 && v.path.startsWith(parent.path + " "))
43
+ .filter((v) => v.path.split(" ").length === parent.path.split(" ").length + 1)
44
+ .sort((a, b) => a.verb.localeCompare(b.verb));
45
+ }
46
+ function renderCliSection(input) {
47
+ const m = input.manifest;
48
+ const groups = topLevelGroups(m);
49
+ const groupsWithSubs = topLevelGroupsWithSubs(m);
50
+ const leaves = topLevelLeaves(m);
51
+ const totalSubcommands = m.verbs.filter((v) => v.depth > 0).length;
52
+ const lines = [];
53
+ lines.push("");
54
+ lines.push(`- [npm](https://www.npmjs.com/package/@solidnumber/cli): \`@solidnumber/cli\` v${m.cli_version}`);
55
+ lines.push(`- [GitHub](https://github.com/Adam-Camp-King/solid-cli): Open-source TypeScript CLI (BUSL-1.1)`);
56
+ lines.push(`- [CLI Documentation](https://solidnumber.com/docs/cli): Full command reference`);
57
+ lines.push(`- **Machine-readable verb tree**: \`solid schema verbs --json\` — every command, every flag, every description, in one JSON dump. Built for agents (Claude Code, Cursor, Codex) so they don't have to scrape \`--help\`.`);
58
+ lines.push(`- ${groups.length} top-level command groups, ${totalSubcommands} subcommands.`);
59
+ lines.push(`- Core workflow: \`solid auth login\` → \`solid company create\` → \`solid clone <industry>\` → \`solid pull\` → edit → \`solid push\` → \`solid pages publish\` → \`solid billing checkout-link\`.`);
60
+ lines.push("");
61
+ lines.push("**Top-level commands (no subcommands):**");
62
+ lines.push("");
63
+ for (const v of leaves) {
64
+ const desc = v.description ? ` — ${v.description}` : "";
65
+ lines.push(`- \`solid ${v.verb}\`${desc}`);
66
+ }
67
+ lines.push("");
68
+ lines.push("**Command groups (alphabetical):**");
69
+ lines.push("");
70
+ for (const g of groupsWithSubs) {
71
+ const subs = childrenOf(m, g).map((c) => c.verb);
72
+ const desc = g.description ? ` — ${g.description}` : "";
73
+ lines.push(`- **${g.verb}** (${subs.length} subcommands)${desc}: \`${subs.join(", ")}\``);
74
+ }
75
+ lines.push("");
76
+ lines.push(`*Auto-generated from the live commander tree at build time. CLI version ${m.cli_version}, manifest schema ${m.version}, generated ${input.generated_at}. Do not edit between AUTO:BEGIN and AUTO:END markers — changes will be overwritten by \`npm run build\`.*`);
77
+ lines.push("");
78
+ return lines.join("\n");
79
+ }
80
+ function renderCliFaqAnswer(manifest) {
81
+ const groups = topLevelGroups(manifest);
82
+ const totalSubcommands = manifest.verbs.filter((v) => v.depth > 0).length;
83
+ return (`- "Does Solid# have a CLI?" → Yes. \`npm i -g @solidnumber/cli\` — ${groups.length} top-level command groups, ${totalSubcommands} subcommands. ` +
84
+ `Create companies, scaffold industry websites, manage pages, run SEO audits, send invoices, chat with AI agents, generate pages with AI, all from the terminal. ` +
85
+ `Free developer tier. Agency tier ($495/mo) for unlimited client companies. ` +
86
+ `Agents discover the full verb tree via \`solid schema verbs --json\`.`);
87
+ }
88
+ const CLI_BEGIN = "<!-- CLI:AUTO:BEGIN -->";
89
+ const CLI_END = "<!-- CLI:AUTO:END -->";
90
+ const FAQ_BEGIN = "<!-- CLI:Q&A:BEGIN -->";
91
+ const FAQ_END = "<!-- CLI:Q&A:END -->";
92
+ function applyToTemplate(template, sections, opts = {}) {
93
+ const out = replaceBetween(template, CLI_BEGIN, CLI_END, sections.cli, "CLI", opts);
94
+ return replaceBetween(out, FAQ_BEGIN, FAQ_END, sections.faq_cli, "CLI:Q&A", opts);
95
+ }
96
+ function replaceBetween(text, begin, end, body, label, opts) {
97
+ const beginIdx = text.indexOf(begin);
98
+ const endIdx = text.indexOf(end);
99
+ if (beginIdx === -1 || endIdx === -1 || endIdx < beginIdx) {
100
+ if (opts.strict) {
101
+ throw new Error(`${label} markers missing or out of order in llms.txt: insert ${begin} … ${end} where the auto-section should live`);
102
+ }
103
+ return text;
104
+ }
105
+ const before = text.slice(0, beginIdx + begin.length);
106
+ const after = text.slice(endIdx);
107
+ return `${before}\n${body}\n${after}`;
108
+ }
109
+ exports.MARKERS = {
110
+ CLI_BEGIN,
111
+ CLI_END,
112
+ FAQ_BEGIN,
113
+ FAQ_END,
114
+ };
115
+ //# sourceMappingURL=render-llms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-llms.js","sourceRoot":"","sources":["../../src/lib/render-llms.ts"],"names":[],"mappings":"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"}
@@ -112,4 +112,21 @@ export declare function checkTenantManifest(baseDir: string, companyId: number):
112
112
  * local tenant working tree should call this before touching the filesystem.
113
113
  */
114
114
  export declare function requireTenantManifest(baseDir: string, companyId: number): PullManifest;
115
+ /**
116
+ * Lenient guard for hook contexts (e.g. `solid context --if-tenant` fired
117
+ * by Claude Code's SessionStart). Returns the manifest if the directory is
118
+ * properly bound; returns null when the directory is a protected root
119
+ * (platform monorepo, $HOME, $HOME/.claude) or simply has no manifest —
120
+ * both meaning "no tenant write to do here, move on quietly".
121
+ *
122
+ * The `mismatch` failure mode is still loud and still exits 1: a manifest
123
+ * pinning the dir to company A while the user is logged in as company B is
124
+ * a real misconfiguration and silently skipping would let stale or wrong
125
+ * context flow into the next Claude session. We want loud here.
126
+ *
127
+ * Use this — not `requireTenantManifest` — for any code path that runs
128
+ * automatically (hooks, cron, post-install scripts) where "I'm not in a
129
+ * tenant directory" is the expected case, not an error.
130
+ */
131
+ export declare function tenantManifestForHook(baseDir: string, companyId: number): PullManifest | null;
115
132
  //# sourceMappingURL=tenant-guard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tenant-guard.d.ts","sourceRoot":"","sources":["../../src/lib/tenant-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,aAAa,GAAG,eAAe,CAAC;AAE3E,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAChG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1G,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAsBzC;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAcjF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKzD;AAiBD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAsBnF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAkBtF"}
1
+ {"version":3,"file":"tenant-guard.d.ts","sourceRoot":"","sources":["../../src/lib/tenant-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,aAAa,GAAG,eAAe,CAAC;AAE3E,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAChG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1G,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAsBzC;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAcjF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKzD;AAiBD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAsBnF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAkBtF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,YAAY,GAAG,IAAI,CAYrB"}
@@ -52,6 +52,7 @@ exports.isProtectedRoot = isProtectedRoot;
52
52
  exports.refuseProtectedRoot = refuseProtectedRoot;
53
53
  exports.checkTenantManifest = checkTenantManifest;
54
54
  exports.requireTenantManifest = requireTenantManifest;
55
+ exports.tenantManifestForHook = tenantManifestForHook;
55
56
  const fs = __importStar(require("fs"));
56
57
  const os = __importStar(require("os"));
57
58
  const path = __importStar(require("path"));
@@ -197,4 +198,36 @@ function requireTenantManifest(baseDir, companyId) {
197
198
  }
198
199
  process.exit(1);
199
200
  }
201
+ /**
202
+ * Lenient guard for hook contexts (e.g. `solid context --if-tenant` fired
203
+ * by Claude Code's SessionStart). Returns the manifest if the directory is
204
+ * properly bound; returns null when the directory is a protected root
205
+ * (platform monorepo, $HOME, $HOME/.claude) or simply has no manifest —
206
+ * both meaning "no tenant write to do here, move on quietly".
207
+ *
208
+ * The `mismatch` failure mode is still loud and still exits 1: a manifest
209
+ * pinning the dir to company A while the user is logged in as company B is
210
+ * a real misconfiguration and silently skipping would let stale or wrong
211
+ * context flow into the next Claude session. We want loud here.
212
+ *
213
+ * Use this — not `requireTenantManifest` — for any code path that runs
214
+ * automatically (hooks, cron, post-install scripts) where "I'm not in a
215
+ * tenant directory" is the expected case, not an error.
216
+ */
217
+ function tenantManifestForHook(baseDir, companyId) {
218
+ const result = checkTenantManifest(baseDir, companyId);
219
+ if (result.ok)
220
+ return result.manifest;
221
+ if (result.failure.kind === 'protected_root')
222
+ return null;
223
+ if (result.failure.kind === 'missing')
224
+ return null;
225
+ // mismatch — fall through to the loud handler in requireTenantManifest
226
+ // so the message stays in one place.
227
+ const f = result.failure;
228
+ console.error(chalk_1.default.red(`Directory belongs to company ${f.manifestCompanyId} (${f.manifestCompanyName}).`));
229
+ console.error(chalk_1.default.red(`You are logged in as company ${f.activeCompanyId}.`));
230
+ console.error(chalk_1.default.dim(` Run \`solid switch ${f.manifestCompanyId}\` to match, or cd elsewhere.`));
231
+ process.exit(1);
232
+ }
200
233
  //# sourceMappingURL=tenant-guard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tenant-guard.js","sourceRoot":"","sources":["../../src/lib/tenant-guard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tenant-guard.js","sourceRoot":"","sources":["../../src/lib/tenant-guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ export interface ImplicitTenantWarning {
2
+ warning: {
3
+ code: 'IMPLICIT_TENANT';
4
+ message: string;
5
+ company_id: number;
6
+ hint: string;
7
+ };
8
+ }
9
+ export declare function buildImplicitTenantWarning(companyId: number): ImplicitTenantWarning;
10
+ /**
11
+ * True when the warning should fire for this invocation:
12
+ * - non-TTY caller (agent, MCP, CI),
13
+ * - no explicit --company / SOLID_COMPANY_ID,
14
+ * - opt-out env not set.
15
+ *
16
+ * The argv check deliberately scans for a few common spellings rather
17
+ * than parsing options properly — this runs at boot before commander
18
+ * dispatches and we want zero allocation cost.
19
+ */
20
+ export declare function shouldWarnImplicitTenant(opts: {
21
+ argv: string[];
22
+ env: NodeJS.ProcessEnv;
23
+ hasCurrentCompany: boolean;
24
+ }): boolean;
25
+ /** Emit the warning to stderr in the right format for the caller. */
26
+ export declare function emitImplicitTenantWarning(companyId: number): void;
27
+ /**
28
+ * Boot-time hook: call once from index.ts after argv has been parsed
29
+ * for the global flags but before commander dispatches the action.
30
+ */
31
+ export declare function maybeWarnImplicitTenant(opts: {
32
+ argv: string[];
33
+ env: NodeJS.ProcessEnv;
34
+ hasCurrentCompany: boolean;
35
+ companyId: number | null;
36
+ }): void;
37
+ //# sourceMappingURL=tenant-warn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-warn.d.ts","sourceRoot":"","sources":["../../src/lib/tenant-warn.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE;QACP,IAAI,EAAE,iBAAiB,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,qBAAqB,CASnF;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;CAC5B,GAAG,OAAO,CAaV;AAED,qEAAqE;AACrE,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CASjE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,IAAI,CAIP"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildImplicitTenantWarning = buildImplicitTenantWarning;
4
+ exports.shouldWarnImplicitTenant = shouldWarnImplicitTenant;
5
+ exports.emitImplicitTenantWarning = emitImplicitTenantWarning;
6
+ exports.maybeWarnImplicitTenant = maybeWarnImplicitTenant;
7
+ /**
8
+ * tenant-warn — soft warning when a non-TTY caller (agent, script) is
9
+ * about to operate on the implicit "current company" set by `solid switch`
10
+ * without passing --company explicitly.
11
+ *
12
+ * Why soft (warning, not hard refusal):
13
+ * Hard refusal would break every existing automation overnight. The
14
+ * feedback that surfaced this concern (Tier 1 #5, ANGL 2026-05-07)
15
+ * acknowledged the trade-off — implicit state is fine for humans, it
16
+ * is a data-leak vector for agents because they can forget to switch.
17
+ * A structured stderr warning gives agents the visibility to gate on
18
+ * the situation themselves while existing scripts keep working.
19
+ *
20
+ * What gets emitted (stderr, single line, JSON when --json is in effect,
21
+ * prose otherwise):
22
+ *
23
+ * {warning:{code:"IMPLICIT_TENANT", message:"...", company_id:N, hint:"..."}}
24
+ *
25
+ * Agents key on `warning.code === "IMPLICIT_TENANT"` and either
26
+ * (a) abort and ask the human, or
27
+ * (b) include --company <id> on the next call to silence it.
28
+ *
29
+ * Opt-out for noisy CI: SOLID_NO_TENANT_WARN=1.
30
+ */
31
+ const json_output_1 = require("./json-output");
32
+ function buildImplicitTenantWarning(companyId) {
33
+ return {
34
+ warning: {
35
+ code: 'IMPLICIT_TENANT',
36
+ message: `Operating on implicit current company (id=${companyId}). Pass --company to be explicit.`,
37
+ company_id: companyId,
38
+ hint: 'Add --company <id> to lock the tenant for this call, or set SOLID_COMPANY_ID. Silence with SOLID_NO_TENANT_WARN=1.',
39
+ },
40
+ };
41
+ }
42
+ /**
43
+ * True when the warning should fire for this invocation:
44
+ * - non-TTY caller (agent, MCP, CI),
45
+ * - no explicit --company / SOLID_COMPANY_ID,
46
+ * - opt-out env not set.
47
+ *
48
+ * The argv check deliberately scans for a few common spellings rather
49
+ * than parsing options properly — this runs at boot before commander
50
+ * dispatches and we want zero allocation cost.
51
+ */
52
+ function shouldWarnImplicitTenant(opts) {
53
+ if (!opts.hasCurrentCompany)
54
+ return false;
55
+ if (!(0, json_output_1.isNonTty)())
56
+ return false;
57
+ if (opts.env.SOLID_NO_TENANT_WARN && /^(1|true|yes|on)$/i.test(opts.env.SOLID_NO_TENANT_WARN)) {
58
+ return false;
59
+ }
60
+ if (opts.env.SOLID_COMPANY_ID)
61
+ return false;
62
+ // Walk argv for any --company / --company-id / -c <value> form.
63
+ for (const arg of opts.argv) {
64
+ if (arg === '--company' || arg === '--company-id' || arg === '-c')
65
+ return false;
66
+ if (arg.startsWith('--company=') || arg.startsWith('--company-id='))
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+ /** Emit the warning to stderr in the right format for the caller. */
72
+ function emitImplicitTenantWarning(companyId) {
73
+ const w = buildImplicitTenantWarning(companyId);
74
+ if ((0, json_output_1.isJsonOutput)()) {
75
+ process.stderr.write(JSON.stringify(w) + '\n');
76
+ }
77
+ else {
78
+ process.stderr.write(`! Implicit tenant: company_id=${companyId}. Pass --company to be explicit.\n`);
79
+ }
80
+ }
81
+ /**
82
+ * Boot-time hook: call once from index.ts after argv has been parsed
83
+ * for the global flags but before commander dispatches the action.
84
+ */
85
+ function maybeWarnImplicitTenant(opts) {
86
+ if (!shouldWarnImplicitTenant(opts))
87
+ return;
88
+ if (opts.companyId == null)
89
+ return;
90
+ emitImplicitTenantWarning(opts.companyId);
91
+ }
92
+ //# sourceMappingURL=tenant-warn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-warn.js","sourceRoot":"","sources":["../../src/lib/tenant-warn.ts"],"names":[],"mappings":";;AAmCA,gEASC;AAYD,4DAiBC;AAGD,8DASC;AAMD,0DASC;AApGD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,+CAAuD;AAWvD,SAAgB,0BAA0B,CAAC,SAAiB;IAC1D,OAAO;QACL,OAAO,EAAE;YACP,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,6CAA6C,SAAS,mCAAmC;YAClG,UAAU,EAAE,SAAS;YACrB,IAAI,EAAE,oHAAoH;SAC3H;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,wBAAwB,CAAC,IAIxC;IACC,IAAI,CAAC,IAAI,CAAC,iBAAiB;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,CAAC,IAAA,sBAAQ,GAAE;QAAE,OAAO,KAAK,CAAC;IAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,oBAAoB,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC9F,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,gBAAgB;QAAE,OAAO,KAAK,CAAC;IAC5C,gEAAgE;IAChE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,cAAc,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAChF,IAAI,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC;YAAE,OAAO,KAAK,CAAC;IACpF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,qEAAqE;AACrE,SAAgB,yBAAyB,CAAC,SAAiB;IACzD,MAAM,CAAC,GAAG,0BAA0B,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,IAAA,0BAAY,GAAE,EAAE,CAAC;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sCAAsC,SAAS,wCAAwC,CACxF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB,CAAC,IAKvC;IACC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC;QAAE,OAAO;IAC5C,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI;QAAE,OAAO;IACnC,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC5C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidnumber/cli",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "AI business infrastructure from the terminal — CRM, payments, voice AI, 116 agents, 52 industry templates. solid clone plumber → instant business. Also: programmatic TS SDK via @solidnumber/cli/sdk.",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",
@@ -24,6 +24,8 @@
24
24
  },
25
25
  "scripts": {
26
26
  "build": "tsc && node -e \"require('fs').cpSync('src/data','dist/data',{recursive:true})\"",
27
+ "postbuild": "ts-node scripts/generate-llms.ts",
28
+ "verify:llms": "ts-node scripts/generate-llms.ts --check",
27
29
  "dev": "ts-node src/index.ts",
28
30
  "start": "node dist/index.js",
29
31
  "lint": "eslint src/**/*.ts",