chivgent 0.9.0 → 0.11.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 +144 -10
- package/README.zh-CN.md +123 -8
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +9 -0
- package/dist/agent.js.map +1 -1
- package/dist/cli-options.d.ts +13 -2
- package/dist/cli-options.d.ts.map +1 -1
- package/dist/cli-options.js +39 -5
- package/dist/cli-options.js.map +1 -1
- package/dist/cli.js +166 -6
- package/dist/cli.js.map +1 -1
- package/dist/events.d.ts +17 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/extensions/api.d.ts +38 -0
- package/dist/extensions/api.d.ts.map +1 -0
- package/dist/extensions/api.js +2 -0
- package/dist/extensions/api.js.map +1 -0
- package/dist/extensions/decide-trust.d.ts +28 -0
- package/dist/extensions/decide-trust.d.ts.map +1 -0
- package/dist/extensions/decide-trust.js +96 -0
- package/dist/extensions/decide-trust.js.map +1 -0
- package/dist/extensions/discover.d.ts +19 -0
- package/dist/extensions/discover.d.ts.map +1 -0
- package/dist/extensions/discover.js +61 -0
- package/dist/extensions/discover.js.map +1 -0
- package/dist/extensions/loader.d.ts +28 -0
- package/dist/extensions/loader.d.ts.map +1 -0
- package/dist/extensions/loader.js +60 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/extensions/registry.d.ts +36 -0
- package/dist/extensions/registry.d.ts.map +1 -0
- package/dist/extensions/registry.js +115 -0
- package/dist/extensions/registry.js.map +1 -0
- package/dist/extensions/trust.d.ts +44 -0
- package/dist/extensions/trust.d.ts.map +1 -0
- package/dist/extensions/trust.js +129 -0
- package/dist/extensions/trust.js.map +1 -0
- package/dist/render.d.ts +5 -0
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +36 -0
- package/dist/render.js.map +1 -1
- package/dist/repl.d.ts +12 -1
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +47 -2
- package/dist/repl.js.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +2 -1
- package/dist/session.js.map +1 -1
- package/dist/shell/config.d.ts +14 -0
- package/dist/shell/config.d.ts.map +1 -0
- package/dist/shell/config.js +43 -0
- package/dist/shell/config.js.map +1 -0
- package/dist/shell/local.d.ts +10 -0
- package/dist/shell/local.d.ts.map +1 -0
- package/dist/shell/local.js +90 -0
- package/dist/shell/local.js.map +1 -0
- package/dist/shell/output.d.ts +54 -0
- package/dist/shell/output.d.ts.map +1 -0
- package/dist/shell/output.js +168 -0
- package/dist/shell/output.js.map +1 -0
- package/dist/shell/process.d.ts +21 -0
- package/dist/shell/process.d.ts.map +1 -0
- package/dist/shell/process.js +134 -0
- package/dist/shell/process.js.map +1 -0
- package/dist/shell/sanitize.d.ts +10 -0
- package/dist/shell/sanitize.d.ts.map +1 -0
- package/dist/shell/sanitize.js +34 -0
- package/dist/shell/sanitize.js.map +1 -0
- package/dist/shell/truncate.d.ts +31 -0
- package/dist/shell/truncate.d.ts.map +1 -0
- package/dist/shell/truncate.js +121 -0
- package/dist/shell/truncate.js.map +1 -0
- package/dist/shell/types.d.ts +33 -0
- package/dist/shell/types.d.ts.map +1 -0
- package/dist/shell/types.js +26 -0
- package/dist/shell/types.js.map +1 -0
- package/dist/tools/bash.d.ts +42 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +225 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/tool.d.ts +5 -0
- package/dist/tools/tool.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DiscoveredExtension } from "./discover.js";
|
|
2
|
+
import { ExtensionRegistry, type RegistryOptions } from "./registry.js";
|
|
3
|
+
export interface LoadedExtension {
|
|
4
|
+
readonly path: string;
|
|
5
|
+
readonly origin: DiscoveredExtension["origin"];
|
|
6
|
+
}
|
|
7
|
+
export interface LoadResult {
|
|
8
|
+
readonly registry: ExtensionRegistry;
|
|
9
|
+
readonly loaded: readonly LoadedExtension[];
|
|
10
|
+
readonly failed: readonly {
|
|
11
|
+
readonly path: string;
|
|
12
|
+
readonly reason: string;
|
|
13
|
+
}[];
|
|
14
|
+
}
|
|
15
|
+
export interface LoadOptions extends RegistryOptions {
|
|
16
|
+
/** Injectable so tests do not have to write modules to disk to test loading. */
|
|
17
|
+
readonly importModule?: (path: string) => Promise<unknown>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Imports each extension and lets it register.
|
|
21
|
+
*
|
|
22
|
+
* Importing a module runs its top-level code, so this is the point of no
|
|
23
|
+
* return: everything the caller wanted to gate must already have been decided.
|
|
24
|
+
* From here on the job is containment — one broken extension must leave
|
|
25
|
+
* chivgent working.
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadExtensions(discovered: readonly DiscoveredExtension[], options: LoadOptions): Promise<LoadResult>;
|
|
28
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/extensions/loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAGxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAChF;AAED,MAAM,WAAW,WAAY,SAAQ,eAAe;IAClD,gFAAgF;IAChF,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5D;AAiBD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,SAAS,mBAAmB,EAAE,EAC1C,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAuCrB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
2
|
+
import { ExtensionRegistry } from "./registry.js";
|
|
3
|
+
async function defaultImport(modulePath) {
|
|
4
|
+
// A file URL is required on Windows and harmless elsewhere.
|
|
5
|
+
return import(pathToFileURL(modulePath).href);
|
|
6
|
+
}
|
|
7
|
+
function readFactory(module) {
|
|
8
|
+
if (typeof module !== "object" || module === null) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const candidate = module.default;
|
|
12
|
+
return typeof candidate === "function"
|
|
13
|
+
? candidate
|
|
14
|
+
: undefined;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Imports each extension and lets it register.
|
|
18
|
+
*
|
|
19
|
+
* Importing a module runs its top-level code, so this is the point of no
|
|
20
|
+
* return: everything the caller wanted to gate must already have been decided.
|
|
21
|
+
* From here on the job is containment — one broken extension must leave
|
|
22
|
+
* chivgent working.
|
|
23
|
+
*/
|
|
24
|
+
export async function loadExtensions(discovered, options) {
|
|
25
|
+
const registry = new ExtensionRegistry(options);
|
|
26
|
+
const importModule = options.importModule ?? defaultImport;
|
|
27
|
+
const loaded = [];
|
|
28
|
+
const failed = [];
|
|
29
|
+
for (const extension of discovered) {
|
|
30
|
+
let factory;
|
|
31
|
+
try {
|
|
32
|
+
factory = readFactory(await importModule(extension.path));
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
36
|
+
failed.push({ path: extension.path, reason });
|
|
37
|
+
options.onWarning(`${extension.path}: failed to load (${reason}).`);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (factory === undefined) {
|
|
41
|
+
const reason = "no default export function";
|
|
42
|
+
failed.push({ path: extension.path, reason });
|
|
43
|
+
options.onWarning(`${extension.path}: ${reason}; an extension must export default a function.`);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
await factory(registry.apiFor(extension.path));
|
|
48
|
+
loaded.push({ path: extension.path, origin: extension.origin });
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
52
|
+
failed.push({ path: extension.path, reason });
|
|
53
|
+
// Whatever it registered before throwing stays: partial is better than
|
|
54
|
+
// discarding work that is already valid.
|
|
55
|
+
options.onWarning(`${extension.path}: threw while registering (${reason}).`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { registry, loaded, failed };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/extensions/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAwB,MAAM,eAAe,CAAC;AAmBxE,KAAK,UAAU,aAAa,CAAC,UAAkB;IAC7C,4DAA4D;IAC5D,OAAO,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,WAAW,CAAC,MAAe;IAClC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,SAAS,GAAI,MAAgC,CAAC,OAAO,CAAC;IAC5D,OAAO,OAAO,SAAS,KAAK,UAAU;QACpC,CAAC,CAAE,SAA8B;QACjC,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAA0C,EAC1C,OAAoB;IAEpB,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,aAAa,CAAC;IAC3D,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,MAAM,MAAM,GAAuC,EAAE,CAAC;IAEtD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,OAAqC,CAAC;QAC1C,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,MAAM,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,IAAI,qBAAqB,MAAM,IAAI,CAAC,CAAC;YACpE,SAAS;QACX,CAAC;QAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,SAAS,CACf,GAAG,SAAS,CAAC,IAAI,KAAK,MAAM,gDAAgD,CAC7E,CAAC;YACF,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9C,uEAAuE;YACvE,yCAAyC;YACzC,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,IAAI,8BAA8B,MAAM,IAAI,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AgentEvent } from "../events.js";
|
|
2
|
+
import type { ExtensionAPI, RegisteredCommand, RegisteredTool } from "./api.js";
|
|
3
|
+
export interface RegistryOptions {
|
|
4
|
+
/** Names an extension may not take, so a project cannot shadow read_file. */
|
|
5
|
+
readonly reservedToolNames: readonly string[];
|
|
6
|
+
readonly reservedCommandNames: readonly string[];
|
|
7
|
+
readonly onWarning: (message: string) => void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Collects what extensions register.
|
|
11
|
+
*
|
|
12
|
+
* Every rejection is reported and survivable: a conflicting registration is
|
|
13
|
+
* dropped, the rest of the extension keeps whatever it registered before and
|
|
14
|
+
* after, and the built-in stays in place.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ExtensionRegistry {
|
|
17
|
+
private readonly options;
|
|
18
|
+
private readonly tools;
|
|
19
|
+
private readonly commands;
|
|
20
|
+
private readonly listeners;
|
|
21
|
+
private readonly promptContributions;
|
|
22
|
+
constructor(options: RegistryOptions);
|
|
23
|
+
/** The API handed to one extension; `source` identifies it in diagnostics. */
|
|
24
|
+
apiFor(source: string): ExtensionAPI;
|
|
25
|
+
get registeredTools(): readonly RegisteredTool[];
|
|
26
|
+
get registeredCommands(): readonly RegisteredCommand[];
|
|
27
|
+
get systemPromptContributions(): readonly string[];
|
|
28
|
+
command(name: string): RegisteredCommand | undefined;
|
|
29
|
+
/** A single listener that fans one event out to every subscribed handler. */
|
|
30
|
+
get eventListener(): (event: AgentEvent) => void;
|
|
31
|
+
private addTool;
|
|
32
|
+
private addCommand;
|
|
33
|
+
private addListener;
|
|
34
|
+
private addPrompt;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/extensions/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,KAAK,EACV,YAAY,EAEZ,iBAAiB,EACjB,cAAc,EACf,MAAM,UAAU,CAAC;AAIlB,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAShB,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAC3D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAGjB;IACT,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAgB;IAEpD,YAA6B,OAAO,EAAE,eAAe,EAAI;IAEzD,8EAA8E;IAC9E,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CASnC;IAED,IAAI,eAAe,IAAI,SAAS,cAAc,EAAE,CAE/C;IAED,IAAI,kBAAkB,IAAI,SAAS,iBAAiB,EAAE,CAErD;IAED,IAAI,yBAAyB,IAAI,SAAS,MAAM,EAAE,CAEjD;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEnD;IAED,6EAA6E;IAC7E,IAAI,aAAa,IAAI,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAa/C;IAED,OAAO,CAAC,OAAO;IA2Bf,OAAO,CAAC,UAAU;IAoClB,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,SAAS;CAOlB"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
const COMMAND_NAME = /^[a-z][a-z0-9-]*$/;
|
|
2
|
+
/**
|
|
3
|
+
* Collects what extensions register.
|
|
4
|
+
*
|
|
5
|
+
* Every rejection is reported and survivable: a conflicting registration is
|
|
6
|
+
* dropped, the rest of the extension keeps whatever it registered before and
|
|
7
|
+
* after, and the built-in stays in place.
|
|
8
|
+
*/
|
|
9
|
+
export class ExtensionRegistry {
|
|
10
|
+
options;
|
|
11
|
+
tools = new Map();
|
|
12
|
+
commands = new Map();
|
|
13
|
+
listeners = [];
|
|
14
|
+
promptContributions = [];
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
}
|
|
18
|
+
/** The API handed to one extension; `source` identifies it in diagnostics. */
|
|
19
|
+
apiFor(source) {
|
|
20
|
+
return {
|
|
21
|
+
registerTool: (tool) => this.addTool(tool, source),
|
|
22
|
+
registerCommand: (name, command) => this.addCommand(name, command, source),
|
|
23
|
+
on: (type, handler) => this.addListener(type, handler, source),
|
|
24
|
+
contributeSystemPrompt: (text) => this.addPrompt(text, source),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
get registeredTools() {
|
|
28
|
+
return [...this.tools.values()];
|
|
29
|
+
}
|
|
30
|
+
get registeredCommands() {
|
|
31
|
+
return [...this.commands.values()];
|
|
32
|
+
}
|
|
33
|
+
get systemPromptContributions() {
|
|
34
|
+
return this.promptContributions;
|
|
35
|
+
}
|
|
36
|
+
command(name) {
|
|
37
|
+
return this.commands.get(name);
|
|
38
|
+
}
|
|
39
|
+
/** A single listener that fans one event out to every subscribed handler. */
|
|
40
|
+
get eventListener() {
|
|
41
|
+
return (event) => {
|
|
42
|
+
for (const listener of this.listeners) {
|
|
43
|
+
if (listener.type !== event.type) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
listener.handler(event);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// An extension must not change the outcome of the run it observes.
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
addTool(tool, source) {
|
|
56
|
+
if (typeof tool !== "object" ||
|
|
57
|
+
tool === null ||
|
|
58
|
+
typeof tool.name !== "string" ||
|
|
59
|
+
tool.name.length === 0 ||
|
|
60
|
+
typeof tool.execute !== "function") {
|
|
61
|
+
this.options.onWarning(`${source}: registerTool needs a tool with a name and an execute function.`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (this.options.reservedToolNames.includes(tool.name)) {
|
|
65
|
+
this.options.onWarning(`${source}: cannot register the tool "${tool.name}"; that name is built in.`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const existing = this.tools.get(tool.name);
|
|
69
|
+
if (existing !== undefined) {
|
|
70
|
+
this.options.onWarning(`${source}: the tool "${tool.name}" is already registered by ${existing.source}.`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.tools.set(tool.name, { tool, source });
|
|
74
|
+
}
|
|
75
|
+
addCommand(name, command, source) {
|
|
76
|
+
if (typeof name !== "string" || !COMMAND_NAME.test(name)) {
|
|
77
|
+
this.options.onWarning(`${source}: "${String(name)}" is not a usable command name; use lowercase letters, digits and dashes.`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (typeof command !== "object" || command === null || typeof command.run !== "function") {
|
|
81
|
+
this.options.onWarning(`${source}: the command "${name}" needs a run function.`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (this.options.reservedCommandNames.includes(name)) {
|
|
85
|
+
this.options.onWarning(`${source}: cannot register "/${name}"; that command is built in.`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const existing = this.commands.get(name);
|
|
89
|
+
if (existing !== undefined) {
|
|
90
|
+
this.options.onWarning(`${source}: "/${name}" is already registered by ${existing.source}.`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.commands.set(name, {
|
|
94
|
+
name,
|
|
95
|
+
source,
|
|
96
|
+
description: typeof command.description === "string" ? command.description : "",
|
|
97
|
+
run: command.run.bind(command),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
addListener(type, handler, source) {
|
|
101
|
+
if (typeof handler !== "function") {
|
|
102
|
+
this.options.onWarning(`${source}: on("${String(type)}") needs a function.`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
this.listeners.push({ type, handler });
|
|
106
|
+
}
|
|
107
|
+
addPrompt(text, source) {
|
|
108
|
+
if (typeof text !== "string" || text.trim().length === 0) {
|
|
109
|
+
this.options.onWarning(`${source}: contributeSystemPrompt needs a non-empty string.`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.promptContributions.push(text.trim());
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/extensions/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const CONFIG_DIRECTORY = ".chivgent";
|
|
2
|
+
export declare const EXTENSIONS_DIRECTORY = "extensions";
|
|
3
|
+
export declare class TrustFileError extends Error {
|
|
4
|
+
constructor(message: string, options?: {
|
|
5
|
+
cause?: unknown;
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export declare function defaultTrustFile(environment?: NodeJS.ProcessEnv): string;
|
|
9
|
+
/**
|
|
10
|
+
* Resolves a directory the way the trust store keys it.
|
|
11
|
+
*
|
|
12
|
+
* Symlinks and `..` are resolved first so that two paths naming the same
|
|
13
|
+
* directory cannot produce two entries, one of which the user never sees.
|
|
14
|
+
*/
|
|
15
|
+
export declare function canonicalDirectory(directory: string): Promise<string>;
|
|
16
|
+
export type TrustDecision = boolean;
|
|
17
|
+
export interface TrustEntry {
|
|
18
|
+
/** The directory the decision was recorded against, which may be an ancestor. */
|
|
19
|
+
readonly path: string;
|
|
20
|
+
readonly decision: TrustDecision;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Records whether a project directory may contribute code to chivgent.
|
|
24
|
+
*
|
|
25
|
+
* Decisions are looked up by nearest ancestor, so trusting `~/work` covers
|
|
26
|
+
* every repository under it. A monorepo does not ask once per package.
|
|
27
|
+
*/
|
|
28
|
+
export declare class TrustStore {
|
|
29
|
+
private readonly filePath;
|
|
30
|
+
constructor(filePath?: string);
|
|
31
|
+
get location(): string;
|
|
32
|
+
lookup(directory: string): Promise<TrustEntry | undefined>;
|
|
33
|
+
set(directory: string, decision: TrustDecision): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Removes the decision that covers this directory, including an ancestor's,
|
|
36
|
+
* so that forgetting actually makes chivgent ask again.
|
|
37
|
+
*/
|
|
38
|
+
forget(directory: string): Promise<string | undefined>;
|
|
39
|
+
private read;
|
|
40
|
+
private write;
|
|
41
|
+
}
|
|
42
|
+
/** True when the project directory carries anything trust has to gate. */
|
|
43
|
+
export declare function hasProjectExtensions(cwd: string): boolean;
|
|
44
|
+
//# sourceMappingURL=trust.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.d.ts","sourceRoot":"","sources":["../../src/extensions/trust.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB,cAAc,CAAC;AAC5C,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAGjD,qBAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAGzD;CACF;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,GAAE,MAAM,CAAC,UAAwB,GAC3C,MAAM,CAER;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS3E;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC;AAEpC,MAAM,WAAW,UAAU;IACzB,iFAAiF;IACjF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CAClC;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAArC,YAA6B,QAAQ,GAAE,MAA2B,EAAI;IAEtE,IAAI,QAAQ,IAAI,MAAM,CAErB;IAEK,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAc/D;IAEK,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnE;IAED;;;OAGG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS3D;YAEa,IAAI;YAyCJ,KAAK;CAcpB;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEzD"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { realpath } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { defaultSessionHome } from "../session-store.js";
|
|
6
|
+
export const CONFIG_DIRECTORY = ".chivgent";
|
|
7
|
+
export const EXTENSIONS_DIRECTORY = "extensions";
|
|
8
|
+
const TRUST_FILE = "trust.json";
|
|
9
|
+
export class TrustFileError extends Error {
|
|
10
|
+
constructor(message, options) {
|
|
11
|
+
super(message, options);
|
|
12
|
+
this.name = "TrustFileError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function defaultTrustFile(environment = process.env) {
|
|
16
|
+
return path.join(defaultSessionHome(environment), TRUST_FILE);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolves a directory the way the trust store keys it.
|
|
20
|
+
*
|
|
21
|
+
* Symlinks and `..` are resolved first so that two paths naming the same
|
|
22
|
+
* directory cannot produce two entries, one of which the user never sees.
|
|
23
|
+
*/
|
|
24
|
+
export async function canonicalDirectory(directory) {
|
|
25
|
+
const absolute = path.resolve(directory);
|
|
26
|
+
try {
|
|
27
|
+
return await realpath(absolute);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// A directory that does not exist cannot be resolved, but it can still be
|
|
31
|
+
// recorded; the lexical form is the best available key.
|
|
32
|
+
return absolute;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Records whether a project directory may contribute code to chivgent.
|
|
37
|
+
*
|
|
38
|
+
* Decisions are looked up by nearest ancestor, so trusting `~/work` covers
|
|
39
|
+
* every repository under it. A monorepo does not ask once per package.
|
|
40
|
+
*/
|
|
41
|
+
export class TrustStore {
|
|
42
|
+
filePath;
|
|
43
|
+
constructor(filePath = defaultTrustFile()) {
|
|
44
|
+
this.filePath = filePath;
|
|
45
|
+
}
|
|
46
|
+
get location() {
|
|
47
|
+
return this.filePath;
|
|
48
|
+
}
|
|
49
|
+
async lookup(directory) {
|
|
50
|
+
const data = await this.read();
|
|
51
|
+
let current = await canonicalDirectory(directory);
|
|
52
|
+
for (;;) {
|
|
53
|
+
const decision = data[current];
|
|
54
|
+
if (decision !== undefined) {
|
|
55
|
+
return { path: current, decision };
|
|
56
|
+
}
|
|
57
|
+
const parent = path.dirname(current);
|
|
58
|
+
if (parent === current) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
current = parent;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async set(directory, decision) {
|
|
65
|
+
const key = await canonicalDirectory(directory);
|
|
66
|
+
const data = await this.read();
|
|
67
|
+
data[key] = decision;
|
|
68
|
+
await this.write(data);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Removes the decision that covers this directory, including an ancestor's,
|
|
72
|
+
* so that forgetting actually makes chivgent ask again.
|
|
73
|
+
*/
|
|
74
|
+
async forget(directory) {
|
|
75
|
+
const entry = await this.lookup(directory);
|
|
76
|
+
if (entry === undefined) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
const data = await this.read();
|
|
80
|
+
delete data[entry.path];
|
|
81
|
+
await this.write(data);
|
|
82
|
+
return entry.path;
|
|
83
|
+
}
|
|
84
|
+
async read() {
|
|
85
|
+
let contents;
|
|
86
|
+
try {
|
|
87
|
+
contents = await readFile(this.filePath, "utf8");
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (error.code === "ENOENT") {
|
|
91
|
+
return {};
|
|
92
|
+
}
|
|
93
|
+
throw new TrustFileError(`Could not read the trust file at ${this.filePath}.`, { cause: error });
|
|
94
|
+
}
|
|
95
|
+
let parsed;
|
|
96
|
+
try {
|
|
97
|
+
parsed = JSON.parse(contents);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
throw new TrustFileError(`The trust file at ${this.filePath} is not valid JSON.`, { cause: error });
|
|
101
|
+
}
|
|
102
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
103
|
+
throw new TrustFileError(`The trust file at ${this.filePath} must contain a JSON object keyed by directory.`);
|
|
104
|
+
}
|
|
105
|
+
const data = {};
|
|
106
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
107
|
+
if (typeof value !== "boolean") {
|
|
108
|
+
throw new TrustFileError(`The trust file entry for "${key}" must be true or false.`);
|
|
109
|
+
}
|
|
110
|
+
data[key] = value;
|
|
111
|
+
}
|
|
112
|
+
return data;
|
|
113
|
+
}
|
|
114
|
+
async write(data) {
|
|
115
|
+
await mkdir(path.dirname(this.filePath), { recursive: true });
|
|
116
|
+
const sorted = {};
|
|
117
|
+
for (const key of Object.keys(data).sort()) {
|
|
118
|
+
sorted[key] = data[key];
|
|
119
|
+
}
|
|
120
|
+
// The file is meant to be read and edited by a person, so it stays sorted
|
|
121
|
+
// and indented rather than compact.
|
|
122
|
+
await writeFile(this.filePath, `${JSON.stringify(sorted, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** True when the project directory carries anything trust has to gate. */
|
|
126
|
+
export function hasProjectExtensions(cwd) {
|
|
127
|
+
return existsSync(path.join(cwd, CONFIG_DIRECTORY, EXTENSIONS_DIRECTORY));
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=trust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.js","sourceRoot":"","sources":["../../src/extensions/trust.ts"],"names":[],"mappings":"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"}
|
package/dist/render.d.ts
CHANGED
|
@@ -11,6 +11,11 @@ export interface RendererOptions {
|
|
|
11
11
|
readonly stream?: boolean;
|
|
12
12
|
/** Print tool activity to stderr. */
|
|
13
13
|
readonly showToolActivity?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Print a self-rewriting progress line while a tool runs. Needs a terminal:
|
|
16
|
+
* the line is redrawn with a carriage return.
|
|
17
|
+
*/
|
|
18
|
+
readonly showToolProgress?: boolean;
|
|
14
19
|
readonly color?: boolean;
|
|
15
20
|
}
|
|
16
21
|
/**
|
package/dist/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAUlE,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,EACxB,OAAO,GAAE,eAAoB,GAC5B,kBAAkB,CA2FpB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,MAAM,GACd,kBAAkB,CAOpB"}
|
package/dist/render.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const MAX_ARGUMENT_CHARACTERS = 120;
|
|
2
2
|
const MAX_RESULT_CHARACTERS = 100;
|
|
3
|
+
const MAX_PROGRESS_CHARACTERS = 100;
|
|
3
4
|
const DIM = "\u001B[2m";
|
|
4
5
|
const RED = "\u001B[31m";
|
|
5
6
|
const RESET = "\u001B[0m";
|
|
@@ -10,9 +11,19 @@ const RESET = "\u001B[0m";
|
|
|
10
11
|
export function createEventRenderer(streams, options = {}) {
|
|
11
12
|
const stream = options.stream ?? true;
|
|
12
13
|
const showToolActivity = options.showToolActivity ?? true;
|
|
14
|
+
const showToolProgress = options.showToolProgress ?? false;
|
|
13
15
|
const color = options.color ?? false;
|
|
14
16
|
const paint = (value, code) => color ? `${code}${value}${RESET}` : value;
|
|
15
17
|
let lineOpen = false;
|
|
18
|
+
let progressWidth = 0;
|
|
19
|
+
// Overwrite the progress line with spaces before anything else is written,
|
|
20
|
+
// or the leftovers of a longer line stay on screen.
|
|
21
|
+
const clearProgress = () => {
|
|
22
|
+
if (progressWidth > 0) {
|
|
23
|
+
streams.stderr.write(`\r${" ".repeat(progressWidth)}\r`);
|
|
24
|
+
progressWidth = 0;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
16
27
|
const endLine = () => {
|
|
17
28
|
if (lineOpen) {
|
|
18
29
|
streams.stdout.write("\n");
|
|
@@ -33,18 +44,32 @@ export function createEventRenderer(streams, options = {}) {
|
|
|
33
44
|
}
|
|
34
45
|
endLine();
|
|
35
46
|
return;
|
|
47
|
+
case "tool_execution_update":
|
|
48
|
+
if (showToolProgress) {
|
|
49
|
+
const line = lastNonEmptyLine(event.content);
|
|
50
|
+
if (line.length > 0) {
|
|
51
|
+
const text = ` ${truncate(line, MAX_PROGRESS_CHARACTERS)}`;
|
|
52
|
+
clearProgress();
|
|
53
|
+
streams.stderr.write(`\r${paint(text, DIM)}`);
|
|
54
|
+
progressWidth = text.length;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
36
58
|
case "tool_execution_start":
|
|
37
59
|
if (showToolActivity) {
|
|
60
|
+
clearProgress();
|
|
38
61
|
streams.stderr.write(paint(`· ${event.toolName} ${summariseArguments(event.arguments)}\n`, DIM));
|
|
39
62
|
}
|
|
40
63
|
return;
|
|
41
64
|
case "tool_execution_end":
|
|
65
|
+
clearProgress();
|
|
42
66
|
if (showToolActivity) {
|
|
43
67
|
const summary = ` ↳ ${summariseResult(event.content, event.isError)}\n`;
|
|
44
68
|
streams.stderr.write(paint(summary, event.isError ? RED : DIM));
|
|
45
69
|
}
|
|
46
70
|
return;
|
|
47
71
|
case "agent_end":
|
|
72
|
+
clearProgress();
|
|
48
73
|
endLine();
|
|
49
74
|
if (event.status === "max_turns") {
|
|
50
75
|
streams.stderr.write(`Stopped after ${event.turnCount} turns without a final answer.\n`);
|
|
@@ -87,6 +112,17 @@ function summariseResult(content, isError) {
|
|
|
87
112
|
const suffix = lineCount > 1 ? ` (${lineCount} lines)` : "";
|
|
88
113
|
return `${isError ? "error: " : ""}${truncate(firstLine, MAX_RESULT_CHARACTERS)}${suffix}`;
|
|
89
114
|
}
|
|
115
|
+
/** The tail of a command's output is the part worth showing while it runs. */
|
|
116
|
+
function lastNonEmptyLine(content) {
|
|
117
|
+
const lines = content.split("\n");
|
|
118
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
119
|
+
const line = (lines[index] ?? "").trim();
|
|
120
|
+
if (line.length > 0) {
|
|
121
|
+
return line;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return "";
|
|
125
|
+
}
|
|
90
126
|
function truncate(value, maxCharacters) {
|
|
91
127
|
return value.length <= maxCharacters
|
|
92
128
|
? value
|
package/dist/render.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAEA,MAAM,uBAAuB,GAAG,GAAG,CAAC;AACpC,MAAM,qBAAqB,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
package/dist/repl.d.ts
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import type { AgentSession } from "./session.js";
|
|
2
2
|
import type { OutputStream } from "./render.js";
|
|
3
|
+
import type { RegisteredCommand } from "./extensions/api.js";
|
|
3
4
|
export declare const REPL_PROMPT = "\u203A ";
|
|
4
|
-
export type SlashCommandOutcome = "handled" | "exit" | "not-a-command"
|
|
5
|
+
export type SlashCommandOutcome = "handled" | "exit" | "not-a-command"
|
|
6
|
+
/** An extension command matched; the REPL runs it, since it may be async. */
|
|
7
|
+
| {
|
|
8
|
+
readonly kind: "extension";
|
|
9
|
+
readonly command: RegisteredCommand;
|
|
10
|
+
readonly argument: string;
|
|
11
|
+
};
|
|
5
12
|
export interface SlashCommandContext {
|
|
6
13
|
readonly session: AgentSession;
|
|
7
14
|
readonly write: (text: string) => void;
|
|
8
15
|
readonly sessionFile?: string;
|
|
16
|
+
/** Commands contributed by extensions, keyed by name without the slash. */
|
|
17
|
+
readonly extensionCommands?: readonly RegisteredCommand[];
|
|
9
18
|
}
|
|
19
|
+
export declare const BUILT_IN_COMMANDS: readonly ["help", "session", "tools", "clear", "exit", "quit"];
|
|
10
20
|
/**
|
|
11
21
|
* Interprets one line of REPL input. Returns `not-a-command` when the line is
|
|
12
22
|
* an ordinary prompt for the model.
|
|
@@ -19,6 +29,7 @@ export interface ReplOptions {
|
|
|
19
29
|
readonly stderr: OutputStream;
|
|
20
30
|
readonly banner?: string;
|
|
21
31
|
readonly sessionFile?: string;
|
|
32
|
+
readonly extensionCommands?: readonly RegisteredCommand[];
|
|
22
33
|
}
|
|
23
34
|
/**
|
|
24
35
|
* Reads prompts until the user leaves. One run at a time: Ctrl+C cancels the
|
package/dist/repl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,eAAO,MAAM,WAAW,YAAO,CAAC;AAEhC,MAAM,MAAM,mBAAmB,GAC3B,SAAS,GACT,MAAM,GACN,eAAe;AACjB,6EAA6E;GAC3E;IACE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEN,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC3D;AAED,eAAO,MAAM,iBAAiB,YAC5B,MAAM,EACN,SAAS,EACT,OAAO,EACP,OAAO,EACP,MAAM,EACN,MAAM,CACE,CAAC;AA0BX;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,mBAAmB,GAC3B,mBAAmB,CA2CrB;AAeD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC3D;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAgFnE"}
|