@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.
- package/README.md +1 -1
- package/dist/commands/ai.d.ts.map +1 -1
- package/dist/commands/ai.js +10 -1
- package/dist/commands/ai.js.map +1 -1
- package/dist/commands/bids.d.ts +19 -0
- package/dist/commands/bids.d.ts.map +1 -0
- package/dist/commands/bids.js +310 -0
- package/dist/commands/bids.js.map +1 -0
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +17 -1
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +18 -6
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/schema.js +29 -0
- package/dist/commands/schema.js.map +1 -1
- package/dist/commands/version.d.ts +38 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +78 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/doctor-env.js +1 -1
- package/dist/lib/doctor-env.js.map +1 -1
- package/dist/lib/error-codes.d.ts +13 -0
- package/dist/lib/error-codes.d.ts.map +1 -1
- package/dist/lib/error-codes.js +36 -0
- package/dist/lib/error-codes.js.map +1 -1
- package/dist/lib/json-output.d.ts +22 -6
- package/dist/lib/json-output.d.ts.map +1 -1
- package/dist/lib/json-output.js +33 -1
- package/dist/lib/json-output.js.map +1 -1
- package/dist/lib/render-llms.d.ts +64 -0
- package/dist/lib/render-llms.d.ts.map +1 -0
- package/dist/lib/render-llms.js +115 -0
- package/dist/lib/render-llms.js.map +1 -0
- package/dist/lib/tenant-guard.d.ts +17 -0
- package/dist/lib/tenant-guard.d.ts.map +1 -1
- package/dist/lib/tenant-guard.js +33 -0
- package/dist/lib/tenant-guard.js.map +1 -1
- package/dist/lib/tenant-warn.d.ts +37 -0
- package/dist/lib/tenant-warn.d.ts.map +1 -0
- package/dist/lib/tenant-warn.js +92 -0
- package/dist/lib/tenant-warn.js.map +1 -0
- package/package.json +3 -1
- package/platform-docs/llms.txt +122 -15
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* --json output control
|
|
2
|
+
* --json output control.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* 1.
|
|
6
|
-
* 2.
|
|
7
|
-
* 3.
|
|
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
|
|
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
|
|
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"}
|
package/dist/lib/json-output.js
CHANGED
|
@@ -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
|
|
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":";;
|
|
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"}
|
package/dist/lib/tenant-guard.js
CHANGED
|
@@ -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":";AAAA;;;;;;;;;;GAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgEH,kDAgBC;AAoBD,0CAEC;AAQD,kDAKC;AAsBD,kDAsBC;AAOD,sDAkBC;
|
|
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(`[33m! Implicit tenant: company_id=${companyId}. Pass --company to be explicit.[0m\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
|
+
"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",
|