agent-readable-ts 0.1.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/LICENSE +21 -0
- package/README.md +551 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +80 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/index.d.ts +33 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +87 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/model.d.ts +60 -0
- package/dist/src/model.d.ts.map +1 -0
- package/dist/src/model.js +426 -0
- package/dist/src/model.js.map +1 -0
- package/dist/src/packages.d.ts +33 -0
- package/dist/src/packages.d.ts.map +1 -0
- package/dist/src/packages.js +201 -0
- package/dist/src/packages.js.map +1 -0
- package/dist/src/protocol.d.ts +21 -0
- package/dist/src/protocol.d.ts.map +1 -0
- package/dist/src/protocol.js +21 -0
- package/dist/src/protocol.js.map +1 -0
- package/dist/src/render.d.ts +19 -0
- package/dist/src/render.d.ts.map +1 -0
- package/dist/src/render.js +45 -0
- package/dist/src/render.js.map +1 -0
- package/dist/src/source-types.d.ts +9 -0
- package/dist/src/source-types.d.ts.map +1 -0
- package/dist/src/source-types.js +298 -0
- package/dist/src/source-types.js.map +1 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 zydo and other agent-readable-ts contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
# agent-readable-ts
|
|
2
|
+
|
|
3
|
+
Coding agents hallucinate a library's API — inventing methods, using stale signatures, or misusing real methods because the correct usage rules (lifecycle order, preconditions, anti-patterns) are not visible from the API surface alone.
|
|
4
|
+
|
|
5
|
+
`agent-readable-ts` lets a library author attach those rules next to a class, object, or function. A package-level function `agentHelp(target)` returns curated, agent-oriented Markdown: the real public runtime surface that can be discovered safely, plus any author-supplied behavioral rules. An agent that calls `agentHelp(target)` before writing code against the target sees the real callable surface and the right usage rules.
|
|
6
|
+
|
|
7
|
+
> **For coding agents:** Install the agent skill to have this run automatically before coding against unfamiliar packages:
|
|
8
|
+
> ```sh
|
|
9
|
+
> npx skills add zydo/skills --skill agent-readable
|
|
10
|
+
> ```
|
|
11
|
+
|
|
12
|
+
**Token efficiency.** When an agent hallucinates an API, the resulting code fails — and each failed attempt triggers a retry cycle that burns tokens without making progress. `agent-readable-ts` generates compact, precise, accurate descriptions of publicly exposed interfaces (verified by runtime introspection on live packages). Calling `npx agent-readable-ts <package>` on unfamiliar packages and classes *before* writing code surfaces the real API upfront, preventing that waste.
|
|
13
|
+
|
|
14
|
+
## Other languages
|
|
15
|
+
|
|
16
|
+
- **Python:** [agent-readable](https://github.com/zydo/agent-readable) — same idea for Python packages and classes.
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
npm install agent-readable-ts
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## CLI
|
|
25
|
+
|
|
26
|
+
The package includes a CLI for generating documentation from the command line. It works with local files **and installed npm packages**.
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
npx agent-readable-ts commander # list all exports
|
|
30
|
+
npx agent-readable-ts commander:Command # document a specific export
|
|
31
|
+
npx agent-readable-ts ./src/widget.ts:Widget # a local TypeScript file
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Usage
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
agent-readable-ts <package-name>[:<export-name>]
|
|
38
|
+
agent-readable-ts <module-path>[:<export-name>]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- **`package-name`** — any installed npm package (e.g. `commander`, `pino`, `@scope/package`)
|
|
42
|
+
- **`module-path`** — a file path (`.js`, `.mjs`, or `.ts`) relative to the current directory
|
|
43
|
+
- **`export-name`** — the named export to document (use dots for nested access, e.g. `Things.Helper`)
|
|
44
|
+
|
|
45
|
+
If no export name is given for a **package**, all exports are listed. If no export name is given for a **file**, the module namespace object is documented.
|
|
46
|
+
|
|
47
|
+
> `.ts` files require `tsx` to be installed. It is included as a devDependency, and `npx` resolves it automatically.
|
|
48
|
+
|
|
49
|
+
### Examples
|
|
50
|
+
|
|
51
|
+
List all exports from an installed package:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
npm install commander
|
|
55
|
+
npx agent-readable-ts commander
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Output:
|
|
59
|
+
|
|
60
|
+
```markdown
|
|
61
|
+
# commander
|
|
62
|
+
|
|
63
|
+
## Exports
|
|
64
|
+
|
|
65
|
+
- `CommanderError` class
|
|
66
|
+
- `InvalidArgumentError` class
|
|
67
|
+
- `Argument` class
|
|
68
|
+
- `Option` class
|
|
69
|
+
- `Help` class
|
|
70
|
+
- `Command` class
|
|
71
|
+
- `createCommand(name: string): Command` function
|
|
72
|
+
- `createOption(flags: string, description: string): Option` function
|
|
73
|
+
- `createArgument(name: string, description: string): Argument` function
|
|
74
|
+
- `program` object
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Document a specific export with full type signatures:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
npx agent-readable-ts commander:Command
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Output:
|
|
84
|
+
|
|
85
|
+
```markdown
|
|
86
|
+
# Command
|
|
87
|
+
|
|
88
|
+
## Public API
|
|
89
|
+
|
|
90
|
+
- `action(fn: (this: this, ...args: any[]) => void | Promise<void>): this` method
|
|
91
|
+
- `addArgument(arg: Argument): this` method
|
|
92
|
+
- `addCommand(cmd: Command, opts: CommandOptions): this` method
|
|
93
|
+
- `addOption(option: Option): this` method
|
|
94
|
+
- `alias(): string` method
|
|
95
|
+
- `argument(name: string, description: string, defaultValue: unknown): this` method
|
|
96
|
+
- `command(nameAndArgs: string, description: string, opts: ExecutableCommandOptions): this` method
|
|
97
|
+
- `description(): string` method
|
|
98
|
+
- `error(message: string, errorOptions: ErrorOptions): never` method
|
|
99
|
+
- `hook(event: HookEvent, listener: (...args: any[]) => void | Promise<void>): this` method
|
|
100
|
+
- `option(flags: string, description: string, defaultValue: unknown): this` method
|
|
101
|
+
- `parse(argv: readonly string[], parseOptions: ParseOptions): this` method
|
|
102
|
+
- `parseAsync(argv: readonly string[], parseOptions: ParseOptions): Promise<this>` method
|
|
103
|
+
- `requiredOption(flags: string, description: string, defaultValue: unknown): this` method
|
|
104
|
+
- `version(str: string, flags: string, description: string): this` method
|
|
105
|
+
- ... (80+ methods total)
|
|
106
|
+
|
|
107
|
+
## Agent usage rules
|
|
108
|
+
|
|
109
|
+
- Prefer the public API listed above.
|
|
110
|
+
- Do not use private, protected, underscored, or internal members.
|
|
111
|
+
- Do not invent unsupported behavior.
|
|
112
|
+
- If usage is ambiguous, prefer the simplest documented usage pattern.
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Document a local file:
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
npx agent-readable-ts ./src/widget.ts:Widget # a class export
|
|
119
|
+
npx agent-readable-ts ./src/util.ts:connect # a function export
|
|
120
|
+
npx agent-readable-ts ./dist/api.js:fetch # a .js file with adjacent api.d.ts
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Two protocols
|
|
124
|
+
|
|
125
|
+
| Protocol | Role | Output behavior |
|
|
126
|
+
| -------------- | ----------------- | ------------------------------------------------ |
|
|
127
|
+
| `agentHelp()` | Full replacement | Returned Markdown is used verbatim |
|
|
128
|
+
| `agentNotes()` | Additive guidance | Notes are appended after auto-generated API docs |
|
|
129
|
+
|
|
130
|
+
### `agentHelp()` — Full replacement
|
|
131
|
+
|
|
132
|
+
If a target implements `agentHelp()`, the returned string **is** the output verbatim. No auto-generated sections are added.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { AgentHelper, agentHelp } from "agent-readable-ts";
|
|
136
|
+
|
|
137
|
+
class RateLimiter implements AgentHelper {
|
|
138
|
+
agentHelp(): string {
|
|
139
|
+
return `# RateLimiter
|
|
140
|
+
|
|
141
|
+
## Usage
|
|
142
|
+
|
|
143
|
+
- Create with \`new RateLimiter(maxRequests)\`.
|
|
144
|
+
- Call \`acquire()\` before making a request.
|
|
145
|
+
- Call \`release()\` after the request completes.
|
|
146
|
+
|
|
147
|
+
## Limits
|
|
148
|
+
|
|
149
|
+
- Default max is 100 concurrent requests.
|
|
150
|
+
- Exceeding the limit blocks until a slot opens.
|
|
151
|
+
`;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
console.log(agentHelp(new RateLimiter()));
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Output:
|
|
159
|
+
|
|
160
|
+
```markdown
|
|
161
|
+
# RateLimiter
|
|
162
|
+
|
|
163
|
+
## Usage
|
|
164
|
+
|
|
165
|
+
- Create with `new RateLimiter(maxRequests)`.
|
|
166
|
+
- Call `acquire()` before making a request.
|
|
167
|
+
- Call `release()` after the request completes.
|
|
168
|
+
|
|
169
|
+
## Limits
|
|
170
|
+
|
|
171
|
+
- Default max is 100 concurrent requests.
|
|
172
|
+
- Exceeding the limit blocks until a slot opens.
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
If the target also defines `agentNotes()`, a warning is written to stderr and the notes are dropped.
|
|
176
|
+
|
|
177
|
+
### `agentNotes()` — Additive guidance
|
|
178
|
+
|
|
179
|
+
Define `agentNotes()` on any class to append usage rules to the auto-generated documentation. Notes accumulate across the inheritance chain in parent-to-child order.
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { AgentNoter, agentHelp } from "agent-readable-ts";
|
|
183
|
+
|
|
184
|
+
class Sensor {
|
|
185
|
+
calibrate(offset: number): void {}
|
|
186
|
+
read(): number {
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
agentNotes(): string {
|
|
191
|
+
return `
|
|
192
|
+
## Do
|
|
193
|
+
|
|
194
|
+
- Call \`calibrate()\` once during setup, before \`read()\`.
|
|
195
|
+
|
|
196
|
+
## Do not
|
|
197
|
+
|
|
198
|
+
- Do not call \`read()\` before \`calibrate()\` on first use.
|
|
199
|
+
`;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
console.log(agentHelp(new Sensor()));
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `agentHelp(target)` entry point
|
|
207
|
+
|
|
208
|
+
The single entry point accepts:
|
|
209
|
+
|
|
210
|
+
- Class constructors
|
|
211
|
+
- Class instances
|
|
212
|
+
- Plain objects
|
|
213
|
+
- Plain functions
|
|
214
|
+
- Arrow functions
|
|
215
|
+
- Bound method values
|
|
216
|
+
- Callable objects
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
import { agentHelp } from "agent-readable-ts";
|
|
220
|
+
|
|
221
|
+
agentHelp(MyClass); // class constructor
|
|
222
|
+
agentHelp(new MyClass()); // class instance
|
|
223
|
+
agentHelp({ a: 1 }); // plain object
|
|
224
|
+
agentHelp(myFunction); // function
|
|
225
|
+
agentHelp(obj.method.bind(obj)); // bound method
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Examples
|
|
229
|
+
|
|
230
|
+
### Example 1: Wrapping a class you do not own
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { agentHelp } from "agent-readable-ts";
|
|
234
|
+
|
|
235
|
+
class Client {
|
|
236
|
+
connect(url: string): void {}
|
|
237
|
+
query(sql: string): unknown {
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
class DocumentedClient extends Client {
|
|
243
|
+
agentNotes(): string {
|
|
244
|
+
return `
|
|
245
|
+
## Do
|
|
246
|
+
|
|
247
|
+
- Call \`connect()\` before \`query()\`.
|
|
248
|
+
|
|
249
|
+
## Do not
|
|
250
|
+
|
|
251
|
+
- Do not pass untrusted SQL directly to \`query()\`.
|
|
252
|
+
`;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
console.log(agentHelp(new DocumentedClient()));
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Output:
|
|
260
|
+
|
|
261
|
+
```markdown
|
|
262
|
+
# DocumentedClient
|
|
263
|
+
|
|
264
|
+
## Public API
|
|
265
|
+
|
|
266
|
+
- `connect(url)` method
|
|
267
|
+
- `query(sql)` method
|
|
268
|
+
|
|
269
|
+
## Agent usage rules
|
|
270
|
+
|
|
271
|
+
- Prefer the public API listed above.
|
|
272
|
+
- Do not use private, protected, underscored, or internal members.
|
|
273
|
+
- Do not invent unsupported behavior.
|
|
274
|
+
- If usage is ambiguous, prefer the simplest documented usage pattern.
|
|
275
|
+
|
|
276
|
+
## Notes from DocumentedClient
|
|
277
|
+
|
|
278
|
+
## Do
|
|
279
|
+
|
|
280
|
+
- Call `connect()` before `query()`.
|
|
281
|
+
|
|
282
|
+
## Do not
|
|
283
|
+
|
|
284
|
+
- Do not pass untrusted SQL directly to `query()`.
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Example 2: Inheritance with accumulated notes
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
import { agentHelp } from "agent-readable-ts";
|
|
291
|
+
|
|
292
|
+
class Sensor {
|
|
293
|
+
calibrate(offset: number): void {}
|
|
294
|
+
read(): number {
|
|
295
|
+
return 0;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
agentNotes(): string {
|
|
299
|
+
return `
|
|
300
|
+
## Do
|
|
301
|
+
|
|
302
|
+
- Call \`calibrate()\` once during setup, before \`read()\`.
|
|
303
|
+
|
|
304
|
+
## Do not
|
|
305
|
+
|
|
306
|
+
- Do not call \`read()\` before \`calibrate()\` on first use.
|
|
307
|
+
`;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
class CalibratedSensor extends Sensor {
|
|
312
|
+
reset(): void {}
|
|
313
|
+
|
|
314
|
+
override agentNotes(): string {
|
|
315
|
+
return `
|
|
316
|
+
## Do
|
|
317
|
+
|
|
318
|
+
- Use \`reset()\` only when recalibration is required.
|
|
319
|
+
|
|
320
|
+
## Do not
|
|
321
|
+
|
|
322
|
+
- Do not call \`reset()\` in the hot read path.
|
|
323
|
+
`;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
console.log(agentHelp(new CalibratedSensor()));
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Output:
|
|
331
|
+
|
|
332
|
+
```markdown
|
|
333
|
+
# CalibratedSensor
|
|
334
|
+
|
|
335
|
+
## Public API
|
|
336
|
+
|
|
337
|
+
- `calibrate(offset)` method
|
|
338
|
+
- `read()` method
|
|
339
|
+
- `reset()` method
|
|
340
|
+
|
|
341
|
+
## Agent usage rules
|
|
342
|
+
|
|
343
|
+
- Prefer the public API listed above.
|
|
344
|
+
- Do not use private, protected, underscored, or internal members.
|
|
345
|
+
- Do not invent unsupported behavior.
|
|
346
|
+
- If usage is ambiguous, prefer the simplest documented usage pattern.
|
|
347
|
+
|
|
348
|
+
## Notes from Sensor
|
|
349
|
+
|
|
350
|
+
## Do
|
|
351
|
+
|
|
352
|
+
- Call `calibrate()` once during setup, before `read()`.
|
|
353
|
+
|
|
354
|
+
## Do not
|
|
355
|
+
|
|
356
|
+
- Do not call `read()` before `calibrate()` on first use.
|
|
357
|
+
|
|
358
|
+
## Notes from CalibratedSensor (extends Sensor; if notes conflict, these take precedence)
|
|
359
|
+
|
|
360
|
+
## Do
|
|
361
|
+
|
|
362
|
+
- Use `reset()` only when recalibration is required.
|
|
363
|
+
|
|
364
|
+
## Do not
|
|
365
|
+
|
|
366
|
+
- Do not call `reset()` in the hot read path.
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Example 3: Full control via `agentHelp()`
|
|
370
|
+
|
|
371
|
+
```ts
|
|
372
|
+
import { agentHelp } from "agent-readable-ts";
|
|
373
|
+
|
|
374
|
+
class RateLimiter {
|
|
375
|
+
agentHelp(): string {
|
|
376
|
+
return `# RateLimiter
|
|
377
|
+
|
|
378
|
+
## Usage
|
|
379
|
+
|
|
380
|
+
- Create with \`new RateLimiter(maxRequests)\`.
|
|
381
|
+
- Call \`acquire()\` before making a request.
|
|
382
|
+
- Call \`release()\` after the request completes.
|
|
383
|
+
|
|
384
|
+
## Limits
|
|
385
|
+
|
|
386
|
+
- Default max is 100 concurrent requests.
|
|
387
|
+
- Exceeding the limit blocks until a slot opens.
|
|
388
|
+
`;
|
|
389
|
+
}
|
|
390
|
+
agentNotes(): string {
|
|
391
|
+
return "This is ignored because agentHelp() owns the full output.";
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
console.log(agentHelp(new RateLimiter()));
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Output:
|
|
399
|
+
|
|
400
|
+
```markdown
|
|
401
|
+
# RateLimiter
|
|
402
|
+
|
|
403
|
+
## Usage
|
|
404
|
+
|
|
405
|
+
- Create with `new RateLimiter(maxRequests)`.
|
|
406
|
+
- Call `acquire()` before making a request.
|
|
407
|
+
- Call `release()` after the request completes.
|
|
408
|
+
|
|
409
|
+
## Limits
|
|
410
|
+
|
|
411
|
+
- Default max is 100 concurrent requests.
|
|
412
|
+
- Exceeding the limit blocks until a slot opens.
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
A warning is written to stderr noting that `agentNotes()` is ignored.
|
|
416
|
+
|
|
417
|
+
### Example 4: Any class, no setup
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
import { agentHelp } from "agent-readable-ts";
|
|
421
|
+
|
|
422
|
+
class Cache {
|
|
423
|
+
get(key: string): unknown {
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
set(key: string, value: unknown): void {}
|
|
427
|
+
clear(): void {}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
console.log(agentHelp(new Cache()));
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Output:
|
|
434
|
+
|
|
435
|
+
```markdown
|
|
436
|
+
# Cache
|
|
437
|
+
|
|
438
|
+
## Public API
|
|
439
|
+
|
|
440
|
+
- `clear()` method
|
|
441
|
+
- `get(key)` method
|
|
442
|
+
- `set(key, value)` method
|
|
443
|
+
|
|
444
|
+
## Agent usage rules
|
|
445
|
+
|
|
446
|
+
- Prefer the public API listed above.
|
|
447
|
+
- Do not use private, protected, underscored, or internal members.
|
|
448
|
+
- Do not invent unsupported behavior.
|
|
449
|
+
- If usage is ambiguous, prefer the simplest documented usage pattern.
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Example 5: Functions and bound methods
|
|
453
|
+
|
|
454
|
+
```ts
|
|
455
|
+
import { agentHelp } from "agent-readable-ts";
|
|
456
|
+
|
|
457
|
+
function connect(host: string, port: number): void {}
|
|
458
|
+
|
|
459
|
+
class Runner {
|
|
460
|
+
execute(command: string): number {
|
|
461
|
+
return 0;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const runner = new Runner();
|
|
466
|
+
|
|
467
|
+
console.log(agentHelp(connect));
|
|
468
|
+
console.log(agentHelp(runner.execute.bind(runner)));
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
Output for `connect`:
|
|
472
|
+
|
|
473
|
+
````markdown
|
|
474
|
+
# connect
|
|
475
|
+
|
|
476
|
+
## Signature
|
|
477
|
+
|
|
478
|
+
```ts
|
|
479
|
+
connect(host, port)
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
## Agent usage rules
|
|
483
|
+
|
|
484
|
+
- Call this function according to the signature above.
|
|
485
|
+
- Do not invent unsupported parameters, return values, side effects, or lifecycle behavior.
|
|
486
|
+
- Do not use private, underscored, or internal implementation details.
|
|
487
|
+
- If usage is ambiguous, prefer the simplest documented usage pattern.
|
|
488
|
+
````
|
|
489
|
+
|
|
490
|
+
Output for the bound method:
|
|
491
|
+
|
|
492
|
+
````markdown
|
|
493
|
+
# execute
|
|
494
|
+
|
|
495
|
+
## Signature
|
|
496
|
+
|
|
497
|
+
```ts
|
|
498
|
+
execute(arg0)
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
## Agent usage rules
|
|
502
|
+
|
|
503
|
+
- Call this function according to the signature above.
|
|
504
|
+
- Do not invent unsupported parameters, return values, side effects, or lifecycle behavior.
|
|
505
|
+
- Do not use private, underscored, or internal implementation details.
|
|
506
|
+
- If usage is ambiguous, prefer the simplest documented usage pattern.
|
|
507
|
+
````
|
|
508
|
+
|
|
509
|
+
## Warning output
|
|
510
|
+
|
|
511
|
+
By default, advisory warnings are written to `process.stderr`. You can redirect or silence them:
|
|
512
|
+
|
|
513
|
+
```ts
|
|
514
|
+
import { setWarnOutput, getWarnOutput } from "agent-readable-ts";
|
|
515
|
+
|
|
516
|
+
// Redirect to a custom sink
|
|
517
|
+
setWarnOutput((chunk: string) => {
|
|
518
|
+
console.log("[WARN]", chunk.trim());
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
// Or use an object with a write method
|
|
522
|
+
setWarnOutput({ write(chunk: string) { /* handle */ } });
|
|
523
|
+
|
|
524
|
+
// Silence warnings
|
|
525
|
+
setWarnOutput(null);
|
|
526
|
+
|
|
527
|
+
// Restore default
|
|
528
|
+
setWarnOutput(process.stderr);
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
## Limitations in TypeScript
|
|
532
|
+
|
|
533
|
+
Runtime JavaScript reflection cannot read TypeScript type annotations, interfaces, overloads, generic parameters, return types, or doc comments. The auto-generated documentation is intentionally conservative:
|
|
534
|
+
|
|
535
|
+
- **Parameter names** are recovered from `Function.prototype.toString()` when possible. For native or bound functions, names fall back to `arg0`, `arg1`, etc. using `Function.length`. Destructured parameters also fall back to `argN`.
|
|
536
|
+
- **Type information** is available in two ways:
|
|
537
|
+
- **CLI with `.ts` source**: full types are extracted by parsing the source file with the TypeScript compiler API.
|
|
538
|
+
- **CLI with `.js`/`.mjs`/`.cjs` files**: types are extracted from adjacent `.d.ts`/`.d.mts`/`.d.cts` declaration files if present (covers published packages).
|
|
539
|
+
- **Library API (`agentHelp()`)**: no type information — only runtime parameter names and arity.
|
|
540
|
+
- **No per-method descriptions.** Authors convey prose through `agentNotes()` or by implementing `agentHelp()`.
|
|
541
|
+
- **Constructors are not invoked** during introspection. Construction guidance belongs in notes.
|
|
542
|
+
- **Instance fields** can only be discovered from an actual instance or plain object, not from a class constructor.
|
|
543
|
+
- **Getters are not invoked** during introspection.
|
|
544
|
+
- **TypeScript `private` and `protected`** are compile-time constructs. The library excludes names starting with `_` but cannot perfectly detect visibility at runtime.
|
|
545
|
+
- **JavaScript `#private` fields and methods** are not reflectable and never appear in output.
|
|
546
|
+
- **Module-level documentation** is not supported.
|
|
547
|
+
- **Dynamic package import or CLI-based introspection** is intentionally omitted.
|
|
548
|
+
|
|
549
|
+
## License
|
|
550
|
+
|
|
551
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { agentHelp } from "./index.js";
|
|
3
|
+
import { resolvePackageTypesPath, listPackageExports } from "./source-types.js";
|
|
4
|
+
import { parseSpecifier, isBarePackageName, splitPackageSpec, walkExportPath, loadTypeSigs, formatExportList, loadPackage, } from "./packages.js";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
function usage() {
|
|
9
|
+
process.stderr.write("Usage: agent-readable-ts <module-path>[:<export-name>]\n" +
|
|
10
|
+
" agent-readable-ts <package-name>[:<export-name>]\n");
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
function fail(message) {
|
|
14
|
+
process.stderr.write(`Error: ${message}\n`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
// ── helpers ────────────────────────────────────────────────────────────────────
|
|
18
|
+
/** Extract the leaf name from a dotted export path for type-signature lookup. */
|
|
19
|
+
function leafName(exportName) {
|
|
20
|
+
if (!exportName)
|
|
21
|
+
return null;
|
|
22
|
+
const lastDot = exportName.lastIndexOf(".");
|
|
23
|
+
return lastDot >= 0 ? exportName.slice(lastDot + 1) : exportName;
|
|
24
|
+
}
|
|
25
|
+
// ── file-based handling ────────────────────────────────────────────────────────
|
|
26
|
+
async function handleFile(modulePath, exportName) {
|
|
27
|
+
const absolutePath = resolve(process.cwd(), modulePath);
|
|
28
|
+
const fileUrl = pathToFileURL(absolutePath).href;
|
|
29
|
+
let mod;
|
|
30
|
+
try {
|
|
31
|
+
mod = (await import(fileUrl));
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
fail(`Cannot import "${modulePath}": ${err instanceof Error ? err.message : String(err)}`);
|
|
35
|
+
}
|
|
36
|
+
const target = exportName ? walkExportPath(mod, exportName) : mod;
|
|
37
|
+
const typeSigs = loadTypeSigs(absolutePath, leafName(exportName));
|
|
38
|
+
process.stdout.write(agentHelp(target, typeSigs));
|
|
39
|
+
}
|
|
40
|
+
// ── package-based handling ─────────────────────────────────────────────────────
|
|
41
|
+
async function handlePackage(spec, exportName) {
|
|
42
|
+
const { name } = splitPackageSpec(spec);
|
|
43
|
+
const { mod, typesDir } = await loadPackage(spec);
|
|
44
|
+
const dtsPath = resolvePackageTypesPath(name, typesDir);
|
|
45
|
+
// No export name: list all exports
|
|
46
|
+
if (!exportName) {
|
|
47
|
+
if (!dtsPath) { /* node:coverage disable */
|
|
48
|
+
// A loadable package always resolves a TypeScript-visible entry (JS counts as a fallback).
|
|
49
|
+
fail(`No type declarations found for "${name}". Try a specific export, e.g. "${name}:SomeExport".`);
|
|
50
|
+
} /* node:coverage enable */
|
|
51
|
+
const dtsSource = readFileSync(dtsPath, "utf-8");
|
|
52
|
+
const exports = listPackageExports(dtsSource, dtsPath);
|
|
53
|
+
if (exports.length === 0)
|
|
54
|
+
fail(`No exports found in "${name}".`);
|
|
55
|
+
const typeSigs = loadTypeSigs(dtsPath, null);
|
|
56
|
+
process.stdout.write(formatExportList(name, exports, typeSigs));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// Specific export: walk and document
|
|
60
|
+
const target = walkExportPath(mod, exportName);
|
|
61
|
+
const typeSigs = dtsPath ? loadTypeSigs(dtsPath, leafName(exportName)) : undefined;
|
|
62
|
+
process.stdout.write(agentHelp(target, typeSigs));
|
|
63
|
+
}
|
|
64
|
+
// ── main ───────────────────────────────────────────────────────────────────────
|
|
65
|
+
const specifier = process.argv[2];
|
|
66
|
+
if (!specifier)
|
|
67
|
+
usage();
|
|
68
|
+
try {
|
|
69
|
+
const { modulePath, exportName } = parseSpecifier(specifier);
|
|
70
|
+
if (isBarePackageName(modulePath)) {
|
|
71
|
+
await handlePackage(modulePath, exportName);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
await handleFile(modulePath, exportName);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-readable-ts
|
|
3
|
+
*
|
|
4
|
+
* Attach agent-oriented documentation to any class, object, or function.
|
|
5
|
+
* Coding agents call `agentHelp(target)` to see the real callable surface
|
|
6
|
+
* and author-supplied behavioral rules before writing code against the target.
|
|
7
|
+
*
|
|
8
|
+
* This module is the orchestrator: it handles the `AgentHelper` full-replacement
|
|
9
|
+
* path and the advisory warning sink, then delegates to `model.ts` (extraction
|
|
10
|
+
* into a format-neutral `HelpDoc`) and `render.ts` (Markdown rendering).
|
|
11
|
+
*/
|
|
12
|
+
import type { TypeSignatureMap } from "./model.js";
|
|
13
|
+
export type { AgentHelper, AgentNoter } from "./protocol.js";
|
|
14
|
+
export type { ParamTypeInfo, MethodTypeSignature, TypeSignatureMap } from "./model.js";
|
|
15
|
+
export type { HelpDoc, HelpMember, HelpNote } from "./model.js";
|
|
16
|
+
/** A sink for advisory warnings. */
|
|
17
|
+
export type WarningSink = {
|
|
18
|
+
write(chunk: string): unknown;
|
|
19
|
+
} | ((chunk: string) => unknown);
|
|
20
|
+
/** Replace the advisory warning sink. Pass `null` to silence warnings. */
|
|
21
|
+
export declare function setWarnOutput(sink: WarningSink | null): void;
|
|
22
|
+
/** Return the current advisory warning sink. */
|
|
23
|
+
export declare function getWarnOutput(): WarningSink | null;
|
|
24
|
+
/**
|
|
25
|
+
* Return agent-oriented help for a class constructor, class instance,
|
|
26
|
+
* plain object, function, arrow function, bound method, or callable object.
|
|
27
|
+
*
|
|
28
|
+
* If the target implements `AgentHelper.agentHelp()`, the returned string is
|
|
29
|
+
* used verbatim. Otherwise auto-generated documentation is produced from
|
|
30
|
+
* safe runtime introspection, with any `AgentNoter.agentNotes()` appended.
|
|
31
|
+
*/
|
|
32
|
+
export declare function agentHelp(target: unknown, typeSigs?: TypeSignatureMap): string;
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|