@ze-norm/cli 0.12.0 → 0.14.1
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/api/client.d.ts.map +1 -1
- package/dist/api/client.js +16 -6
- package/dist/auth/device-flow.d.ts.map +1 -1
- package/dist/auth/device-flow.js +11 -0
- package/dist/auth/store.d.ts.map +1 -1
- package/dist/auth/store.js +7 -1
- package/dist/commands/interactive-agent.d.ts +92 -0
- package/dist/commands/interactive-agent.d.ts.map +1 -0
- package/dist/commands/interactive-agent.js +120 -0
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +23 -2
- package/dist/commands/work-render.d.ts +22 -0
- package/dist/commands/work-render.d.ts.map +1 -1
- package/dist/commands/work-render.js +33 -0
- package/dist/commands/work.d.ts +117 -3
- package/dist/commands/work.d.ts.map +1 -1
- package/dist/commands/work.js +391 -41
- package/dist/config/environments.d.ts +31 -0
- package/dist/config/environments.d.ts.map +1 -0
- package/dist/config/environments.js +65 -0
- package/dist/config/schema.d.ts +10 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +6 -0
- package/dist/util/markdown.d.ts +16 -0
- package/dist/util/markdown.d.ts.map +1 -1
- package/dist/util/markdown.js +34 -0
- package/package.json +1 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { CliError } from "../util/errors.js";
|
|
2
|
+
import { PRODUCTION_API_URL, PRODUCTION_CLERK_CLIENT_ID, PRODUCTION_CLERK_ISSUER, } from "./defaults.js";
|
|
3
|
+
const PROD_ENVIRONMENT = {
|
|
4
|
+
name: "prod",
|
|
5
|
+
apiUrl: PRODUCTION_API_URL,
|
|
6
|
+
clerkIssuer: PRODUCTION_CLERK_ISSUER,
|
|
7
|
+
clerkClientId: PRODUCTION_CLERK_CLIENT_ID,
|
|
8
|
+
};
|
|
9
|
+
export const ZENORM_CLI_ENV_VAR = "ZENORM_CLI";
|
|
10
|
+
const ENV_NAMES = ["prod", "dev", "local"];
|
|
11
|
+
/**
|
|
12
|
+
* Normalize a raw `ZENORM_CLI` value to a canonical env name. Accepts the bare
|
|
13
|
+
* name (`prod`/`dev`/`local`), `production`, and each name with a `-zenorm`
|
|
14
|
+
* suffix (constructed here so the suffixed literal is never a static token).
|
|
15
|
+
*/
|
|
16
|
+
function parseEnvName(raw) {
|
|
17
|
+
const key = raw.trim().toLowerCase();
|
|
18
|
+
if (key === "production")
|
|
19
|
+
return "prod";
|
|
20
|
+
for (const name of ENV_NAMES) {
|
|
21
|
+
if (key === name || key === `${name}-zenorm`)
|
|
22
|
+
return name;
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build a non-prod environment from the endpoint env vars injected by the
|
|
28
|
+
* repo launchers. Fails loud if they are missing — that means the public
|
|
29
|
+
* `zenorm` was pointed at an internal stack without the launcher that carries
|
|
30
|
+
* its (non-shipped) endpoints, and we must not silently fall back to prod.
|
|
31
|
+
*/
|
|
32
|
+
function environmentFromInjectedVars(name) {
|
|
33
|
+
const apiUrl = process.env["ZENORM_API_URL"];
|
|
34
|
+
const clerkIssuer = process.env["ZENORM_CLERK_ISSUER"];
|
|
35
|
+
const clerkClientId = process.env["ZENORM_CLERK_CLIENT_ID"];
|
|
36
|
+
if (!apiUrl || !clerkIssuer || !clerkClientId) {
|
|
37
|
+
const shim = `${name}${"-zenorm"}`;
|
|
38
|
+
throw new CliError(`${ZENORM_CLI_ENV_VAR}=${name} needs the ${name} endpoints, which are not ` +
|
|
39
|
+
`bundled in the public CLI. Launch it with \`${shim}\` (from the repo), ` +
|
|
40
|
+
`or set ZENORM_API_URL, ZENORM_CLERK_ISSUER, and ZENORM_CLERK_CLIENT_ID.`);
|
|
41
|
+
}
|
|
42
|
+
return { name, apiUrl, clerkIssuer, clerkClientId };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Resolve the active CLI environment from `ZENORM_CLI`.
|
|
46
|
+
*
|
|
47
|
+
* Unset → production (the public default). A set-but-unrecognized value is a
|
|
48
|
+
* loud error rather than a silent fallback: a typo like `ZENORM_CLI=prd` must
|
|
49
|
+
* not quietly send `zenorm` commands at the wrong stack.
|
|
50
|
+
*/
|
|
51
|
+
export function resolveEnvironment() {
|
|
52
|
+
const raw = process.env[ZENORM_CLI_ENV_VAR];
|
|
53
|
+
if (raw === undefined || raw.trim() === "") {
|
|
54
|
+
return PROD_ENVIRONMENT;
|
|
55
|
+
}
|
|
56
|
+
const name = parseEnvName(raw);
|
|
57
|
+
if (!name) {
|
|
58
|
+
const allowed = ENV_NAMES.join(", ");
|
|
59
|
+
throw new CliError(`Invalid ${ZENORM_CLI_ENV_VAR}=${JSON.stringify(raw)}. ` +
|
|
60
|
+
`Expected one of: ${allowed} (or a "-zenorm" suffixed form).`);
|
|
61
|
+
}
|
|
62
|
+
if (name === "prod")
|
|
63
|
+
return PROD_ENVIRONMENT;
|
|
64
|
+
return environmentFromInjectedVars(name);
|
|
65
|
+
}
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
export interface ZenormConfig {
|
|
2
2
|
org?: string;
|
|
3
3
|
apiUrl?: string;
|
|
4
|
+
/**
|
|
5
|
+
* Opt into coding-agent mode for local `zenorm work` runs: instead of running
|
|
6
|
+
* each task headlessly, launch the active coding agent (the one named by
|
|
7
|
+
* `--agent`) as a LIVE interactive session seeded with the spec handoff. The
|
|
8
|
+
* operator works with the agent, then closes it to release the worker and
|
|
9
|
+
* continue to the next task. Off by default; the `--interactive` flag
|
|
10
|
+
* overrides this. Requires a usable local TTY at run time (fails loud
|
|
11
|
+
* otherwise — see `interactive-agent.ts`).
|
|
12
|
+
*/
|
|
13
|
+
interactive?: boolean;
|
|
4
14
|
}
|
|
5
15
|
export declare function validateConfig(raw: unknown): ZenormConfig;
|
|
6
16
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CA8BzD"}
|
package/dist/config/schema.js
CHANGED
|
@@ -17,5 +17,11 @@ export function validateConfig(raw) {
|
|
|
17
17
|
}
|
|
18
18
|
config.apiUrl = obj["apiUrl"];
|
|
19
19
|
}
|
|
20
|
+
if ("interactive" in obj) {
|
|
21
|
+
if (typeof obj["interactive"] !== "boolean") {
|
|
22
|
+
throw new CliError('.zenorm.json: "interactive" must be a boolean');
|
|
23
|
+
}
|
|
24
|
+
config.interactive = obj["interactive"];
|
|
25
|
+
}
|
|
20
26
|
return config;
|
|
21
27
|
}
|
package/dist/util/markdown.d.ts
CHANGED
|
@@ -21,4 +21,20 @@ export type SpecBlock = {
|
|
|
21
21
|
* the agent sees a clean "## goals", "## acceptance_criterion" structure.
|
|
22
22
|
*/
|
|
23
23
|
export declare function blocksToMarkdown(blocks: SpecBlock[]): string;
|
|
24
|
+
export type AttachmentRecord = {
|
|
25
|
+
id: string;
|
|
26
|
+
fileName: string;
|
|
27
|
+
fileSize: number;
|
|
28
|
+
mimeType: string;
|
|
29
|
+
status: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Render the spec's ready attachments as an "## Attachments" markdown section
|
|
33
|
+
* for the worker work context. Lists fileName — mimeType — pretty size only;
|
|
34
|
+
* the file CONTENT/bytes are never inlined (binary can't be, and no AC needs
|
|
35
|
+
* download). Callers must pass ONLY ready attachments — the server is the gate
|
|
36
|
+
* (the `?status=ready` filter), this renderer does not re-filter. Returns an
|
|
37
|
+
* empty string when there are none so `pull` can omit the section.
|
|
38
|
+
*/
|
|
39
|
+
export declare function attachmentsToMarkdown(attachments: AttachmentRecord[]): string;
|
|
24
40
|
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/util/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAmB1D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAqB1E;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACvC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CA+B5D"}
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/util/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAmB1D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAqB1E;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACvC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CA+B5D;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAmBF;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAO7E"}
|
package/dist/util/markdown.js
CHANGED
|
@@ -77,6 +77,40 @@ export function blocksToMarkdown(blocks) {
|
|
|
77
77
|
}
|
|
78
78
|
return out.join("\n").trimEnd();
|
|
79
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Render a human-readable byte size (e.g. 1536 → "1.5 KB"). Used for the
|
|
82
|
+
* attachments listing only — purely cosmetic.
|
|
83
|
+
*/
|
|
84
|
+
function prettySize(bytes) {
|
|
85
|
+
if (!Number.isFinite(bytes) || bytes < 0)
|
|
86
|
+
return `${bytes} B`;
|
|
87
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
88
|
+
let value = bytes;
|
|
89
|
+
let unit = 0;
|
|
90
|
+
while (value >= 1024 && unit < units.length - 1) {
|
|
91
|
+
value /= 1024;
|
|
92
|
+
unit += 1;
|
|
93
|
+
}
|
|
94
|
+
const rounded = unit === 0 ? value : Math.round(value * 10) / 10;
|
|
95
|
+
return `${rounded} ${units[unit]}`;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Render the spec's ready attachments as an "## Attachments" markdown section
|
|
99
|
+
* for the worker work context. Lists fileName — mimeType — pretty size only;
|
|
100
|
+
* the file CONTENT/bytes are never inlined (binary can't be, and no AC needs
|
|
101
|
+
* download). Callers must pass ONLY ready attachments — the server is the gate
|
|
102
|
+
* (the `?status=ready` filter), this renderer does not re-filter. Returns an
|
|
103
|
+
* empty string when there are none so `pull` can omit the section.
|
|
104
|
+
*/
|
|
105
|
+
export function attachmentsToMarkdown(attachments) {
|
|
106
|
+
if (attachments.length === 0)
|
|
107
|
+
return "";
|
|
108
|
+
const out = ["## Attachments", ""];
|
|
109
|
+
for (const a of attachments) {
|
|
110
|
+
out.push(`- ${a.fileName} — ${a.mimeType} — ${prettySize(a.fileSize)}`);
|
|
111
|
+
}
|
|
112
|
+
return out.join("\n");
|
|
113
|
+
}
|
|
80
114
|
function humanizeType(type) {
|
|
81
115
|
return type.split("_").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" ");
|
|
82
116
|
}
|