@opengeni/ogtool 0.3.31-canary.0 → 0.3.31-canary.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,7 +23,7 @@ to disk. `ogtool doctor` reports the selected delivery mode without printing the
23
23
 
24
24
  Commands:
25
25
 
26
- - `ogtool list` — a bounded page of callable paths and short descriptions, one tool per line
26
+ - `ogtool list` — all authorized callable paths and short descriptions, one tool per line
27
27
  - `ogtool list --json` — compact JSON with `catalogDigest`, `total`, `offset`, `nextOffset`, and `tools: [{path, description}]`
28
28
  - `ogtool list [--json] [--query <substring>] [--limit <1..100>] [--offset <integer>]`
29
29
  - `ogtool list --full` — the previous full catalog JSON, including identity and schemas
@@ -38,24 +38,25 @@ descriptions collapse whitespace and use at most 160 Unicode code points, includ
38
38
  an ellipsis when shortened; a missing/empty description falls back to the title.
39
39
  Text mode displays C0, C1, and DEL control characters as literal `\uNNNN` escapes
40
40
  so descriptions and title fallbacks cannot execute terminal control sequences.
41
- The byte budget includes this escape expansion. This is text-only presentation:
41
+ This is text-only presentation:
42
42
  catalog content, query matching, and explicit JSON/full/schema output remain unchanged.
43
43
  Catalog order and callable paths are preserved. Compact output contains no identities,
44
44
  schemas, approval annotations, or attempt IDs. JSON includes the frozen catalog digest
45
45
  so a machine caller can detect a changed catalog between pages.
46
46
 
47
- Compact pages default to at most 50 tools; `--limit` accepts 1 through 100. The complete
48
- stdout page, including JSON escaping, metadata, text continuation hints, and final
49
- newline, is at most 16 KiB. The CLI drops trailing entries until it fits, never
50
- truncates a callable path, and fails clearly if even one entry cannot fit. The
51
- catalog's maximum valid callable path fits this bound.
47
+ Both default text and `--json` list every authorized catalog entry. There is no
48
+ aggregate stdout byte cap and no default pagination: compactness comes from omitting
49
+ per-tool schemas and shortening summaries, never dropping tools or truncating paths.
50
+ For compatibility, `--limit` accepts 1 through 100 as a strictly opt-in row limit;
51
+ `--offset` alone returns all remaining matching tools. Count/offset metadata remains
52
+ available for callers that explicitly request a slice.
52
53
 
53
54
  `--query` is a literal, case-sensitive substring match against the callable path or
54
55
  full whitespace-normalized description (title fallback), including text beyond the
55
56
  displayed summary. An empty query matches all tools. `total` counts filtered matches;
56
57
  `--offset` is a nonnegative safe integer within that filtered order, not the unfiltered
57
- catalog. Follow the returned `nextOffset` rather than adding your requested limit:
58
- the byte cap may return fewer tools. Keep the query unchanged and verify the JSON
58
+ catalog. Follow the returned `nextOffset` when explicitly limiting rows.
59
+ Keep the query unchanged and verify the JSON
59
60
  `catalogDigest` is unchanged when walking pages. `nextOffset: null` means finished.
60
61
  Empty/no-match/past-end pages return no tools and no next offset; text still prints
61
62
  the total/offset footer. Both `--flag value` and `--flag=value` are supported.
@@ -15124,7 +15124,13 @@ class CodemodeClient {
15124
15124
  });
15125
15125
  return CodemodeOperation.parse(await response.json());
15126
15126
  }
