@agentic-surfaces/cli 0.1.5 → 0.1.7

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.
Files changed (2) hide show
  1. package/dist/index.js +68 -2
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -1,9 +1,38 @@
1
- import { readFileSync, readdirSync } from "node:fs";
1
+ import { readFileSync, readdirSync, existsSync } from "node:fs";
2
2
  import { join, dirname, resolve } from "node:path";
3
3
  import { spawn } from "node:child_process";
4
4
  import { loadWorkflow, runWorkflowOnce, Scheduler, loadProjectConfig, buildWorkflowRunner, defaultRegistry } from "@agentic-surfaces/core";
5
- import { serve } from "@agentic-surfaces/server";
5
+ import { serve, StreamingObserver } from "@agentic-surfaces/server";
6
6
  import { buildServices } from "./services.js";
7
+ const CONFIG = "agentic-surfaces.config.yaml";
8
+ // Locate a project folder when none is given: check the dir, its ./agentic-surfaces
9
+ // subfolder (the repo-native convention), then walk up. Lets `agentic-surfaces`
10
+ // be run bare from a repo root and still find the config.
11
+ function discoverProjectDir(start) {
12
+ let dir = resolve(start);
13
+ for (;;) {
14
+ if (existsSync(join(dir, CONFIG)))
15
+ return dir;
16
+ if (existsSync(join(dir, "agentic-surfaces", CONFIG)))
17
+ return join(dir, "agentic-surfaces");
18
+ const parent = dirname(dir);
19
+ if (parent === dir)
20
+ return undefined;
21
+ dir = parent;
22
+ }
23
+ }
24
+ // Load every workflow yaml in a folder into a name→Workflow map.
25
+ function loadWorkflows(dir) {
26
+ const map = new Map();
27
+ for (const f of readdirSync(dir).filter((f) => f.endsWith(".yaml") && f !== CONFIG)) {
28
+ try {
29
+ const w = loadWorkflow(readFileSync(join(dir, f), "utf8"));
30
+ map.set(w.name, w);
31
+ }
32
+ catch { /* skip unparseable */ }
33
+ }
34
+ return map;
35
+ }
7
36
  // `--ui`: start the live dashboard (HTTP server + SSE) and return its
8
37
  // StreamingObserver so run lifecycle events stream to the browser.
9
38
  function startUi() {
@@ -46,6 +75,43 @@ function findProjectConfig(startDir) {
46
75
  export async function run(argv) {
47
76
  const [cmd, ...rest] = argv;
48
77
  try {
78
+ // Default / `ui`: launch the visual control surface. `agentic-surfaces`
79
+ // (no args) discovers the project from the cwd; `ui <dir>` is explicit.
80
+ // Workflows are listed + Run-able from the browser; cron ones also fire.
81
+ if (cmd === undefined || cmd === "ui") {
82
+ const arg = rest.find((a) => !a.startsWith("--"));
83
+ const dir = arg ? resolve(arg) : discoverProjectDir(process.cwd());
84
+ if (!dir) {
85
+ console.error(`no ${CONFIG} found (looked in . and ./agentic-surfaces, then up).\n pass a folder: agentic-surfaces ui <projectDir>`);
86
+ return 1;
87
+ }
88
+ const pc = loadProjectConfig(dir);
89
+ const workflowsDir = pc?.workflows ? join(dir, pc.workflows) : dir;
90
+ const allWorkflows = loadWorkflows(workflowsDir);
91
+ const registry = defaultRegistry();
92
+ const observer = new StreamingObserver();
93
+ const services = buildServices({ projectConfig: pc });
94
+ const runWorkflowFn = buildWorkflowRunner({ workflows: allWorkflows, registry, services, observer });
95
+ const servicesWithRunner = { ...services, runWorkflow: runWorkflowFn };
96
+ // Cron-triggered workflows fire on schedule too.
97
+ const sched = new Scheduler(servicesWithRunner, registry, observer);
98
+ for (const [, w] of allWorkflows)
99
+ sched.add(w);
100
+ sched.start();
101
+ const port = parseInt(process.env["FLOW_UI_PORT"] ?? "4000", 10);
102
+ const { port: actualPort } = serve({
103
+ port,
104
+ observer,
105
+ workflows: [...allWorkflows.values()],
106
+ onRun: (name) => runWorkflowFn(name, undefined),
107
+ });
108
+ const url = `http://127.0.0.1:${actualPort}`;
109
+ openBrowser(url);
110
+ console.log(`\n▶ agentic-surfaces — ${url}`);
111
+ console.log(` project: ${dir} · ${allWorkflows.size} workflow(s) · Ctrl-C to exit`);
112
+ await new Promise(() => { }); // serve until interrupted
113
+ return 0;
114
+ }
49
115
  if (cmd === "validate") {
50
116
  loadWorkflow(readFileSync(rest[0], "utf8"));
51
117
  console.log("OK:", rest[0]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentic-surfaces/cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -21,9 +21,9 @@
21
21
  "dist"
22
22
  ],
23
23
  "dependencies": {
24
- "@agentic-surfaces/core": "0.1.5",
25
- "@agentic-surfaces/agent": "0.1.5",
26
- "@agentic-surfaces/server": "0.1.5"
24
+ "@agentic-surfaces/core": "0.1.7",
25
+ "@agentic-surfaces/agent": "0.1.7",
26
+ "@agentic-surfaces/server": "0.1.7"
27
27
  },
28
28
  "scripts": {
29
29
  "build": "tsc -b",