leglas 1.3.0 → 1.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/dist/keep.d.ts CHANGED
@@ -14,16 +14,9 @@ export type KeepPlan = {
14
14
  error: string;
15
15
  };
16
16
  /**
17
- * Plan the end of an exploration.
18
- *
19
- * Exploring is only safe to start because finishing is cheap, and finishing
20
- * means the winner leaves the ignored directory for real source while the
21
- * alternatives disappear entirely. Leglas can do this only because it knows
22
- * where it put those files; anything it did not generate is refused rather than
23
- * guessed at.
24
- *
25
- * The one step left to the user is the import in their own component, for the
26
- * same reason `leglas new` prints it rather than applying it.
17
+ * Plan the end of an exploration: the winner moves into real source and the
18
+ * rest is deleted. Anything Leglas didn't generate is refused, not guessed at.
19
+ * The import in the user's own component is left to them, as with `leglas new`.
27
20
  */
28
21
  export declare function planKeep(options: {
29
22
  title: string;
package/dist/new.d.ts CHANGED
@@ -14,10 +14,9 @@ export type NewPlan = {
14
14
  instructions: string;
15
15
  };
16
16
  /**
17
- * Which shape of param reading to generate. Only the distinction that changes
18
- * the output is drawn: whether params arrive on the server as a prop, or are
19
- * read from the URL in the browser. The browser form is the fallback because
20
- * it works anywhere React does.
17
+ * Params either arrive on the server as a prop or are read from the URL in the
18
+ * browser. The browser form is the fallback, since it works anywhere React
19
+ * does.
21
20
  */
22
21
  export declare function detectFramework(packageJson: string | null): Framework;
23
22
  /** The surface name becomes a query param, so it has to survive a URL intact. */
@@ -7,13 +7,9 @@ export type Resolved = {
7
7
  error: string;
8
8
  };
9
9
  /**
10
- * Resolve a name a command was given, and say something useful when it cannot.
11
- *
12
- * The message matters more than usual here. A direction renamed in the rail is
13
- * only renamed on this machine, so the name a user says is often not the name
14
- * the config spells; that gap is covered by resolving through the rename map.
15
- * What is left is a name nothing answers to, where the old message ("run
16
- * leglas list") sent an agent to a listing that would not contain the name
17
- * either, and the second miss reads as "the direction is gone".
10
+ * Resolves a name a command was given, or explains why not. Rail renames are
11
+ * local, so the name a user says is often not the config's; the rename map
12
+ * covers that. For a name nothing answers to, pointing at leglas list would
13
+ * just miss again and read as "the direction is gone".
18
14
  */
19
15
  export declare function resolveOrExplain(input: string, titles: readonly string[], renames: Renames): Resolved;
@@ -0,0 +1,41 @@
1
+ import type { AddPreview, ShareReach, ShareTunnel } from "./args.js";
2
+ /**
3
+ * What a command accepts beyond the shape of its arguments, for the parser and
4
+ * the MCP tools alike. Syntax stays with the parser: unknown flags, missing
5
+ * values, numbers that are not numbers.
6
+ */
7
+ export declare const MIN_PORT = 1;
8
+ export declare const MAX_PORT = 65535;
9
+ export declare const MIN_SHOW_WIDTH = 320;
10
+ export declare const MAX_SHOW_WIDTH = 3840;
11
+ export declare const DEFAULT_EXPLORE_COUNT = 3;
12
+ export declare const DEFAULT_SHARE_REACH: ShareReach;
13
+ export declare function portRefusal(flag: string, port: number): string | null;
14
+ export declare function valueRefusal(flag: string): string;
15
+ /**
16
+ * A preview needs something to show, and every text it carries has to say
17
+ * something: an empty note or tag is a slip, not a choice.
18
+ */
19
+ export declare function addRefusal(preview: AddPreview): string | null;
20
+ /**
21
+ * Stopping takes nothing that would start a share, and a share holds one
22
+ * direction or a pair. Reach counts only when it was asked for, since it has
23
+ * a default.
24
+ */
25
+ export declare function shareRefusal(options: {
26
+ titles: readonly string[];
27
+ reach: ShareReach | undefined;
28
+ tunnel: ShareTunnel | null;
29
+ stop: boolean;
30
+ rotate?: boolean;
31
+ revoke?: string | null;
32
+ }): string | null;
33
+ export declare function linkRefusal(titles: readonly string[]): string | null;
34
+ export declare function widthRefusal(width: number): string | null;
35
+ /** A width or a port only means something for a screenshot. */
36
+ export declare function showRefusal(options: {
37
+ screenshot: boolean;
38
+ width: number | null;
39
+ port: number | null;
40
+ }): string | null;
41
+ export declare function fromRefusal(from: string | undefined): string | null;
@@ -1,11 +1,9 @@
1
1
  import type { ClassifyChange } from "./args.js";
2
2
  import type { PreviewDeps, PreviewResult } from "./run-previews.js";
3
3
  /**
4
- * Answer where a direction should live, before it is written.
5
- *
6
- * Both answers are successes: the point is to be asked, so an agent about to
7
- * change dependencies or rewrite a shared file learns the checkout route
8
- * instead of quietly costing the property that makes flipping instant.
4
+ * Where a direction should live, asked before it's written. Both answers
5
+ * succeed: the point is that an agent about to change dependencies or rewrite a
6
+ * shared file learns the checkout route.
9
7
  */
10
8
  export declare function runClassify(options: {
11
9
  changes: ClassifyChange[];
@@ -15,12 +15,9 @@ export type ExploreBuildDeps = {
15
15
  sleep?: (milliseconds: number) => Promise<void>;
16
16
  };
17
17
  /**
18
- * Build a set of directions with the configured agent and wait for it.
19
- *
20
- * The work happens in the running Leglas, which owns the switch file, the
21
- * rail and the renders; this command starts it, reports each direction as it
22
- * lands and exits 0 only when every one is ready. Leaving it early does not
23
- * stop the builds, which the interface can still show and stop.
18
+ * Builds a set with the configured agent and waits. The running Leglas does the
19
+ * work; this reports each direction as it lands and exits 0 only when all are
20
+ * ready. Leaving early doesn't stop the builds.
24
21
  */
25
22
  export declare function runExploreBuild(options: ExploreBuildOptions, deps: ExploreBuildDeps): Promise<{
26
23
  exitCode: number;
@@ -2,12 +2,9 @@ export type ExploreDeps = {
2
2
  log(line: string): void;
3
3
  };
4
4
  /**
5
- * Brief an agent's exploration.
6
- *
7
- * Leglas runs no model, and it hands out no taste either: the agent has the
8
- * product, the surface and the design system in context, which is where taste
9
- * comes from. This prints the part the agent cannot know: how a set registers
10
- * and displays here, what the set is for, and how sets fail.
5
+ * Briefs an agent's exploration. Leglas runs no model and hands out no taste;
6
+ * this prints only what the agent can't know: how a set registers here, what
7
+ * it's for and how sets fail.
11
8
  */
12
9
  export declare function runExplore(options: {
13
10
  surface: string;
@@ -2,10 +2,9 @@ export type InitDeps = {
2
2
  log(line: string): void;
3
3
  };
4
4
  /**
5
- * Prepare a project: an AGENTS.md section so any agent entering the repo knows
6
- * how to author directions, a starter config, and the ignore entry. Adopting
7
- * Leglas in a repository is what distributes the contract; nothing has to be
8
- * installed per user.
5
+ * Prepares a project: an AGENTS.md section on authoring directions, a starter
6
+ * config and the ignore entry. Committing it is what spreads the contract;
7
+ * nothing is installed per user.
9
8
  */
10
9
  export declare function runInit(options: {
11
10
  cwd: string;
@@ -0,0 +1,18 @@
1
+ export type LinkDeps = {
2
+ log(line: string): void;
3
+ error(line: string): void;
4
+ fetch?: typeof fetch;
5
+ };
6
+ /**
7
+ * A link for the person to open: the rail, one direction on the stage, or two
8
+ * side by side. Names resolve the way `share` resolves them, so the name the
9
+ * rail shows works too.
10
+ */
11
+ export declare function runLink(options: {
12
+ titles: string[];
13
+ port: number | null;
14
+ json: boolean;
15
+ cwd: string;
16
+ }, deps: LinkDeps): Promise<{
17
+ exitCode: number;
18
+ }>;
package/dist/run-log.d.ts CHANGED
@@ -3,13 +3,9 @@ export type LogDeps = {
3
3
  error(line: string): void;
4
4
  };
5
5
  /**
6
- * Read what past explorations decided.
7
- *
8
- * The entries are plain markdown in a committed directory and are meant to be
9
- * read that way, in a pull request or on GitHub. This exists because an agent
10
- * asked to work on a surface should be able to find what was already tried
11
- * there without being told where to look, and because a person coming back to
12
- * a project should not have to know the directory's name.
6
+ * Reads what past explorations decided. The entries are plain markdown meant to
7
+ * be read on GitHub; this lets an agent or a returning person find them without
8
+ * knowing the directory.
13
9
  */
14
10
  export declare function runLog(options: {
15
11
  entry: string | null;
package/dist/run-new.d.ts CHANGED
@@ -6,13 +6,10 @@ export type NewResult = {
6
6
  written: string[];
7
7
  };
8
8
  /**
9
- * Scaffold a branch point for a surface.
10
- *
11
- * Writes only into the gitignored directory and, at most, appends one line to
12
- * .gitignore. The single change to the user's own source is printed rather
13
- * than applied: rewriting somebody's component automatically is how a tool
14
- * breaks a codebase it does not understand, and a wrong edit there costs far
15
- * more than a line of copying.
9
+ * Scaffolds a branch point for a surface. Writes only into the ignored
10
+ * directory, plus at most one .gitignore line. The one change to the user's own
11
+ * source is printed, not applied: an automatic edit to someone's component
12
+ * costs far more than a line of copying.
16
13
  */
17
14
  export declare function runNew(options: {
18
15
  surface: string;
@@ -2,6 +2,7 @@ import type { AddPreview } from "./args.js";
2
2
  export type PreviewDeps = {
3
3
  log(line: string): void;
4
4
  error(line: string): void;
5
+ fetch?: typeof fetch;
5
6
  };
6
7
  export type PreviewResult = {
7
8
  exitCode: number;
@@ -16,10 +17,9 @@ export declare function runList(options: {
16
17
  cwd: string;
17
18
  }, deps: PreviewDeps): Promise<PreviewResult>;
18
19
  /**
19
- * Hand pending requests to whoever asks. An agent polls this, acts on each
20
- * prompt, and clears the queue. Leglas runs no model of its own: the user's
21
- * agent already knows their conventions and design system, which is context
22
- * no external worker can have.
20
+ * Hands pending requests to whoever asks: an agent polls this, acts on each
21
+ * prompt and clears the queue. Leglas runs no model; the user's agent already
22
+ * knows their conventions.
23
23
  */
24
24
  export declare function runRequests(options: {
25
25
  json: boolean;
@@ -0,0 +1,17 @@
1
+ export type RemoveDeps = {
2
+ log(line: string): void;
3
+ error(line: string): void;
4
+ };
5
+ /**
6
+ * The rail's delete, from the command line: directions this machine registered
7
+ * leave the registry, and a running rail drops them on its next read. A
8
+ * direction the config lists is the project's, so it is refused, and one
9
+ * refusal removes nothing.
10
+ */
11
+ export declare function runRemove(options: {
12
+ titles: string[];
13
+ json: boolean;
14
+ cwd: string;
15
+ }, deps: RemoveDeps): Promise<{
16
+ exitCode: number;
17
+ }>;
@@ -5,6 +5,10 @@ export type ShareOptions = {
5
5
  reach: ShareReach;
6
6
  tunnel: ShareTunnel | null;
7
7
  stop: boolean;
8
+ /** End every link and mint one new, through a new tunnel. */
9
+ rotate?: boolean;
10
+ /** One link to end, by its address or id. */
11
+ revoke?: string | null;
8
12
  port: number | null;
9
13
  json: boolean;
10
14
  cwd: string;
@@ -17,19 +21,15 @@ export type ShareDeps = {
17
21
  sleep?: (milliseconds: number) => Promise<void>;
18
22
  };
19
23
  /**
20
- * How long to wait for a tunnel's public address before handing back the
21
- * local one. A quick tunnel usually answers in seconds; a minute covers a
22
- * slow one without leaving a terminal hanging on a tunnel that failed quietly.
24
+ * How long to wait for a tunnel's public address before handing back the local
25
+ * one. Quick tunnels answer in seconds; a minute covers a slow one without
26
+ * hanging on one that failed quietly.
23
27
  */
24
28
  export declare const TUNNEL_WAIT_MS = 60000;
25
29
  /**
26
- * Share from the terminal what the panel shares from the interface.
27
- *
28
- * The share itself is the running Leglas's, through the same endpoints the
29
- * panel calls, so it carries the same refusals and the same ceiling. What a
30
- * terminal cannot have is the browser's own view of the rail, so the rail it
31
- * shares is the project's: every direction in config order, under the names
32
- * the interface saved.
30
+ * The panel's share, from the terminal, through the same endpoints, refusals
31
+ * and ceiling. Without the browser's view of the rail, the rail shared is the
32
+ * project's: config order, under the names the interface saved.
33
33
  */
34
34
  export declare function runShare(options: ShareOptions, deps: ShareDeps): Promise<{
35
35
  exitCode: number;
@@ -4,11 +4,9 @@ export type ShowDeps = {
4
4
  fetch?: typeof fetch;
5
5
  };
6
6
  /**
7
- * Answer for one direction, for whoever was handed its reference block.
8
- *
9
- * Addressing is by config title, which is what every other command takes and
10
- * what the block quotes, so a renamed direction is still reachable by the name
11
- * the project knows it by.
7
+ * Everything about one direction, for whoever was handed its reference block.
8
+ * Addressed by config title, like every other command, so a renamed direction
9
+ * is still reachable.
12
10
  */
13
11
  export declare function runShow(options: {
14
12
  title: string;
@@ -3,15 +3,9 @@ export type WatchDeps = {
3
3
  error(line: string): void;
4
4
  };
5
5
  /**
6
- * Hand change requests to the user's own agent as they arrive.
7
- *
8
- * This is the whole live loop: the interface writes a request, watch picks it
9
- * up, the user's agent does the work with the user's keys and the user's model.
10
- * Leglas still runs no model of its own. What it adds is locality, so asking
11
- * for a change no longer means leaving the comparison for a terminal.
12
- *
13
- * Resolves when the watcher stops, which is what a signal does, so the caller
14
- * stays the same shape as every other command.
6
+ * Hands change requests to the user's own agent as they arrive, with the user's
7
+ * keys and model; Leglas runs none. Resolves when a signal stops the watcher,
8
+ * so the caller looks like every other command.
15
9
  */
16
10
  export declare function runWatch(options: {
17
11
  run: string | undefined;
package/dist/run.d.ts CHANGED
@@ -18,12 +18,9 @@ export type RunResult = {
18
18
  stop(): Promise<void>;
19
19
  };
20
20
  /**
21
- * Boot Leglas: resolve config, start the server, open the interface.
22
- *
23
- * Nothing here is fatal except being unable to bind a port. A missing config,
24
- * an invalid config, or a dev server that is not running are all reported and
25
- * survivable, because the user is mid-setup and needs to be told what to fix,
26
- * not handed a stack trace.
21
+ * Boots Leglas: resolve config, start the server, open the interface. Only
22
+ * failing to bind a port is fatal; a missing or invalid config or a stopped dev
23
+ * server is reported, since the user is mid-setup.
27
24
  */
28
25
  export declare function run(options: RunOptions & {
29
26
  cwd: string;
package/dist/running.d.ts CHANGED
@@ -8,12 +8,29 @@ export type FoundLeglas = {
8
8
  error: string;
9
9
  };
10
10
  /**
11
- * The Leglas serving this project, for a command that needs the running one.
12
- *
13
- * An explicit port wins; then the record the running server wrote; then the
14
- * default, since a record can be missing while a server is up (two servers on
15
- * one project, the newer one gone first). The health answer decides whichever
16
- * way the port was found, and a Leglas serving another project is not this
17
- * one: acting on it would act on the wrong project's directions.
11
+ * The Leglas serving this project: an explicit port, else the server's record,
12
+ * else the default (a record can be missing while a server is up). Health
13
+ * decides either way, and a Leglas serving another project is refused.
18
14
  */
19
15
  export declare function findLeglas(cwd: string, port: number | null, request: typeof fetch): Promise<FoundLeglas>;
16
+ /**
17
+ * The interface on one direction, or two side by side; none opens the rail.
18
+ * On localhost, like the address Leglas opens, because the rail keeps its
19
+ * layout per origin.
20
+ */
21
+ export declare function interfaceUrl(port: number, titles: readonly string[]): string;
22
+ /**
23
+ * The titles on the rail a running Leglas serves, as its interface reads them.
24
+ * They can differ from the files: a branch or file direction registered while
25
+ * it runs joins only after a restart.
26
+ */
27
+ export declare function railTitles(port: number, request: typeof fetch): Promise<ReadonlySet<string> | null>;
28
+ export type Rail = {
29
+ port: number;
30
+ titles: ReadonlySet<string>;
31
+ };
32
+ /**
33
+ * This project's running rail, known only from the record its server writes:
34
+ * without one there is no link to give, and nothing is asked.
35
+ */
36
+ export declare function recordedRail(cwd: string, request: typeof fetch): Promise<Rail | null>;