@openagt/start 0.0.0-stage → 0.22.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Suleiman Shahbari
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/bin.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
package/dist/bin.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from './cli.js';
3
+ runCli(process.argv.slice(2))
4
+ .then(code => {
5
+ process.exitCode = code;
6
+ })
7
+ .catch((err) => {
8
+ console.error(err);
9
+ process.exitCode = 1;
10
+ });
11
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC1B,IAAI,CAAC,IAAI,CAAC,EAAE;IACX,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAA;AACzB,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AACtB,CAAC,CAAC,CAAA"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ import { type VersionFetcher } from './update-check.js';
2
+ /** Where the CLI writes. Injectable so tests capture output. */
3
+ export interface CliIO {
4
+ out: (line: string) => void;
5
+ err: (line: string) => void;
6
+ }
7
+ /** What the CLI itself accepts: three options, no verbs (D4). */
8
+ export interface CliArgs {
9
+ help: boolean;
10
+ version: boolean;
11
+ /** `--port <n>`: the port the dashboard binds. Default {@link DEFAULT_DAEMON_PORT}; `0` is ephemeral. */
12
+ port?: number;
13
+ error?: string;
14
+ }
15
+ /**
16
+ * Parse argv (without the node/script prefix). Pure and testable.
17
+ *
18
+ * Three options and nothing else: `--port` because it is the one thing a browser cannot be asked
19
+ * and a dashboard cannot serve about itself; `--help` and `--version` because a command with
20
+ * options owes the user both. The command runs no agent (#1774): a run is started
21
+ * from the dashboard, by the project's own start hook.
22
+ */
23
+ export declare function parseArgs(argv: string[]): CliArgs;
24
+ export declare function runCli(argv: string[], io?: CliIO): Promise<number>;
25
+ /**
26
+ * The startup footer every dashboard path prints (#312): where prompts come from, the version,
27
+ * and then — once npm answers — whether that version is the latest.
28
+ *
29
+ * The update line is deliberately not awaited before the static lines. #312 asks for the static
30
+ * info first, and the foreground path (bare `openagent`) blocks on the server forever, so a line
31
+ * printed after the await would never appear there at all. `checkForUpdate` is already forgiving:
32
+ * offline or slow (2.5s cap) resolves to 'unknown', which prints nothing.
33
+ */
34
+ export declare function printStartupFooter(io: CliIO, opts?: {
35
+ fetchLatest?: VersionFetcher;
36
+ }): Promise<void>;
37
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0D,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAM/G,gEAAgE;AAChE,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC5B;AAyBD,iEAAiE;AACjE,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,yGAAyG;IACzG,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAyBjD;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBnF;AAkCD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,cAAc,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAaxG"}
package/dist/cli.js ADDED
@@ -0,0 +1,137 @@
1
+ import { checkForUpdate, formatUpdateStatus, nodeVersionFetcher } from './update-check.js';
2
+ import { runDaemon, DEFAULT_DAEMON_PORT } from '@openagt/dashboard/serve';
3
+ import { handDownSkills } from './skills.js';
4
+ import { repositoryOf } from './project.js';
5
+ import { openagentVersion } from './version.js';
6
+ const defaultIO = {
7
+ out: line => process.stdout.write(line + '\n'),
8
+ err: line => process.stderr.write(line + '\n'),
9
+ };
10
+ const HELP = `OpenAgent — turnkey AI orchestration that wraps a coding agent (Claude Code or Codex).
11
+
12
+ Usage:
13
+ openagent Serve the dashboard in the foreground. Ctrl+C closes it; the server
14
+ logs stream to this terminal. Typed inside a Git repository, it adds
15
+ that repository to the dashboard's projects.
16
+
17
+ Options:
18
+ --port <n> Dashboard port (default: 4200).
19
+ -h, --help Show this help.
20
+ -v, --version Print the version.
21
+
22
+ The dashboard listens on this computer only. A phone, or another computer's OpenAgent, gets in
23
+ from Settings › Devices.
24
+
25
+ Everything else is the dashboard: it shows a project's runs from their files, and starts one
26
+ through the project's own start hook (.openagent/hooks.yml), which names the tool that runs it.`;
27
+ /**
28
+ * Parse argv (without the node/script prefix). Pure and testable.
29
+ *
30
+ * Three options and nothing else: `--port` because it is the one thing a browser cannot be asked
31
+ * and a dashboard cannot serve about itself; `--help` and `--version` because a command with
32
+ * options owes the user both. The command runs no agent (#1774): a run is started
33
+ * from the dashboard, by the project's own start hook.
34
+ */
35
+ export function parseArgs(argv) {
36
+ const opts = { help: false, version: false };
37
+ for (let i = 0; i < argv.length; i++) {
38
+ const arg = argv[i];
39
+ switch (arg) {
40
+ case '--help':
41
+ case '-h':
42
+ opts.help = true;
43
+ break;
44
+ case '--version':
45
+ case '-v':
46
+ opts.version = true;
47
+ break;
48
+ case '--port': {
49
+ const n = Number(argv[++i]);
50
+ if (Number.isInteger(n) && n >= 0)
51
+ opts.port = n;
52
+ else
53
+ opts.error ??= 'invalid --port: must be a non-negative integer';
54
+ break;
55
+ }
56
+ default:
57
+ // The first thing that could not be read is the one told: what follows an unknown option is its value, not a command.
58
+ opts.error ??= arg.startsWith('-') ? `unknown option: ${arg}` : `unknown command: ${arg}`;
59
+ }
60
+ }
61
+ return opts;
62
+ }
63
+ export async function runCli(argv, io = defaultIO) {
64
+ const args = parseArgs(argv);
65
+ if (args.error) {
66
+ io.err(args.error);
67
+ io.err('Run `openagent --help` for usage.');
68
+ return 2;
69
+ }
70
+ if (args.help) {
71
+ io.out(HELP);
72
+ return 0;
73
+ }
74
+ if (args.version) {
75
+ io.out(openagentVersion());
76
+ return 0;
77
+ }
78
+ // Everything else is bare `openagent`: serve the dashboard in the foreground until Ctrl-C.
79
+ return runForegroundDaemonCmd(args, io);
80
+ }
81
+ /**
82
+ * Bare `openagent`: run the dashboard server in the foreground (#456), so its logs and any
83
+ * server-thrown errors are visible and Ctrl+C stops it. Blocks until the server is signalled
84
+ * (SIGINT/SIGTERM).
85
+ */
86
+ async function runForegroundDaemonCmd(args, io) {
87
+ const cwd = process.cwd();
88
+ const port = args.port ?? DEFAULT_DAEMON_PORT;
89
+ try {
90
+ // Set in this process's own environment, so everything the dashboard starts inherits it.
91
+ await handDownSkills(process.env);
92
+ const project = await repositoryOf(cwd);
93
+ await runDaemon(cwd, {
94
+ port,
95
+ version: openagentVersion(),
96
+ ...(project !== undefined ? { project, onProjectAdded: (path) => io.out(`◆ project added: ${path}`) } : {}),
97
+ onListening: state => {
98
+ io.out(`◆ dashboard running: ${state.url}`);
99
+ io.out(' Ctrl+C to stop the dashboard. Server logs stream below.');
100
+ // #312 asks bare `openagent` to print the commands + version too. onListening is sync and
101
+ // runDaemon then blocks until signalled, so this is fire-and-forget by necessity: the
102
+ // update line lands a moment later, above the server logs.
103
+ void printStartupFooter(io);
104
+ },
105
+ });
106
+ }
107
+ catch (err) {
108
+ io.err(`could not start the dashboard (${err instanceof Error ? err.message : String(err)}).`);
109
+ return 1;
110
+ }
111
+ return 0;
112
+ }
113
+ /**
114
+ * The startup footer every dashboard path prints (#312): where prompts come from, the version,
115
+ * and then — once npm answers — whether that version is the latest.
116
+ *
117
+ * The update line is deliberately not awaited before the static lines. #312 asks for the static
118
+ * info first, and the foreground path (bare `openagent`) blocks on the server forever, so a line
119
+ * printed after the await would never appear there at all. `checkForUpdate` is already forgiving:
120
+ * offline or slow (2.5s cap) resolves to 'unknown', which prints nothing.
121
+ */
122
+ export function printStartupFooter(io, opts = {}) {
123
+ const version = openagentVersion();
124
+ io.out('');
125
+ io.out('Type a prompt on the dashboard to start an agent, or use:');
126
+ io.out(' openagent --help All options');
127
+ io.out('');
128
+ io.out(`OpenAgent v${version}`);
129
+ return checkForUpdate(version, opts.fetchLatest ?? nodeVersionFetcher())
130
+ .then(status => {
131
+ const line = formatUpdateStatus(status);
132
+ if (line)
133
+ io.out(line);
134
+ })
135
+ .catch(() => { });
136
+ }
137
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The Git repository a folder is in, by its top folder: the project `npx @openagt/start` adds when
3
+ * it is typed in that folder. Undefined outside a repository, where there is nothing to add.
4
+ */
5
+ export declare function repositoryOf(folder: string): Promise<string | undefined>;
6
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAI9E"}
@@ -0,0 +1,13 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const run = promisify(execFile);
4
+ /**
5
+ * The Git repository a folder is in, by its top folder: the project `npx @openagt/start` adds when
6
+ * it is typed in that folder. Undefined outside a repository, where there is nothing to add.
7
+ */
8
+ export async function repositoryOf(folder) {
9
+ const said = await run('git', ['rev-parse', '--show-toplevel'], { cwd: folder }).catch(() => undefined);
10
+ const top = said?.stdout.trim();
11
+ return top ? top : undefined;
12
+ }
13
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAE/B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc;IAC/C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;IACvG,MAAM,GAAG,GAAG,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;IAC/B,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;AAC9B,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The skills every run gets by default: what an agent needs in any project to work at all, read
3
+ * what earlier agents did, ask the person a question, and hand its work over on the project's git
4
+ * host; and the ones the dashboard has pages for, so a page never shows work an agent cannot do:
5
+ * split a task across subagents, the tickets and the queue. The one place they are named: the
6
+ * runner links whatever it is handed, and the dashboard gives every project their pages. Each is
7
+ * linked into a run's checkout, hidden from git, and a project's own skill of the same name takes
8
+ * its place (see the runner's `basic-skills.ts`).
9
+ */
10
+ export declare const DEFAULT_SKILLS: readonly string[];
11
+ /**
12
+ * Put the default skills in `env` under {@link SKILLS_ENV}: their packages' directories, resolved
13
+ * from this package's own install, joined by the path delimiter. One that is not installed is
14
+ * left out.
15
+ */
16
+ export declare function handDownSkills(env: NodeJS.ProcessEnv): Promise<void>;
17
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAkK,CAAA;AAE9M;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAa1E"}
package/dist/skills.js ADDED
@@ -0,0 +1,35 @@
1
+ import { realpath } from 'node:fs/promises';
2
+ import { createRequire } from 'node:module';
3
+ import { delimiter, dirname } from 'node:path';
4
+ import { SKILLS_ENV } from '@openagt/agent-data';
5
+ /**
6
+ * The skills every run gets by default: what an agent needs in any project to work at all, read
7
+ * what earlier agents did, ask the person a question, and hand its work over on the project's git
8
+ * host; and the ones the dashboard has pages for, so a page never shows work an agent cannot do:
9
+ * split a task across subagents, the tickets and the queue. The one place they are named: the
10
+ * runner links whatever it is handed, and the dashboard gives every project their pages. Each is
11
+ * linked into a run's checkout, hidden from git, and a project's own skill of the same name takes
12
+ * its place (see the runner's `basic-skills.ts`).
13
+ */
14
+ export const DEFAULT_SKILLS = ['@openagt/skill-logs', '@openagt/skill-question', '@openagt/skill-github', '@openagt/skill-orchestration', '@openagt/skill-tickets', '@openagt/skill-queue'];
15
+ /**
16
+ * Put the default skills in `env` under {@link SKILLS_ENV}: their packages' directories, resolved
17
+ * from this package's own install, joined by the path delimiter. One that is not installed is
18
+ * left out.
19
+ */
20
+ export async function handDownSkills(env) {
21
+ const require = createRequire(import.meta.url);
22
+ const dirs = [];
23
+ for (const name of DEFAULT_SKILLS) {
24
+ let manifest;
25
+ try {
26
+ manifest = require.resolve(`${name}/package.json`);
27
+ }
28
+ catch {
29
+ continue;
30
+ }
31
+ dirs.push(await realpath(dirname(manifest)));
32
+ }
33
+ env[SKILLS_ENV] = dirs.join(delimiter);
34
+ }
35
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAsB,CAAC,qBAAqB,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,wBAAwB,EAAE,sBAAsB,CAAC,CAAA;AAE9M;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAsB;IACzD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;IAC9C,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,IAAI,QAAgB,CAAA;QACpB,IAAI,CAAC;YACH,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,eAAe,CAAC,CAAA;QACpD,CAAC;QAAC,MAAM,CAAC;YACP,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC9C,CAAC;IACD,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AACxC,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * CLI "up-to-date?" check (#312): after the bare-`openagent` version footer,
3
+ * tell the user whether a newer version is published on npm. Display only;
4
+ * auto-update is a separate, deferred concern. Same seam + node-adapter +
5
+ * forgiving-on-error convention as `project.ts` (#380).
6
+ */
7
+ /** The npm package this CLI ships as; the registry key for the version check. */
8
+ export declare const PACKAGE_NAME = "@openagt/start";
9
+ /** Fetches the latest published version of `pkg`, or undefined on any failure. Injectable for tests. */
10
+ export type VersionFetcher = (pkg: string) => Promise<string | undefined>;
11
+ /**
12
+ * A {@link VersionFetcher} backed by the npm registry. GETs the packument and
13
+ * reads `dist-tags.latest`. A 2.5s AbortSignal.timeout caps it; any error /
14
+ * non-ok / offline yields undefined (the check silently degrades to "unknown").
15
+ */
16
+ export declare function nodeVersionFetcher(): VersionFetcher;
17
+ /** The result of an update check. */
18
+ export type UpdateStatus = {
19
+ kind: 'up-to-date';
20
+ current: string;
21
+ } | {
22
+ kind: 'update-available';
23
+ current: string;
24
+ latest: string;
25
+ } | {
26
+ kind: 'unknown';
27
+ current: string;
28
+ };
29
+ /**
30
+ * Compare two `major.minor.patch` versions numerically (a prerelease/build
31
+ * suffix after `-` or `+` is stripped, missing parts read as 0). Returns
32
+ * -1 / 0 / 1. No semver dependency.
33
+ */
34
+ export declare function compareVersions(a: string, b: string): number;
35
+ /**
36
+ * Check whether `current` is behind the latest published version. Uses the
37
+ * injected fetcher; a missing/failed fetch is 'unknown'. `current` >= latest is
38
+ * 'up-to-date' (so running a local build ahead of the registry never reads as
39
+ * "update available").
40
+ */
41
+ export declare function checkForUpdate(current: string, fetchLatest: VersionFetcher, pkg?: string): Promise<UpdateStatus>;
42
+ /** The one-line message to print for a status, or undefined for 'unknown' (print nothing). */
43
+ export declare function formatUpdateStatus(status: UpdateStatus): string | undefined;
44
+ //# sourceMappingURL=update-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,iFAAiF;AACjF,eAAO,MAAM,YAAY,mBAAmB,CAAA;AAE5C,wGAAwG;AACxG,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;AAEzE;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CAYnD;AAED,qCAAqC;AACrC,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAExC;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAW5D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,cAAc,EAC3B,GAAG,GAAE,MAAqB,GACzB,OAAO,CAAC,YAAY,CAAC,CAMvB;AAED,8FAA8F;AAC9F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAS3E"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * CLI "up-to-date?" check (#312): after the bare-`openagent` version footer,
3
+ * tell the user whether a newer version is published on npm. Display only;
4
+ * auto-update is a separate, deferred concern. Same seam + node-adapter +
5
+ * forgiving-on-error convention as `project.ts` (#380).
6
+ */
7
+ /** The npm package this CLI ships as; the registry key for the version check. */
8
+ export const PACKAGE_NAME = '@openagt/start';
9
+ /**
10
+ * A {@link VersionFetcher} backed by the npm registry. GETs the packument and
11
+ * reads `dist-tags.latest`. A 2.5s AbortSignal.timeout caps it; any error /
12
+ * non-ok / offline yields undefined (the check silently degrades to "unknown").
13
+ */
14
+ export function nodeVersionFetcher() {
15
+ return async (pkg) => {
16
+ try {
17
+ const res = await fetch(`https://registry.npmjs.org/${pkg}`, { signal: AbortSignal.timeout(2500) });
18
+ if (!res.ok)
19
+ return undefined;
20
+ const data = (await res.json());
21
+ const latest = data?.['dist-tags']?.latest;
22
+ return typeof latest === 'string' ? latest : undefined;
23
+ }
24
+ catch {
25
+ return undefined;
26
+ }
27
+ };
28
+ }
29
+ /**
30
+ * Compare two `major.minor.patch` versions numerically (a prerelease/build
31
+ * suffix after `-` or `+` is stripped, missing parts read as 0). Returns
32
+ * -1 / 0 / 1. No semver dependency.
33
+ */
34
+ export function compareVersions(a, b) {
35
+ const parse = (v) => (v.split(/[-+]/)[0] ?? '').split('.').map(n => parseInt(n, 10) || 0);
36
+ const pa = parse(a);
37
+ const pb = parse(b);
38
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
39
+ const na = pa[i] ?? 0;
40
+ const nb = pb[i] ?? 0;
41
+ if (na !== nb)
42
+ return na < nb ? -1 : 1;
43
+ }
44
+ return 0;
45
+ }
46
+ /**
47
+ * Check whether `current` is behind the latest published version. Uses the
48
+ * injected fetcher; a missing/failed fetch is 'unknown'. `current` >= latest is
49
+ * 'up-to-date' (so running a local build ahead of the registry never reads as
50
+ * "update available").
51
+ */
52
+ export async function checkForUpdate(current, fetchLatest, pkg = PACKAGE_NAME) {
53
+ const latest = await fetchLatest(pkg);
54
+ if (!latest)
55
+ return { kind: 'unknown', current };
56
+ return compareVersions(latest, current) > 0
57
+ ? { kind: 'update-available', current, latest }
58
+ : { kind: 'up-to-date', current };
59
+ }
60
+ /** The one-line message to print for a status, or undefined for 'unknown' (print nothing). */
61
+ export function formatUpdateStatus(status) {
62
+ switch (status.kind) {
63
+ case 'up-to-date':
64
+ return `✅ Up to date (v${status.current})`;
65
+ case 'update-available':
66
+ return `⬆️ Update available: v${status.latest} (you have v${status.current}). Run: npm i -g ${PACKAGE_NAME}`;
67
+ case 'unknown':
68
+ return undefined;
69
+ }
70
+ }
71
+ //# sourceMappingURL=update-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function openagentVersion(): string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAYA,wBAAgB,gBAAgB,IAAI,MAAM,CAYzC"}
@@ -0,0 +1,27 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /**
5
+ * OpenAgent's version: this package's own, the one people install, read from its `package.json`
6
+ * at runtime (#312). Handed to the dashboard, which tells it to machines and a phone.
7
+ * The compiled entry lives one level under the package root (`dist/` or
8
+ * `dist-test/`), so its `package.json` is always `../package.json`. Cached after
9
+ * the first read; falls back to `unknown` if the file is somehow unreadable.
10
+ */
11
+ let cachedVersion;
12
+ export function openagentVersion() {
13
+ if (cachedVersion !== undefined)
14
+ return cachedVersion;
15
+ try {
16
+ const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
17
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
18
+ // `unknown`, not `0.0.0`: the packages are unreleased and legitimately versioned `0.0.0`, so a
19
+ // numeric fallback would make a failed read indistinguishable from a correct one (#312).
20
+ cachedVersion = pkg.version ?? 'unknown';
21
+ }
22
+ catch {
23
+ cachedVersion = 'unknown';
24
+ }
25
+ return cachedVersion;
26
+ }
27
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC;;;;;;GAMG;AACH,IAAI,aAAiC,CAAA;AACrC,MAAM,UAAU,gBAAgB;IAC9B,IAAI,aAAa,KAAK,SAAS;QAAE,OAAO,aAAa,CAAA;IACrD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAA;QACnF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAyB,CAAA;QAC7E,+FAA+F;QAC/F,yFAAyF;QACzF,aAAa,GAAG,GAAG,CAAC,OAAO,IAAI,SAAS,CAAA;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,aAAa,GAAG,SAAS,CAAA;IAC3B,CAAC;IACD,OAAO,aAAa,CAAA;AACtB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,47 @@
1
1
  {
2
2
  "name": "@openagt/start",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.22.0",
4
+ "description": "OpenAgent in one command: the dashboard, with the skills every agent gets by default. A project's own skill of the same name takes a default's place.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/openagt/openagent.git",
9
+ "directory": "packages/start"
10
+ },
11
+ "type": "module",
12
+ "engines": {
13
+ "node": ">=22.12.0"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "bin": {
22
+ "openagent": "dist/bin.js"
23
+ },
24
+ "exports": {
25
+ "./package.json": "./package.json"
26
+ },
27
+ "dependencies": {
28
+ "@openagt/agent-data": "0.0.5",
29
+ "@openagt/dashboard": "0.22.0",
30
+ "@openagt/skill-github": "0.1.1",
31
+ "@openagt/skill-orchestration": "0.1.7",
32
+ "@openagt/skill-logs": "0.1.3",
33
+ "@openagt/skill-queue": "0.1.1",
34
+ "@openagt/skill-question": "0.1.0",
35
+ "@openagt/skill-tickets": "0.1.2"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^20.0.0",
39
+ "typescript": "^7.0.2"
40
+ },
41
+ "scripts": {
42
+ "build": "tsc -p tsconfig.build.json",
43
+ "typecheck": "tsc --noEmit",
44
+ "test": "tsc -p tsconfig.test.json && node --test --test-timeout=60000 'dist-test/**/*.test.js'",
45
+ "clean": "rm -rf dist dist-test"
46
+ }
6
47
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.