@nettee/beacon 0.3.5 → 0.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/README.md +25 -8
- package/deploy/io.nettee.beacon.plist.example +0 -2
- package/dist/cli-app.d.ts +31 -0
- package/dist/cli-app.js +6 -13
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +11 -8
- package/dist/daemon/config/channels.d.ts +11 -0
- package/dist/daemon/config/event-credentials.d.ts +6 -0
- package/dist/daemon/config/global.d.ts +40 -0
- package/dist/daemon/config/profile.d.ts +38 -0
- package/dist/daemon/config/registry.d.ts +3 -0
- package/dist/daemon/config/runtime-environment.d.ts +2 -0
- package/dist/daemon/config/secrets.d.ts +5 -0
- package/dist/daemon/config/yaml.d.ts +1 -0
- package/dist/daemon/dashboard/export.d.ts +11 -0
- package/dist/daemon/dashboard/profiles.d.ts +5 -0
- package/dist/daemon/dashboard/records.d.ts +25 -0
- package/dist/daemon/dashboard/server.d.ts +15 -0
- package/dist/daemon/dashboard/session-prompt.d.ts +4 -0
- package/dist/daemon/dashboard/static.d.ts +2 -0
- package/dist/daemon/doctor.d.ts +1 -0
- package/dist/daemon/domain/types.d.ts +137 -0
- package/dist/daemon/events/cloudevent.d.ts +25 -0
- package/dist/daemon/events/pipeline.d.ts +35 -0
- package/dist/daemon/events/server.d.ts +15 -0
- package/dist/daemon/events/store.d.ts +58 -0
- package/dist/daemon/feishu/doctor.d.ts +2 -0
- package/dist/daemon/feishu/final-outcome-card.d.ts +20 -0
- package/dist/daemon/feishu/gateway.d.ts +46 -0
- package/dist/daemon/feishu/intake.d.ts +37 -0
- package/dist/daemon/feishu/mentions.d.ts +37 -0
- package/dist/daemon/feishu/message-gateway.d.ts +4 -0
- package/dist/daemon/feishu/message-pipeline.d.ts +13 -0
- package/dist/daemon/feishu/reply-experiment.d.ts +3 -0
- package/dist/daemon/feishu/trigger-input.d.ts +36 -0
- package/dist/daemon/index.d.ts +6 -0
- package/dist/daemon/index.js +5 -0
- package/dist/daemon/manual-trigger.d.ts +2 -0
- package/dist/{manual-trigger.js → daemon/manual-trigger.js} +2 -1
- package/dist/daemon/message/gateway.d.ts +9 -0
- package/dist/daemon/outcome/content.d.ts +68 -0
- package/dist/daemon/outcome/doctor.d.ts +2 -0
- package/dist/{outcome → daemon/outcome}/doctor.js +2 -3
- package/dist/daemon/outcome/instructions.d.ts +3 -0
- package/dist/daemon/outcome/server.d.ts +20 -0
- package/dist/daemon/outcome/submit.d.ts +5 -0
- package/dist/daemon/run/create-pi-orchestrator.d.ts +17 -0
- package/dist/{run → daemon/run}/create-pi-orchestrator.js +1 -2
- package/dist/daemon/run/orchestrator.d.ts +61 -0
- package/dist/daemon/run/profile-runner.d.ts +9 -0
- package/dist/daemon/run/queue.d.ts +20 -0
- package/dist/daemon/runtime/pi-doctor.d.ts +1 -0
- package/dist/daemon/runtime/pi-outcome-extension.d.ts +43 -0
- package/dist/daemon/runtime/pi-rpc.d.ts +42 -0
- package/dist/{runtime → daemon/runtime}/pi-rpc.js +3 -1
- package/dist/daemon/runtime/system-prompt.d.ts +10 -0
- package/dist/daemon/runtime-options.d.ts +4 -0
- package/dist/daemon/runtime-options.js +1 -0
- package/dist/daemon/schedule/cron.d.ts +2 -0
- package/dist/daemon/schedule/cursor-store.d.ts +18 -0
- package/dist/daemon/schedule/loop.d.ts +17 -0
- package/dist/daemon/schedule/reconciler.d.ts +16 -0
- package/dist/daemon/schedule-trigger.d.ts +18 -0
- package/dist/{schedule-trigger.js → daemon/schedule-trigger.js} +2 -1
- package/dist/daemon/service.d.ts +4 -0
- package/dist/{service.js → daemon/service.js} +3 -1
- package/dist/daemon/state/trigger-store.d.ts +30 -0
- package/dist/version.d.ts +1 -0
- package/dist/web/assets/index-BP5xd2Iv.js +9 -0
- package/dist/web/assets/index-D3C6sw_J.css +2 -0
- package/dist/{dashboard/ui → web}/index.html +2 -2
- package/package.json +13 -25
- package/dist/dashboard/ui/assets/index-BNrf6SEW.css +0 -2
- package/dist/dashboard/ui/assets/index-DNeyL6DY.js +0 -9
- /package/dist/{config → daemon/config}/channels.js +0 -0
- /package/dist/{config → daemon/config}/event-credentials.js +0 -0
- /package/dist/{config → daemon/config}/global.js +0 -0
- /package/dist/{config → daemon/config}/profile.js +0 -0
- /package/dist/{config → daemon/config}/registry.js +0 -0
- /package/dist/{config → daemon/config}/runtime-environment.js +0 -0
- /package/dist/{config → daemon/config}/secrets.js +0 -0
- /package/dist/{config → daemon/config}/yaml.js +0 -0
- /package/dist/{dashboard → daemon/dashboard}/export.js +0 -0
- /package/dist/{dashboard → daemon/dashboard}/profiles.js +0 -0
- /package/dist/{dashboard → daemon/dashboard}/records.js +0 -0
- /package/dist/{dashboard → daemon/dashboard}/server.js +0 -0
- /package/dist/{dashboard → daemon/dashboard}/session-prompt.js +0 -0
- /package/dist/{dashboard → daemon/dashboard}/static.js +0 -0
- /package/dist/{doctor.js → daemon/doctor.js} +0 -0
- /package/dist/{domain → daemon/domain}/types.js +0 -0
- /package/dist/{events → daemon/events}/cloudevent.js +0 -0
- /package/dist/{events → daemon/events}/pipeline.js +0 -0
- /package/dist/{events → daemon/events}/server.js +0 -0
- /package/dist/{events → daemon/events}/store.js +0 -0
- /package/dist/{feishu → daemon/feishu}/doctor.js +0 -0
- /package/dist/{feishu → daemon/feishu}/final-outcome-card.js +0 -0
- /package/dist/{feishu → daemon/feishu}/gateway.js +0 -0
- /package/dist/{feishu → daemon/feishu}/intake.js +0 -0
- /package/dist/{feishu → daemon/feishu}/mentions.js +0 -0
- /package/dist/{feishu → daemon/feishu}/message-gateway.js +0 -0
- /package/dist/{feishu → daemon/feishu}/message-pipeline.js +0 -0
- /package/dist/{feishu → daemon/feishu}/reply-experiment.js +0 -0
- /package/dist/{feishu → daemon/feishu}/trigger-input.js +0 -0
- /package/dist/{message → daemon/message}/gateway.js +0 -0
- /package/dist/{outcome → daemon/outcome}/content.js +0 -0
- /package/dist/{outcome → daemon/outcome}/instructions.js +0 -0
- /package/dist/{outcome → daemon/outcome}/server.js +0 -0
- /package/dist/{outcome → daemon/outcome}/submit.js +0 -0
- /package/dist/{run → daemon/run}/orchestrator.js +0 -0
- /package/dist/{run → daemon/run}/profile-runner.js +0 -0
- /package/dist/{run → daemon/run}/queue.js +0 -0
- /package/dist/{runtime → daemon/runtime}/pi-doctor.js +0 -0
- /package/dist/{runtime → daemon/runtime}/pi-outcome-extension.js +0 -0
- /package/dist/{runtime → daemon/runtime}/system-prompt.js +0 -0
- /package/dist/{schedule → daemon/schedule}/cron.js +0 -0
- /package/dist/{schedule → daemon/schedule}/cursor-store.js +0 -0
- /package/dist/{schedule → daemon/schedule}/loop.js +0 -0
- /package/dist/{schedule → daemon/schedule}/reconciler.js +0 -0
- /package/dist/{state → daemon/state}/trigger-store.js +0 -0
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ deployment names its configuration explicitly:
|
|
|
36
36
|
|
|
37
37
|
```sh
|
|
38
38
|
beacon doctor
|
|
39
|
-
beacon serve
|
|
39
|
+
beacon serve
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
`doctor` validates every Profile and credential, obtains a Feishu tenant token, and runs a real Pi RPC smoke test. It does not create Beacon state records.
|
|
@@ -319,17 +319,19 @@ same host. Expose only the event endpoint, not Beacon's unauthenticated Dashboar
|
|
|
319
319
|
## Commands
|
|
320
320
|
|
|
321
321
|
```text
|
|
322
|
-
beacon serve --config <absolute-path>
|
|
322
|
+
beacon serve [--config <absolute-path>]
|
|
323
323
|
beacon doctor [--config <absolute-path>]
|
|
324
324
|
beacon trigger [--config <absolute-path>] --profile <id> --input -
|
|
325
325
|
beacon schedule trigger [--config <absolute-path>] --profile <id> --schedule <id>
|
|
326
326
|
beacon version
|
|
327
327
|
```
|
|
328
328
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
329
|
+
`serve`, `doctor`, `trigger`, and `schedule trigger` use `~/.beacon/config.yaml`
|
|
330
|
+
in the current running user's home directory when `--config` is omitted,
|
|
331
|
+
regardless of the working directory. An explicit override must be an absolute
|
|
332
|
+
path, for example `beacon serve --config /opt/beacon/config.yaml`.
|
|
333
|
+
Missing or invalid configuration and required dependency failures are reported
|
|
334
|
+
as errors with a nonzero exit status; Beacon does not fall back to another config.
|
|
333
335
|
|
|
334
336
|
An operator can run one Profile without Feishu delivery by piping input to `trigger`; the Final Outcome is printed to stdout:
|
|
335
337
|
|
|
@@ -448,7 +450,7 @@ Secrets and ephemeral Run Capability tokens are excluded from persisted records
|
|
|
448
450
|
|
|
449
451
|
## launchd
|
|
450
452
|
|
|
451
|
-
Edit [`deploy/io.nettee.beacon.plist.example`](deploy/io.nettee.beacon.plist.example) so every executable,
|
|
453
|
+
Edit [`deploy/io.nettee.beacon.plist.example`](deploy/io.nettee.beacon.plist.example) so every executable, working-directory, and log path is absolute. The example runs `beacon serve` and loads the running user's `~/.beacon/config.yaml`; add `--config` and an absolute path to `ProgramArguments` to override it. Create the log directory, copy the plist to `~/Library/LaunchAgents/io.nettee.beacon.plist`, then validate and load it:
|
|
452
454
|
|
|
453
455
|
Use `command -v beacon` after the global npm installation to find the absolute
|
|
454
456
|
CLI path for `ProgramArguments`. A Node version-manager upgrade can change that
|
|
@@ -512,7 +514,7 @@ pnpm bump-version patch
|
|
|
512
514
|
```
|
|
513
515
|
|
|
514
516
|
For an in-repository pull request that changes production CLI inputs under
|
|
515
|
-
`
|
|
517
|
+
`apps/`, `services/`, `packages/`, or workspace build configuration without changing
|
|
516
518
|
the package version, CI automatically commits a patch bump to the PR branch.
|
|
517
519
|
Test-only and documentation changes do not trigger a release. An explicit
|
|
518
520
|
version change takes precedence over the automatic patch bump, and CI rejects
|
|
@@ -549,3 +551,18 @@ a package to exist before Trusted Publishing can be configured. After the
|
|
|
549
551
|
The repository variable deliberately keeps publishing disabled during the
|
|
550
552
|
bootstrap merge. Subsequent versions publish from GitHub Actions with OIDC and
|
|
551
553
|
do not use a long-lived npm write token.
|
|
554
|
+
|
|
555
|
+
## Workspace layout
|
|
556
|
+
|
|
557
|
+
Beacon is a pnpm monorepo:
|
|
558
|
+
|
|
559
|
+
- `apps/cli`: the published `@nettee/beacon` command-line package and its version.
|
|
560
|
+
- `apps/web`: the React/Vite web application.
|
|
561
|
+
- `services/daemon`: scheduling, triggers, Agent execution, storage, and HTTP endpoints.
|
|
562
|
+
- `packages/shared`: browser-safe HTTP response contracts shared by daemon and web.
|
|
563
|
+
|
|
564
|
+
Run `pnpm install`, `pnpm build`, `pnpm typecheck`, and `pnpm test` from the repository root. The workspace builds dependencies before consumers. Run the built CLI with `node apps/cli/dist/cli.js serve`; it defaults to `~/.beacon/config.yaml`. For web development, run `pnpm --filter @nettee/beacon-web dev` alongside the daemon; Vite proxies API and run-export requests to port 46183.
|
|
565
|
+
|
|
566
|
+
The daemon and web are separate workspace packages, but the published CLI remains a single installable product. Its build assembles the daemon modules and web assets inside `apps/cli/dist`; external daemon runtime dependencies remain regular CLI dependencies and are checked for consistency during assembly. Internal packages are private and do not require separate registry releases. Run `pnpm build` before `npm pack ./apps/cli` or publishing from `apps/cli`. `pnpm test:package` checks an isolated installation.
|
|
567
|
+
|
|
568
|
+
`pnpm bump-version minor` updates `apps/cli/package.json`. Package separation preserves existing runtime behavior: `serve` starts the daemon and serves web assets in one process, and manual triggers still execute locally.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare const defaultConfigPath: string;
|
|
2
|
+
export type CliCommand = {
|
|
3
|
+
command: "serve";
|
|
4
|
+
config: string;
|
|
5
|
+
} | {
|
|
6
|
+
command: "doctor";
|
|
7
|
+
config: string;
|
|
8
|
+
} | {
|
|
9
|
+
command: "trigger";
|
|
10
|
+
config: string;
|
|
11
|
+
profile: string;
|
|
12
|
+
} | {
|
|
13
|
+
command: "schedule-trigger";
|
|
14
|
+
config: string;
|
|
15
|
+
profile: string;
|
|
16
|
+
schedule: string;
|
|
17
|
+
} | {
|
|
18
|
+
command: "version";
|
|
19
|
+
} | {
|
|
20
|
+
command: "outcome-submit";
|
|
21
|
+
};
|
|
22
|
+
export declare function parseCli(args: string[]): CliCommand;
|
|
23
|
+
export type CliDependencies = {
|
|
24
|
+
serve(config: string): Promise<void>;
|
|
25
|
+
doctor(config: string): Promise<void>;
|
|
26
|
+
trigger(config: string, profile: string, input: string): Promise<void>;
|
|
27
|
+
triggerSchedule(config: string, profile: string, schedule: string): Promise<void>;
|
|
28
|
+
submitOutcome(): Promise<void>;
|
|
29
|
+
version: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function runCli(command: CliCommand, dependencies: CliDependencies): Promise<void>;
|
package/dist/cli-app.js
CHANGED
|
@@ -3,18 +3,14 @@ import { isAbsolute, join } from "node:path";
|
|
|
3
3
|
export const defaultConfigPath = join(homedir(), ".beacon", "config.yaml");
|
|
4
4
|
function usage() {
|
|
5
5
|
throw new Error(`Usage:
|
|
6
|
-
beacon serve --config <absolute-path>
|
|
6
|
+
beacon serve [--config <absolute-path>]
|
|
7
7
|
beacon doctor [--config <absolute-path>]
|
|
8
8
|
beacon trigger [--config <absolute-path>] --profile <id> --input -
|
|
9
9
|
beacon schedule trigger [--config <absolute-path>] --profile <id> --schedule <id>
|
|
10
|
-
beacon version
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
usage();
|
|
15
|
-
if (!isAbsolute(args[1]))
|
|
16
|
-
throw new Error("Config path must be absolute");
|
|
17
|
-
return args[1];
|
|
10
|
+
beacon version
|
|
11
|
+
|
|
12
|
+
Config defaults to ~/.beacon/config.yaml in the current user's home directory.
|
|
13
|
+
An explicit --config path must be absolute.`);
|
|
18
14
|
}
|
|
19
15
|
function options(args) {
|
|
20
16
|
if (args.length % 2 !== 0)
|
|
@@ -42,10 +38,7 @@ export function parseCli(args) {
|
|
|
42
38
|
usage();
|
|
43
39
|
return { command: "version" };
|
|
44
40
|
}
|
|
45
|
-
if (command === "serve") {
|
|
46
|
-
return { command, config: requiredConfig(rest) };
|
|
47
|
-
}
|
|
48
|
-
if (command === "doctor") {
|
|
41
|
+
if (command === "serve" || command === "doctor") {
|
|
49
42
|
const values = options(rest);
|
|
50
43
|
if ([...values.keys()].some((key) => key !== "--config"))
|
|
51
44
|
usage();
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { runBeacon, runDoctor, runManualTrigger, runScheduleTrigger, submitOutcomeFromCli, } from "./daemon/index.js";
|
|
2
5
|
import { parseCli, runCli } from "./cli-app.js";
|
|
3
|
-
import { runDoctor } from "./doctor.js";
|
|
4
|
-
import { runManualTrigger } from "./manual-trigger.js";
|
|
5
|
-
import { submitOutcomeFromCli } from "./outcome/submit.js";
|
|
6
|
-
import { runScheduleTrigger } from "./schedule-trigger.js";
|
|
7
|
-
import { runBeacon } from "./service.js";
|
|
8
6
|
import { packageVersion } from "./version.js";
|
|
7
|
+
const beaconCliPath = fileURLToPath(import.meta.url);
|
|
8
|
+
const runtime = { beaconCliPath };
|
|
9
9
|
async function main() {
|
|
10
10
|
await runCli(parseCli(process.argv.slice(2)), {
|
|
11
|
-
serve: runBeacon,
|
|
11
|
+
serve: (config) => runBeacon(config, {
|
|
12
|
+
...runtime,
|
|
13
|
+
uiDirectory: join(dirname(beaconCliPath), "web"),
|
|
14
|
+
}),
|
|
12
15
|
doctor: runDoctor,
|
|
13
|
-
trigger: runManualTrigger,
|
|
14
|
-
triggerSchedule: runScheduleTrigger,
|
|
16
|
+
trigger: (config, profile, input) => runManualTrigger(config, profile, input, runtime),
|
|
17
|
+
triggerSchedule: (config, profile, schedule) => runScheduleTrigger(config, profile, schedule, runtime),
|
|
15
18
|
submitOutcome: submitOutcomeFromCli,
|
|
16
19
|
version: packageVersion,
|
|
17
20
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const channelNamePattern: RegExp;
|
|
2
|
+
export type Channel = {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
chatId: string;
|
|
6
|
+
};
|
|
7
|
+
export type ChannelRegistry = ReadonlyMap<string, Channel>;
|
|
8
|
+
export declare function defaultChannelsPath(homeDirectory?: string): string;
|
|
9
|
+
export declare function emptyChannelRegistry(): ChannelRegistry;
|
|
10
|
+
export declare function loadChannelRegistry(path: string): Promise<ChannelRegistry>;
|
|
11
|
+
export declare function resolveChannelName(name: string, channels: ChannelRegistry, channelsPath: string): Channel;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type GlobalConfig = {
|
|
2
|
+
path: string;
|
|
3
|
+
homeDirectory: string;
|
|
4
|
+
profilesDirectory: string;
|
|
5
|
+
secretsPath: string;
|
|
6
|
+
channelsPath: string;
|
|
7
|
+
runtimeEnvironmentPath: string;
|
|
8
|
+
pi: {
|
|
9
|
+
executable: string;
|
|
10
|
+
codingAgentDirectory: string;
|
|
11
|
+
sessionDirectory: string;
|
|
12
|
+
};
|
|
13
|
+
runs: {
|
|
14
|
+
maxConcurrent: number;
|
|
15
|
+
maxQueued: number;
|
|
16
|
+
timeoutSeconds: number;
|
|
17
|
+
terminateGraceSeconds: number;
|
|
18
|
+
};
|
|
19
|
+
scheduler: {
|
|
20
|
+
maxOccurrencesPerReconciliation: number;
|
|
21
|
+
};
|
|
22
|
+
events?: {
|
|
23
|
+
listen: string;
|
|
24
|
+
port: number;
|
|
25
|
+
maxBodyBytes: number;
|
|
26
|
+
maxPending: number;
|
|
27
|
+
credentialsPath: string;
|
|
28
|
+
};
|
|
29
|
+
dashboard: {
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
listen: string;
|
|
32
|
+
port: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export declare const defaultDashboard: {
|
|
36
|
+
readonly enabled: true;
|
|
37
|
+
readonly listen: "0.0.0.0";
|
|
38
|
+
readonly port: 46183;
|
|
39
|
+
};
|
|
40
|
+
export declare function loadGlobalConfig(path: string): Promise<GlobalConfig>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type EventListener } from "../events/cloudevent.js";
|
|
2
|
+
import { type ChannelRegistry } from "./channels.js";
|
|
3
|
+
export declare const profilePersonaFile = "persona.md";
|
|
4
|
+
export declare const profileTaskFile = "task.md";
|
|
5
|
+
export declare const workspaceProfileDirectoryName = ".beacon-profile";
|
|
6
|
+
export type DeliveryDestination = {
|
|
7
|
+
chatId: string;
|
|
8
|
+
name?: string | undefined;
|
|
9
|
+
description?: string | undefined;
|
|
10
|
+
};
|
|
11
|
+
export type Profile = {
|
|
12
|
+
id: string;
|
|
13
|
+
directory: string;
|
|
14
|
+
persona: string;
|
|
15
|
+
task: string;
|
|
16
|
+
workspace: string;
|
|
17
|
+
runtime: "pi";
|
|
18
|
+
model: {
|
|
19
|
+
provider: string;
|
|
20
|
+
id: string;
|
|
21
|
+
};
|
|
22
|
+
admin?: DeliveryDestination | undefined;
|
|
23
|
+
listener?: EventListener | undefined;
|
|
24
|
+
schedules: Array<{
|
|
25
|
+
id: string;
|
|
26
|
+
cron: string;
|
|
27
|
+
timezone: string;
|
|
28
|
+
input: string;
|
|
29
|
+
notify?: DeliveryDestination | undefined;
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
export type LoadProfileOptions = {
|
|
33
|
+
channels?: ChannelRegistry;
|
|
34
|
+
channelsPath?: string;
|
|
35
|
+
};
|
|
36
|
+
export declare function workspaceProfileDirectory(workspace: string): string;
|
|
37
|
+
export declare function loadProfile(profileId: string, profilesDirectory?: string, options?: LoadProfileOptions): Promise<Profile>;
|
|
38
|
+
export declare function profileAdminChatId(profile: Profile): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseStrictYaml(path: string): Promise<unknown>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type SessionExportRequest = {
|
|
2
|
+
executable: string;
|
|
3
|
+
sessionDirectory: string;
|
|
4
|
+
runId: string;
|
|
5
|
+
sessionPath: string;
|
|
6
|
+
/** Beacon `--system-prompt` text for this Run, used when JSONL has no system line. */
|
|
7
|
+
systemPrompt?: string | undefined;
|
|
8
|
+
timeoutMs?: number | undefined;
|
|
9
|
+
};
|
|
10
|
+
export declare function resolveSessionJsonl(sessionDirectory: string, runId: string, sessionPath: string): Promise<string>;
|
|
11
|
+
export declare function exportSessionHtml(request: SessionExportRequest): Promise<string>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ProfileDetailView, ProfileListItem } from "@nettee/beacon-shared";
|
|
2
|
+
export type { ProfileDetailView, ProfileListenerView, ProfileListItem, ProfileNotifyView, ProfileScheduleView, } from "@nettee/beacon-shared";
|
|
3
|
+
export declare function isProfileId(value: string): boolean;
|
|
4
|
+
export declare function listProfileViews(profilesDirectory: string): Promise<ProfileListItem[]>;
|
|
5
|
+
export declare function getProfileDetailView(profilesDirectory: string, profileId: string): Promise<ProfileDetailView | null>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RunRow } from "@nettee/beacon-shared";
|
|
2
|
+
import type { FeedbackRecord } from "../domain/types.js";
|
|
3
|
+
export declare const runIdPattern: RegExp;
|
|
4
|
+
export type RunSummary = {
|
|
5
|
+
profileId: string;
|
|
6
|
+
triggerKey: string;
|
|
7
|
+
acceptedAt: string;
|
|
8
|
+
kind: string;
|
|
9
|
+
scheduleId: string | undefined;
|
|
10
|
+
eventSource?: string | undefined;
|
|
11
|
+
eventType?: string | undefined;
|
|
12
|
+
hasNotifyTarget: boolean;
|
|
13
|
+
runId: string | undefined;
|
|
14
|
+
state: string | undefined;
|
|
15
|
+
failureCode: string | undefined;
|
|
16
|
+
deliveryState: string | undefined;
|
|
17
|
+
sessionPath: string | undefined;
|
|
18
|
+
hasSessionFile: boolean;
|
|
19
|
+
systemPrompt: string | undefined;
|
|
20
|
+
feedback: FeedbackRecord | undefined;
|
|
21
|
+
};
|
|
22
|
+
export declare function listRunSummaries(profilesDirectory: string): Promise<RunSummary[]>;
|
|
23
|
+
export declare function kindLabel(row: Pick<RunSummary, "kind" | "scheduleId" | "eventSource" | "eventType">): string;
|
|
24
|
+
export declare function toRunListItem(row: RunSummary): RunRow;
|
|
25
|
+
export declare function findRunSummary(profilesDirectory: string, runId: string): Promise<RunSummary | undefined>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type DashboardOptions = {
|
|
2
|
+
listen: string;
|
|
3
|
+
port: number;
|
|
4
|
+
profilesDirectory: string;
|
|
5
|
+
sessionDirectory: string;
|
|
6
|
+
piExecutable: string;
|
|
7
|
+
exportTimeoutMs?: number | undefined;
|
|
8
|
+
uiDirectory?: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
export type DashboardServer = {
|
|
11
|
+
port: number;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
export declare function defaultUiDirectory(): string;
|
|
15
|
+
export declare function startDashboard(options: DashboardOptions): Promise<DashboardServer>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Prefer a JSONL system message; otherwise the Beacon-owned `--system-prompt` text. */
|
|
2
|
+
export declare function pickExportedSystemPrompt(jsonl: string, beaconOwned?: string | undefined): string | undefined;
|
|
3
|
+
export declare function systemPromptFromJsonl(jsonl: string): string | undefined;
|
|
4
|
+
export declare function fillExportedHtmlSystemPrompt(html: string, systemPrompt: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runDoctor(configPath: string): Promise<void>;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { CloudEvent } from "../events/cloudevent.js";
|
|
2
|
+
export type ReplyDeliveryTarget = {
|
|
3
|
+
kind: "reply";
|
|
4
|
+
messageId: string;
|
|
5
|
+
};
|
|
6
|
+
export type ChatDeliveryTarget = {
|
|
7
|
+
kind: "chat";
|
|
8
|
+
chatId: string;
|
|
9
|
+
};
|
|
10
|
+
export type LocalStdoutDeliveryTarget = {
|
|
11
|
+
kind: "local_stdout";
|
|
12
|
+
};
|
|
13
|
+
export type DeliveryTarget = ReplyDeliveryTarget | ChatDeliveryTarget | LocalStdoutDeliveryTarget;
|
|
14
|
+
export type MessageSnapshot = {
|
|
15
|
+
messageId: string;
|
|
16
|
+
messageType: string;
|
|
17
|
+
senderType: string;
|
|
18
|
+
senderId?: string | undefined;
|
|
19
|
+
content: unknown;
|
|
20
|
+
};
|
|
21
|
+
export type FeishuMessageInput = {
|
|
22
|
+
kind: "feishu_message";
|
|
23
|
+
eventId: string;
|
|
24
|
+
chatType: "p2p" | "group";
|
|
25
|
+
quotedMessages: MessageSnapshot[];
|
|
26
|
+
currentMessage: MessageSnapshot;
|
|
27
|
+
};
|
|
28
|
+
export type ScheduleInput = {
|
|
29
|
+
kind: "schedule";
|
|
30
|
+
scheduleId: string;
|
|
31
|
+
scheduledFor: string;
|
|
32
|
+
text: string;
|
|
33
|
+
};
|
|
34
|
+
export type ManualInput = {
|
|
35
|
+
kind: "manual";
|
|
36
|
+
text: string;
|
|
37
|
+
};
|
|
38
|
+
export type EventInput = {
|
|
39
|
+
kind: "event";
|
|
40
|
+
event: CloudEvent;
|
|
41
|
+
};
|
|
42
|
+
export type TriggerInput = FeishuMessageInput | ScheduleInput | ManualInput | EventInput;
|
|
43
|
+
export declare const failureCodes: readonly ["config_invalid", "secret_invalid", "gateway_terminal", "trigger_persist_failed", "trigger_normalization_failed", "schedule_state_invalid", "capacity_exceeded", "runtime_spawn_failed", "runtime_protocol_error", "runtime_timeout", "runtime_exit_failed", "outcome_missing", "outcome_invalid", "service_interrupted", "delivery_api_failed", "delivery_interrupted"];
|
|
44
|
+
export type FailureCode = (typeof failureCodes)[number];
|
|
45
|
+
export type RunState = "queued" | "starting" | "running" | "succeeded" | "failed";
|
|
46
|
+
export type DeliveryState = "pending" | "delivering" | "delivered" | "failed";
|
|
47
|
+
export type Failure = {
|
|
48
|
+
code: FailureCode;
|
|
49
|
+
summary: string;
|
|
50
|
+
};
|
|
51
|
+
export type TextReplyContent = {
|
|
52
|
+
kind: "text";
|
|
53
|
+
text: string;
|
|
54
|
+
};
|
|
55
|
+
export type NoReplyContent = {
|
|
56
|
+
kind: "no_reply";
|
|
57
|
+
reason: string;
|
|
58
|
+
};
|
|
59
|
+
export type CardContent = {
|
|
60
|
+
kind: "card";
|
|
61
|
+
title: string;
|
|
62
|
+
content: string;
|
|
63
|
+
buttons: Array<{
|
|
64
|
+
label: string;
|
|
65
|
+
url: string;
|
|
66
|
+
}>;
|
|
67
|
+
};
|
|
68
|
+
/** Text, silent, or a `reply_card` interactive message on the conversational channel. */
|
|
69
|
+
export type ReplyContent = TextReplyContent | NoReplyContent | CardContent;
|
|
70
|
+
export type FinalOutcomeContent = {
|
|
71
|
+
reply: ReplyContent;
|
|
72
|
+
notify?: CardContent | undefined;
|
|
73
|
+
};
|
|
74
|
+
export declare const feedbackPriorities: readonly ["high", "medium"];
|
|
75
|
+
export type FeedbackPriority = (typeof feedbackPriorities)[number];
|
|
76
|
+
export type FeedbackItem = {
|
|
77
|
+
priority: FeedbackPriority;
|
|
78
|
+
summary: string;
|
|
79
|
+
};
|
|
80
|
+
export type FeedbackContent = {
|
|
81
|
+
items: FeedbackItem[];
|
|
82
|
+
};
|
|
83
|
+
export type FeedbackRecord = {
|
|
84
|
+
items: FeedbackItem[];
|
|
85
|
+
submittedAt: string;
|
|
86
|
+
};
|
|
87
|
+
export type DeliveryContent = TextReplyContent | CardContent;
|
|
88
|
+
export type RunRecord = {
|
|
89
|
+
runId: string;
|
|
90
|
+
/** Pi session ID. Absent only on records written before session persistence. */
|
|
91
|
+
sessionId?: string | undefined;
|
|
92
|
+
/** Dedicated directory containing this Run's Pi session JSONL file. */
|
|
93
|
+
sessionPath?: string | undefined;
|
|
94
|
+
state: RunState;
|
|
95
|
+
queuedAt: string;
|
|
96
|
+
startedAt?: string | undefined;
|
|
97
|
+
finishedAt?: string | undefined;
|
|
98
|
+
provider: string;
|
|
99
|
+
model: string;
|
|
100
|
+
workspace: string;
|
|
101
|
+
promptDigest: string;
|
|
102
|
+
/** Full `--system-prompt` text sent to Pi. Absent on records written before this field. */
|
|
103
|
+
systemPrompt?: string | undefined;
|
|
104
|
+
failure?: Failure | undefined;
|
|
105
|
+
};
|
|
106
|
+
export type FinalOutcomeRecord = {
|
|
107
|
+
origin: "agent" | "beacon_failure";
|
|
108
|
+
content: FinalOutcomeContent;
|
|
109
|
+
submittedAt: string;
|
|
110
|
+
};
|
|
111
|
+
export type DeliveryRecord = {
|
|
112
|
+
deliveryId: string;
|
|
113
|
+
target: DeliveryTarget;
|
|
114
|
+
state: DeliveryState;
|
|
115
|
+
startedAt?: string | undefined;
|
|
116
|
+
finishedAt?: string | undefined;
|
|
117
|
+
providerRequestId?: string | undefined;
|
|
118
|
+
failure?: Failure | undefined;
|
|
119
|
+
};
|
|
120
|
+
export type TriggerRecord = {
|
|
121
|
+
version: 1;
|
|
122
|
+
triggerKey: string;
|
|
123
|
+
triggerId: string;
|
|
124
|
+
profileId: string;
|
|
125
|
+
sourceKey: string[];
|
|
126
|
+
acceptedAt: string;
|
|
127
|
+
target: DeliveryTarget;
|
|
128
|
+
notifyTarget?: DeliveryTarget | undefined;
|
|
129
|
+
input?: TriggerInput | undefined;
|
|
130
|
+
ingress?: Record<string, unknown> | undefined;
|
|
131
|
+
run?: RunRecord | undefined;
|
|
132
|
+
finalOutcome?: FinalOutcomeRecord | undefined;
|
|
133
|
+
/** Present only when the Agent called `submit_feedback`. */
|
|
134
|
+
feedback?: FeedbackRecord | undefined;
|
|
135
|
+
delivery?: DeliveryRecord | undefined;
|
|
136
|
+
notifyDelivery?: DeliveryRecord | undefined;
|
|
137
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const eventSourceSchema: z.ZodString;
|
|
3
|
+
export type EventListener = {
|
|
4
|
+
sources: string[];
|
|
5
|
+
types: string[];
|
|
6
|
+
notify?: {
|
|
7
|
+
chatId: string;
|
|
8
|
+
name?: string | undefined;
|
|
9
|
+
description?: string | undefined;
|
|
10
|
+
} | undefined;
|
|
11
|
+
};
|
|
12
|
+
export declare const cloudEventSchema: z.ZodObject<{
|
|
13
|
+
specversion: z.ZodLiteral<"1.0">;
|
|
14
|
+
id: z.ZodString;
|
|
15
|
+
source: z.ZodString;
|
|
16
|
+
type: z.ZodString;
|
|
17
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
18
|
+
time: z.ZodOptional<z.ZodISODateTime>;
|
|
19
|
+
dataschema: z.ZodOptional<z.ZodString>;
|
|
20
|
+
datacontenttype: z.ZodOptional<z.ZodString>;
|
|
21
|
+
data: z.ZodOptional<z.ZodJSONSchema>;
|
|
22
|
+
}, z.core.$catchall<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber]>>>;
|
|
23
|
+
export type CloudEvent = z.infer<typeof cloudEventSchema>;
|
|
24
|
+
export declare function parseCloudEvent(input: unknown): CloudEvent;
|
|
25
|
+
export declare function matchesListener(event: CloudEvent, listener: EventListener): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { EventProducer } from "../config/event-credentials.js";
|
|
2
|
+
import type { Profile } from "../config/profile.js";
|
|
3
|
+
import type { TriggerInput } from "../domain/types.js";
|
|
4
|
+
import type { TriggerStore } from "../state/trigger-store.js";
|
|
5
|
+
import { type CloudEvent } from "./cloudevent.js";
|
|
6
|
+
import { type EventRecord, type EventStore } from "./store.js";
|
|
7
|
+
export type EventContext = {
|
|
8
|
+
profile: Profile;
|
|
9
|
+
store: TriggerStore;
|
|
10
|
+
orchestrator: {
|
|
11
|
+
process(key: string, normalize: () => Promise<TriggerInput>): Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export declare class EventPipeline {
|
|
15
|
+
private readonly options;
|
|
16
|
+
private work;
|
|
17
|
+
private requested;
|
|
18
|
+
private stopped;
|
|
19
|
+
private failure;
|
|
20
|
+
constructor(options: {
|
|
21
|
+
store: EventStore;
|
|
22
|
+
contexts: EventContext[];
|
|
23
|
+
maxPending: number;
|
|
24
|
+
onFatal(error: Error): void;
|
|
25
|
+
});
|
|
26
|
+
accept(event: CloudEvent, producer: EventProducer): Promise<{
|
|
27
|
+
created: boolean;
|
|
28
|
+
record: EventRecord;
|
|
29
|
+
}>;
|
|
30
|
+
/** Call after Profile orchestrator recovery and after the HTTP listener binds. */
|
|
31
|
+
wake(): void;
|
|
32
|
+
private pump;
|
|
33
|
+
close(): Promise<void>;
|
|
34
|
+
drain(): Promise<void>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { EventProducer } from "../config/event-credentials.js";
|
|
2
|
+
import type { EventPipeline } from "./pipeline.js";
|
|
3
|
+
import { type EventStore } from "./store.js";
|
|
4
|
+
export declare function startEventServer(options: {
|
|
5
|
+
listen: string;
|
|
6
|
+
port: number;
|
|
7
|
+
maxBodyBytes: number;
|
|
8
|
+
producers: EventProducer[];
|
|
9
|
+
pipeline: EventPipeline;
|
|
10
|
+
store: EventStore;
|
|
11
|
+
onFatal(error: Error): void;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
port: number;
|
|
14
|
+
close(): Promise<void>;
|
|
15
|
+
}>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type CloudEvent } from "./cloudevent.js";
|
|
3
|
+
declare const recipientSchema: z.ZodObject<{
|
|
4
|
+
profileId: z.ZodString;
|
|
5
|
+
chatId: z.ZodString;
|
|
6
|
+
notifyChatId: z.ZodOptional<z.ZodString>;
|
|
7
|
+
triggerId: z.ZodOptional<z.ZodString>;
|
|
8
|
+
}, z.core.$strict>;
|
|
9
|
+
declare const recordSchema: z.ZodObject<{
|
|
10
|
+
version: z.ZodLiteral<1>;
|
|
11
|
+
receiptId: z.ZodString;
|
|
12
|
+
producerId: z.ZodString;
|
|
13
|
+
acceptedAt: z.ZodString;
|
|
14
|
+
event: z.ZodObject<{
|
|
15
|
+
specversion: z.ZodLiteral<"1.0">;
|
|
16
|
+
id: z.ZodString;
|
|
17
|
+
source: z.ZodString;
|
|
18
|
+
type: z.ZodString;
|
|
19
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
20
|
+
time: z.ZodOptional<z.ZodISODateTime>;
|
|
21
|
+
dataschema: z.ZodOptional<z.ZodString>;
|
|
22
|
+
datacontenttype: z.ZodOptional<z.ZodString>;
|
|
23
|
+
data: z.ZodOptional<z.ZodJSONSchema>;
|
|
24
|
+
}, z.core.$catchall<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber]>>>;
|
|
25
|
+
recipients: z.ZodArray<z.ZodObject<{
|
|
26
|
+
profileId: z.ZodString;
|
|
27
|
+
chatId: z.ZodString;
|
|
28
|
+
notifyChatId: z.ZodOptional<z.ZodString>;
|
|
29
|
+
triggerId: z.ZodOptional<z.ZodString>;
|
|
30
|
+
}, z.core.$strict>>;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
export type EventRecipient = z.infer<typeof recipientSchema>;
|
|
33
|
+
export type EventRecord = z.infer<typeof recordSchema>;
|
|
34
|
+
export declare class EventIntakeError extends Error {
|
|
35
|
+
readonly status: number;
|
|
36
|
+
constructor(status: number, message: string);
|
|
37
|
+
}
|
|
38
|
+
export declare function eventStatus(record: EventRecord): "unmatched" | "pending" | "dispatched";
|
|
39
|
+
/** Single service owner; serialized read/modify/write, atomic durable snapshots. */
|
|
40
|
+
export declare class EventStore {
|
|
41
|
+
readonly directory: string;
|
|
42
|
+
private tail;
|
|
43
|
+
constructor(directory: string);
|
|
44
|
+
private exclusive;
|
|
45
|
+
private prepare;
|
|
46
|
+
private path;
|
|
47
|
+
private read;
|
|
48
|
+
private records;
|
|
49
|
+
private write;
|
|
50
|
+
accept(event: CloudEvent, producerId: string, recipients: EventRecipient[], maxPending: number): Promise<{
|
|
51
|
+
created: boolean;
|
|
52
|
+
record: EventRecord;
|
|
53
|
+
}>;
|
|
54
|
+
get(id: string): Promise<EventRecord | undefined>;
|
|
55
|
+
pending(): Promise<EventRecord[]>;
|
|
56
|
+
markDispatched(id: string, profileId: string, triggerId: string): Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
export {};
|