15127
- async request(path, init) {
15127
+ async sessionRequest(path, init) {
15128
+ if (!path.startsWith("/v1/")) {
15129
+ throw new Error("Unsupported Site session API path");
15130
+ }
15131
+ return this.request(`/sdk${path}`, init, false);
15132
+ }
15133
+ async request(path, init, throwOnError = true) {
15128
15134
  const token = typeof this.options.token === "function" ? await this.options.token() : this.options.token;
15129
15135
  const response = await this.fetchImpl(`${this.baseUrl}${path}`, {
15130
15136
  ...init,
@@ -15133,7 +15139,7 @@ class CodemodeClient {
15133
15139
  authorization: `Bearer ${token}`
15134
15140
  }
15135
15141
  });
15136
- if (!response.ok) {
15142
+ if (!response.ok && throwOnError) {
15137
15143
  let message = `Codemode request failed with HTTP ${response.status}`;
15138
15144
  let errorOptions = {};
15139
15145
  try {
@@ -15269,7 +15275,7 @@ async function abortableDelay(delayMs, signal) {
15269
15275
  // package.json
15270
15276
  var package_default = {
15271
15277
  name: "@opengeni/ogtool",
15272
- version: "0.3.31-canary.0",
15278
+ version: "0.3.31-canary.2",
15273
15279
  description: "Codemode CLI and typed client entrypoint for an OpenGeni execution attempt.",
15274
15280
  license: "Apache-2.0",
15275
15281
  repository: {
@@ -15319,7 +15325,6 @@ var package_default = {
15319
15325
 
15320
15326
  // src/catalog-discovery.ts
15321
15327
  var DESCRIPTION_MAX_CHARS = 160;
15322
- var LIST_MAX_BYTES = 16 * 1024;
15323
15328
  function normalizedDescription(entry) {
15324
15329
  return (entry.description || entry.title || "").split(/\p{White_Space}+/u).filter(Boolean).join(" ");
15325
15330
  }
@@ -15332,7 +15337,7 @@ function terminalDescription(text) {
15332
15337
  return text.replace(/[\u0000-\u001f\u007f-\u009f]/gu, (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`);
15333
15338
  }
15334
15339
  function parseListOptions(args) {
15335
- const options = { full: false, json: false, query: "", limit: 50, offset: 0 };
15340
+ const options = { full: false, json: false, query: "", offset: 0 };
15336
15341
  const seen = new Set;
15337
15342
  const invalid = () => new Error("usage: ogtool list [--full | --json] [--query <substring>] [--limit <1..100>] [--offset <nonnegative integer>]");
15338
15343
  for (let index = 0;index < args.length; index++) {
@@ -15369,32 +15374,25 @@ function parseListOptions(args) {
15369
15374
  }
15370
15375
  function compactOutput(catalog, options) {
15371
15376
  const matches = catalog.entries.filter((entry) => entry.codemodePath.join(".").includes(options.query) || normalizedDescription(entry).includes(options.query));
15372
- const tools = matches.slice(options.offset, options.offset + options.limit).map((entry) => ({
15377
+ const tools = matches.slice(options.offset, options.limit === undefined ? undefined : options.offset + options.limit).map((entry) => ({
15373
15378
  path: entry.codemodePath.join("."),
15374
15379
  description: shortDescription(entry)
15375
15380
  }));
15376
15381
  const textLines = options.json ? [] : tools.map((tool) => `${tool.path}${tool.description ? ` — ${terminalDescription(tool.description)}` : ""}
15377
15382
  `);
15378
- for (;; ) {
15379
- const nextOffset = options.offset + tools.length < matches.length ? options.offset + tools.length : null;
15380
- const page = {
15381
- catalogDigest: catalog.digest,
15382
- total: matches.length,
15383
- offset: options.offset,
15384
- nextOffset,
15385
- tools
15386
- };
15387
- const output = options.json ? `${JSON.stringify(page)}
15388
- ` : textLines.slice(0, tools.length).join("") + `# total: ${page.total}; offset: ${page.offset}; nextOffset: ${nextOffset ?? "none"}
15383
+ const nextOffset = options.offset + tools.length < matches.length ? options.offset + tools.length : null;
15384
+ const page = {
15385
+ catalogDigest: catalog.digest,
15386
+ total: matches.length,
15387
+ offset: options.offset,
15388
+ nextOffset,
15389
+ tools
15390
+ };
15391
+ const output = options.json ? `${JSON.stringify(page)}
15392
+ ` : textLines.join("") + `# total: ${page.total}; offset: ${page.offset}; nextOffset: ${nextOffset ?? "none"}
15389
15393
  ` + (nextOffset === null ? "" : `# Continue with --offset ${nextOffset} (keep the same --query and --limit).
15390
15394
  `);
15391
- if (Buffer.byteLength(output, "utf8") <= LIST_MAX_BYTES)
15392
- return output;
15393
- if (tools.length <= 1) {
15394
- throw new Error("One tool exceeds the 16384-byte compact page limit; use list --full redirected to a file");
15395
- }
15396
- tools.pop();
15397
- }
15395
+ return output;
15398
15396
  }
15399
15397
 
15400
15398
  // src/cli.ts
@@ -15411,6 +15409,8 @@ function usage(exitCode = 1) {
15411
15409
  " ogtool doctor",
15412
15410
  " ogtool --version",
15413
15411
  "",
15412
+ "list returns all authorized tools by default; --limit/--offset are opt-in slices",
15413
+ "",
15414
15414
  "requires OPENGENI_CODEMODE_URL and OPENGENI_CODEMODE_TOKEN or OPENGENI_CODEMODE_TOKEN_FILE"
15415
15415
  ].join(`
15416
15416
  `);
@@ -4,9 +4,9 @@ export type ListOptions = {
4
4
  full: boolean;
5
5
  json: boolean;
6
6
  query: string;
7
- limit: number;
7
+ limit?: number;
8
8
  offset: number;
9
9
  };
10
10
  export declare function parseListOptions(args: string[]): ListOptions;
11
- /** Render first, then emit: the bound includes metadata, escaping, hints, and newline. */
11
+ /** Compact per tool, never truncate the authorized catalog to an output budget. */
12
12
  export declare function compactOutput(catalog: AttemptToolCatalog, options: ListOptions): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/ogtool",
3
- "version": "0.3.31-canary.0",
3
+ "version": "0.3.31-canary.2",
4
4
  "description": "Codemode CLI and typed client entrypoint for an OpenGeni execution attempt.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -37,7 +37,7 @@
37
37
  "prepublishOnly": "bash ../../scripts/prepublish-guard"
38
38
  },
39
39
  "dependencies": {
40
- "@opengeni/codemode": "^0.4.27-canary.0"
40
+ "@opengeni/codemode": "^0.4.27-canary.2"
41
41
  },
42
42
  "engines": {
43
43
  "node": ">=18"
@@ -1,7 +1,6 @@
1
1
  import type { AttemptToolCatalog, AttemptToolCatalogEntry } from "@opengeni/codemode";
2
2
 
3
3
  const DESCRIPTION_MAX_CHARS = 160;
4
- const LIST_MAX_BYTES = 16 * 1024;
5
4
 
6
5
  function normalizedDescription(entry: AttemptToolCatalogEntry): string {
7
6
  return (entry.description || entry.title || "")
@@ -30,12 +29,12 @@ export type ListOptions = {
30
29
  full: boolean;
31
30
  json: boolean;
32
31
  query: string;
33
- limit: number;
32
+ limit?: number;
34
33
  offset: number;
35
34
  };
36
35
 
37
36
  export function parseListOptions(args: string[]): ListOptions {
38
- const options: ListOptions = { full: false, json: false, query: "", limit: 50, offset: 0 };
37
+ const options: ListOptions = { full: false, json: false, query: "", offset: 0 };
39
38
  const seen = new Set<string>();
40
39
  const invalid = () =>
41
40
  new Error(
@@ -66,46 +65,40 @@ export function parseListOptions(args: string[]): ListOptions {
66
65
  return options;
67
66
  }
68
67
 
69
- /** Render first, then emit: the bound includes metadata, escaping, hints, and newline. */
68
+ /** Compact per tool, never truncate the authorized catalog to an output budget. */
70
69
  export function compactOutput(catalog: AttemptToolCatalog, options: ListOptions): string {
71
70
  const matches = catalog.entries.filter(
72
71
  (entry) =>
73
72
  entry.codemodePath.join(".").includes(options.query) ||
74
73
  normalizedDescription(entry).includes(options.query),
75
74
  );
76
- const tools = matches.slice(options.offset, options.offset + options.limit).map((entry) => ({
77
- path: entry.codemodePath.join("."),
78
- description: shortDescription(entry),
79
- }));
75
+ const tools = matches
76
+ .slice(options.offset, options.limit === undefined ? undefined : options.offset + options.limit)
77
+ .map((entry) => ({
78
+ path: entry.codemodePath.join("."),
79
+ description: shortDescription(entry),
80
+ }));
80
81
  const textLines = options.json
81
82
  ? []
82
83
  : tools.map(
83
84
  (tool) =>
84
85
  `${tool.path}${tool.description ? ` — ${terminalDescription(tool.description)}` : ""}\n`,
85
86
  );
86
- for (;;) {
87
- const nextOffset =
88
- options.offset + tools.length < matches.length ? options.offset + tools.length : null;
89
- const page = {
90
- catalogDigest: catalog.digest,
91
- total: matches.length,
92
- offset: options.offset,
93
- nextOffset,
94
- tools,
95
- };
96
- const output = options.json
97
- ? `${JSON.stringify(page)}\n`
98
- : textLines.slice(0, tools.length).join("") +
99
- `# total: ${page.total}; offset: ${page.offset}; nextOffset: ${nextOffset ?? "none"}\n` +
100
- (nextOffset === null
101
- ? ""
102
- : `# Continue with --offset ${nextOffset} (keep the same --query and --limit).\n`);
103
- if (Buffer.byteLength(output, "utf8") <= LIST_MAX_BYTES) return output;
104
- if (tools.length <= 1) {
105
- throw new Error(
106
- "One tool exceeds the 16384-byte compact page limit; use list --full redirected to a file",
107
- );
108
- }
109
- tools.pop();
110
- }
87
+ const nextOffset =
88
+ options.offset + tools.length < matches.length ? options.offset + tools.length : null;
89
+ const page = {
90
+ catalogDigest: catalog.digest,
91
+ total: matches.length,
92
+ offset: options.offset,
93
+ nextOffset,
94
+ tools,
95
+ };
96
+ const output = options.json
97
+ ? `${JSON.stringify(page)}\n`
98
+ : textLines.join("") +
99
+ `# total: ${page.total}; offset: ${page.offset}; nextOffset: ${nextOffset ?? "none"}\n` +
100
+ (nextOffset === null
101
+ ? ""
102
+ : `# Continue with --offset ${nextOffset} (keep the same --query and --limit).\n`);
103
+ return output;
111
104
  }
package/src/cli.ts CHANGED
@@ -23,6 +23,8 @@ function usage(exitCode = 1): void {
23
23
  " ogtool doctor",
24
24
  " ogtool --version",
25
25
  "",
26
+ "list returns all authorized tools by default; --limit/--offset are opt-in slices",
27
+ "",
26
28
  "requires OPENGENI_CODEMODE_URL and OPENGENI_CODEMODE_TOKEN or OPENGENI_CODEMODE_TOKEN_FILE",
27
29
  ].join("\n");
28
30
  (exitCode === 0 ? process.stdout : process.stderr).write(`${output}\n`);