runline 0.7.4 → 0.7.6

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.
@@ -1,11 +1,21 @@
1
1
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { dirname, join, resolve } from "node:path";
4
- import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import { fileURLToPath } from "node:url";
5
+ import { createJiti } from "jiti";
5
6
  import { findConfigDir } from "../config/loader.js";
6
7
  import { resolvePluginExport } from "./api.js";
7
8
  import { registry } from "./registry.js";
8
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const jiti = createJiti(import.meta.url, {
11
+ moduleCache: false,
12
+ interopDefault: true,
13
+ tryNative: false,
14
+ alias: {
15
+ runline: new URL("../index.js", import.meta.url).pathname,
16
+ "runline/utils/cli": new URL("../utils/cli.js", import.meta.url).pathname,
17
+ },
18
+ });
9
19
  export async function loadPluginFromPath(path) {
10
20
  let absPath = resolve(path);
11
21
  if (existsSync(absPath) && statSync(absPath).isDirectory()) {
@@ -34,9 +44,16 @@ export async function loadPluginFromPath(path) {
34
44
  throw new Error(`No entry point found in ${absPath}`);
35
45
  }
36
46
  }
37
- const mod = await import(pathToFileURL(absPath).href);
47
+ // Plugins may live outside the project/package tree. Load them
48
+ // through Runline's module context so documented imports like
49
+ // `from "runline"` work without requiring a node_modules folder next
50
+ // to the plugin file.
51
+ const mod = (await jiti.import(absPath));
38
52
  const pluginId = absPath.replace(/.*\//, "").replace(/\.(ts|js)$/, "");
39
- return resolvePluginExport(mod.default, pluginId);
53
+ const pluginExport = typeof mod === "object" && mod !== null && "default" in mod
54
+ ? mod.default
55
+ : mod;
56
+ return resolvePluginExport(pluginExport, pluginId);
40
57
  }
41
58
  async function loadFromDirectory(dir) {
42
59
  const plugins = [];
@@ -473,6 +473,103 @@ export default function github(rl) {
473
473
  },
474
474
  });
475
475
  // ── Repository ──────────────────────────────────────
476
+ rl.registerAction("commit.list", {
477
+ description: "List repository commits, including latest commits on a branch or path",
478
+ inputSchema: {
479
+ owner: {
480
+ type: "string",
481
+ required: true,
482
+ description: "Repository owner",
483
+ },
484
+ repo: { type: "string", required: true, description: "Repository name" },
485
+ sha: {
486
+ type: "string",
487
+ required: false,
488
+ description: "SHA or branch to start listing commits from",
489
+ },
490
+ path: {
491
+ type: "string",
492
+ required: false,
493
+ description: "Only commits containing this file path",
494
+ },
495
+ author: {
496
+ type: "string",
497
+ required: false,
498
+ description: "GitHub username or email address",
499
+ },
500
+ since: {
501
+ type: "string",
502
+ required: false,
503
+ description: "Only commits after this ISO 8601 timestamp",
504
+ },
505
+ until: {
506
+ type: "string",
507
+ required: false,
508
+ description: "Only commits before this ISO 8601 timestamp",
509
+ },
510
+ perPage: {
511
+ type: "number",
512
+ required: false,
513
+ description: "Results per page (max: 100)",
514
+ },
515
+ page: { type: "number", required: false, description: "Page number" },
516
+ },
517
+ async execute(input, ctx) {
518
+ const { owner, repo, sha, path, author, since, until, perPage, page } = (input ?? {});
519
+ const qs = {};
520
+ if (sha)
521
+ qs.sha = sha;
522
+ if (path)
523
+ qs.path = path;
524
+ if (author)
525
+ qs.author = author;
526
+ if (since)
527
+ qs.since = since;
528
+ if (until)
529
+ qs.until = until;
530
+ if (perPage)
531
+ qs.per_page = perPage;
532
+ if (page)
533
+ qs.page = page;
534
+ return gh(ctx, "GET", `/repos/${owner}/${repo}/commits`, undefined, qs);
535
+ },
536
+ });
537
+ rl.registerAction("commit.get", {
538
+ description: "Get a repository commit by SHA, branch, or tag ref",
539
+ inputSchema: {
540
+ owner: {
541
+ type: "string",
542
+ required: true,
543
+ description: "Repository owner",
544
+ },
545
+ repo: { type: "string", required: true, description: "Repository name" },
546
+ ref: {
547
+ type: "string",
548
+ required: true,
549
+ description: "Commit SHA, branch name, or tag name",
550
+ },
551
+ },
552
+ async execute(input, ctx) {
553
+ const { owner, repo, ref } = input;
554
+ return gh(ctx, "GET", `/repos/${owner}/${repo}/commits/${encodeURIComponent(String(ref))}`);
555
+ },
556
+ });
557
+ rl.registerAction("branch.get", {
558
+ description: "Get a repository branch, including its latest commit",
559
+ inputSchema: {
560
+ owner: {
561
+ type: "string",
562
+ required: true,
563
+ description: "Repository owner",
564
+ },
565
+ repo: { type: "string", required: true, description: "Repository name" },
566
+ branch: { type: "string", required: true, description: "Branch name" },
567
+ },
568
+ async execute(input, ctx) {
569
+ const { owner, repo, branch } = input;
570
+ return gh(ctx, "GET", `/repos/${owner}/${repo}/branches/${encodeURIComponent(String(branch))}`);
571
+ },
572
+ });
476
573
  rl.registerAction("repository.get", {
477
574
  description: "Get repository details",
478
575
  inputSchema: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runline",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "Code mode for agents — turn any API or command into a callable action",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -65,6 +65,7 @@
65
65
  "dependencies": {
66
66
  "chalk": "^5.6.2",
67
67
  "commander": "^14.0.3",
68
+ "jiti": "^2.7.0",
68
69
  "proper-lockfile": "^4.1.2",
69
70
  "quickjs-emscripten": "^0.32.0",
70
71
  "rrule": "^2.8.1"