@cueloop/extension-api 0.1.0-alpha.16 → 0.1.0-alpha.17

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/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@cueloop/extension-api",
3
- "version": "0.1.0-alpha.16",
3
+ "version": "0.1.0-alpha.17",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./src/index.ts"
8
8
  },
9
9
  "dependencies": {
10
- "@cueloop/schema": "0.1.0-alpha.16"
10
+ "@cueloop/schema": "0.1.0-alpha.17"
11
11
  },
12
12
  "publishConfig": {
13
13
  "access": "public"
package/src/loader.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Extension discovery and loading (#10): zero-build TypeScript executed
2
+ * Extension discovery and loading: zero-build TypeScript executed
3
3
  * directly. Global user extensions always load; repo-local `.cueloop/
4
4
  * extensions/` loads only when the repo is trusted (persisted decisions
5
5
  * under the cueloop home).
@@ -51,29 +51,29 @@ export function grantTrust(home: string, repoRoot: string): void {
51
51
  function extensionFiles(dir: string): string[] {
52
52
  if (!existsSync(dir)) return [];
53
53
  return readdirSync(dir)
54
- .filter((f) => f.endsWith(".ts") || f.endsWith(".js"))
55
- .map((f) => join(dir, f))
54
+ .filter((fileName) => fileName.endsWith(".ts") || fileName.endsWith(".js"))
55
+ .map((fileName) => join(dir, fileName))
56
56
  .sort();
57
57
  }
58
58
 
59
- export async function loadExtensions(opts: LoadOptions): Promise<{ loaded: string[]; skipped: string[] }> {
59
+ export async function loadExtensions(options: LoadOptions): Promise<{ loaded: string[]; skipped: string[] }> {
60
60
  const loaded: string[] = [];
61
61
  const skipped: string[] = [];
62
62
  const files: { path: string; source: string }[] = [];
63
63
 
64
- for (const path of extensionFiles(opts.userDir ?? userExtensionsDir())) {
64
+ for (const path of extensionFiles(options.userDir ?? userExtensionsDir())) {
65
65
  files.push({ path, source: "user" });
66
66
  }
67
- if (opts.repoRoot) {
68
- const repoDir = join(opts.repoRoot, ".cueloop", "extensions");
67
+ if (options.repoRoot) {
68
+ const repoDir = join(options.repoRoot, ".cueloop", "extensions");
69
69
  const repoFiles = extensionFiles(repoDir);
70
70
  if (repoFiles.length) {
71
- const home = opts.home ?? join(homedir(), ".cueloop");
71
+ const home = options.home ?? join(homedir(), ".cueloop");
72
72
  const trusted =
73
- readTrust(home).trusted.includes(opts.repoRoot) ||
74
- (opts.confirmTrust ? await opts.confirmTrust(opts.repoRoot) : false);
73
+ readTrust(home).trusted.includes(options.repoRoot) ||
74
+ (options.confirmTrust ? await options.confirmTrust(options.repoRoot) : false);
75
75
  if (trusted) {
76
- grantTrust(home, opts.repoRoot);
76
+ grantTrust(home, options.repoRoot);
77
77
  for (const path of repoFiles) files.push({ path, source: "repo" });
78
78
  } else {
79
79
  skipped.push(...repoFiles);
@@ -83,12 +83,12 @@ export async function loadExtensions(opts: LoadOptions): Promise<{ loaded: strin
83
83
 
84
84
  for (const file of files) {
85
85
  try {
86
- const mod = (await import(file.path)) as { default?: ExtensionFactory };
87
- if (typeof mod.default !== "function") {
86
+ const extensionModule = (await import(file.path)) as { default?: ExtensionFactory };
87
+ if (typeof extensionModule.default !== "function") {
88
88
  skipped.push(file.path);
89
89
  continue;
90
90
  }
91
- await opts.registry.load(file.path, mod.default);
91
+ await options.registry.load(file.path, extensionModule.default);
92
92
  loaded.push(file.path);
93
93
  } catch {
94
94
  skipped.push(file.path);
@@ -48,7 +48,7 @@ describe("Registry", () => {
48
48
  api.on("session.resolved", () => {
49
49
  throw new Error("observer bug");
50
50
  });
51
- api.on("session.resolved", (s) => seen.push(s.id));
51
+ api.on("session.resolved", (session) => seen.push(session.id));
52
52
  });
53
53
  reg.emit("session.resolved", SESSION);
54
54
  expect(seen).toEqual(["ses_x"]);
package/src/registry.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The contribution registry (#10): registrations are plain data, attributed
2
+ * The contribution registry: registrations are plain data, attributed
3
3
  * per extension. Reserved app keybindings are rejected at registration so a
4
4
  * broken extension cannot shadow core grammar.
5
5
  */
@@ -44,19 +44,19 @@ export class Registry {
44
44
  registerRenderer(type, renderer) {
45
45
  record.renderers.set(type, renderer);
46
46
  },
47
- registerCommand(cmdName, registration) {
48
- record.commands.set(cmdName, registration);
47
+ registerCommand(commandName, registration) {
48
+ record.commands.set(commandName, registration);
49
49
  },
50
50
  registerKeybinding(registration) {
51
- const clash = registration.defaultKeys.find((k) => RESERVED_KEYS.has(k));
51
+ const clash = registration.defaultKeys.find((key) => RESERVED_KEYS.has(key));
52
52
  if (clash) {
53
53
  record.errors.push(`keybinding "${registration.action}" rejected: "${clash}" is reserved`);
54
54
  return;
55
55
  }
56
56
  record.keybindings.push(registration);
57
57
  },
58
- registerExporter(expName, exporter) {
59
- record.exporters.set(expName, exporter);
58
+ registerExporter(exporterName, exporter) {
59
+ record.exporters.set(exporterName, exporter);
60
60
  },
61
61
  on(event, handler) {
62
62
  const list = record.listeners.get(event) ?? [];
@@ -76,24 +76,24 @@ export class Registry {
76
76
 
77
77
  /** First-registered wins for renderers/commands; built-ins load first. */
78
78
  rendererFor(artifactType: string): ArtifactRenderer | undefined {
79
- for (const ext of this.extensions) {
80
- const r = ext.renderers.get(artifactType);
81
- if (r) return r;
79
+ for (const extension of this.extensions) {
80
+ const renderer = extension.renderers.get(artifactType);
81
+ if (renderer) return renderer;
82
82
  }
83
83
  return undefined;
84
84
  }
85
85
 
86
86
  commandFor(name: string): { extension: string; registration: CommandRegistration } | undefined {
87
- for (const ext of this.extensions) {
88
- const c = ext.commands.get(name);
89
- if (c) return { extension: ext.name, registration: c };
87
+ for (const extension of this.extensions) {
88
+ const command = extension.commands.get(name);
89
+ if (command) return { extension: extension.name, registration: command };
90
90
  }
91
91
  return undefined;
92
92
  }
93
93
 
94
94
  emit(event: string, session: ReviewSession): void {
95
- for (const ext of this.extensions) {
96
- for (const handler of ext.listeners.get(event) ?? []) {
95
+ for (const extension of this.extensions) {
96
+ for (const handler of extension.listeners.get(event) ?? []) {
97
97
  try {
98
98
  handler(session);
99
99
  } catch {
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The single typed extension contract (#10). This module is import-free
2
+ * The single typed extension contract. This module is import-free
3
3
  * beyond the schema: whatever a declaration file can reach gets published,
4
4
  * so the contract stays self-contained.
5
5
  *
@@ -32,14 +32,14 @@ export interface CommandContext {
32
32
 
33
33
  export interface CommandRegistration {
34
34
  description: string;
35
- handler(ctx: CommandContext, args: string): void | Promise<void>;
35
+ handler(context: CommandContext, args: string): void | Promise<void>;
36
36
  }
37
37
 
38
38
  export interface KeybindingRegistration {
39
39
  /** Action name; binds through the same [keys] config as built-ins. */
40
40
  action: string;
41
41
  defaultKeys: string[];
42
- handler(ctx: CommandContext): void | Promise<void>;
42
+ handler(context: CommandContext): void | Promise<void>;
43
43
  }
44
44
 
45
45
  /** Exporters ship resolved sessions somewhere (notes vaults, forges). */