@pellux/goodvibes-agent 0.1.70 → 0.1.72
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/CHANGELOG.md +12 -0
- package/README.md +3 -3
- package/docs/README.md +2 -2
- package/docs/getting-started.md +1 -1
- package/docs/runtime-connection.md +37 -0
- package/package.json +43 -2
- package/src/agent/skill-discovery.ts +119 -0
- package/src/cli/config-overrides.ts +1 -5
- package/src/cli/entrypoint.ts +0 -6
- package/src/cli/help.ts +0 -43
- package/src/cli/index.ts +0 -2
- package/src/cli/management-commands.ts +1 -109
- package/src/cli/management.ts +1 -32
- package/src/cli/package-verification.ts +12 -4
- package/src/cli/parser.ts +0 -16
- package/src/cli/status.ts +1 -1
- package/src/cli/types.ts +0 -8
- package/src/input/commands/delegation-runtime.ts +0 -8
- package/src/input/commands/experience-runtime.ts +0 -177
- package/src/input/commands/guidance-runtime.ts +0 -69
- package/src/input/commands/local-runtime.ts +1 -57
- package/src/input/commands/local-setup-review.ts +1 -1
- package/src/input/commands/operator-runtime.ts +1 -145
- package/src/input/commands/platform-access-runtime.ts +2 -195
- package/src/input/commands/product-runtime.ts +0 -116
- package/src/input/commands/security-runtime.ts +88 -0
- package/src/input/commands/session-content.ts +0 -97
- package/src/input/commands/shell-core.ts +0 -13
- package/src/input/commands.ts +2 -95
- package/src/panels/builtin/operations.ts +3 -184
- package/src/panels/confirm-state.ts +1 -1
- package/src/panels/index.ts +0 -11
- package/src/version.ts +1 -1
- package/docs/deployment-and-services.md +0 -52
- package/src/cli/service-command.ts +0 -26
- package/src/cli/surface-command.ts +0 -247
- package/src/input/commands/branch-runtime.ts +0 -72
- package/src/input/commands/control-room-runtime.ts +0 -234
- package/src/input/commands/discovery-runtime.ts +0 -61
- package/src/input/commands/hooks-runtime.ts +0 -207
- package/src/input/commands/incident-runtime.ts +0 -106
- package/src/input/commands/integration-runtime.ts +0 -437
- package/src/input/commands/local-setup.ts +0 -288
- package/src/input/commands/managed-runtime.ts +0 -240
- package/src/input/commands/marketplace-runtime.ts +0 -305
- package/src/input/commands/memory-product-runtime.ts +0 -148
- package/src/input/commands/operator-panel-runtime.ts +0 -146
- package/src/input/commands/platform-services-runtime.ts +0 -271
- package/src/input/commands/profile-sync-runtime.ts +0 -110
- package/src/input/commands/provider.ts +0 -363
- package/src/input/commands/remote-runtime-pool.ts +0 -89
- package/src/input/commands/remote-runtime-setup.ts +0 -226
- package/src/input/commands/remote-runtime.ts +0 -432
- package/src/input/commands/replay-runtime.ts +0 -25
- package/src/input/commands/services-runtime.ts +0 -220
- package/src/input/commands/settings-sync-runtime.ts +0 -197
- package/src/input/commands/share-runtime.ts +0 -127
- package/src/input/commands/skills-runtime.ts +0 -226
- package/src/input/commands/teleport-runtime.ts +0 -68
- package/src/panels/cockpit-panel.ts +0 -183
- package/src/panels/communication-panel.ts +0 -153
- package/src/panels/control-plane-panel.ts +0 -211
- package/src/panels/forensics-panel.ts +0 -364
- package/src/panels/hooks-panel.ts +0 -239
- package/src/panels/incident-review-panel.ts +0 -197
- package/src/panels/marketplace-panel.ts +0 -212
- package/src/panels/ops-control-panel.ts +0 -150
- package/src/panels/ops-strategy-panel.ts +0 -235
- package/src/panels/orchestration-panel.ts +0 -272
- package/src/panels/plugins-panel.ts +0 -178
- package/src/panels/remote-panel.ts +0 -449
- package/src/panels/routes-panel.ts +0 -178
- package/src/panels/services-panel.ts +0 -231
- package/src/panels/settings-sync-panel.ts +0 -120
- package/src/panels/skills-panel.ts +0 -431
- package/src/panels/watchers-panel.ts +0 -193
- package/src/verification/live-verifier.ts +0 -588
- package/src/verification/verification-ledger.ts +0 -239
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GoodVibes Agent will be recorded here.
|
|
4
4
|
|
|
5
|
+
## 0.1.72 - 2026-05-31
|
|
6
|
+
|
|
7
|
+
- Removed copied runtime lifecycle and transport words from the Agent CLI parser, command handler, detailed help, and package exports.
|
|
8
|
+
- Replaced package-facing deployment/service docs with runtime-connection docs focused on the external runtime prerequisite and Agent product boundary.
|
|
9
|
+
- Added regression coverage so hidden lifecycle words are treated as normal TUI prompts instead of supported Agent commands.
|
|
10
|
+
|
|
11
|
+
## 0.1.71 - 2026-05-31
|
|
12
|
+
|
|
13
|
+
- Stopped importing copied TUI slash-command modules that do not belong to the Agent product surface.
|
|
14
|
+
- Trimmed the built-in panel registry to Agent-relevant approval, automation, auth, provider, security, task, and policy views.
|
|
15
|
+
- Reduced package contents so hidden copied command and panel modules are not shipped with the installed Agent TUI.
|
|
16
|
+
|
|
5
17
|
## 0.1.70 - 2026-05-31
|
|
6
18
|
|
|
7
19
|
- Removed copied TUI coding, runtime lifecycle, and developer-maintenance slash commands from the visible Agent command registry.
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
GoodVibes Agent is the personal operator assistant TUI for GoodVibes. It is built for day-to-day operator work: chat, setup, local profiles, routines, skills, personas, isolated Agent Knowledge, status review, approvals, automation visibility, and explicit build delegation.
|
|
7
7
|
|
|
8
|
-
The Agent product connects to an already-running GoodVibes runtime. It does not install, start, stop, restart, or own runtime
|
|
8
|
+
The Agent product connects to an already-running GoodVibes runtime. It does not install, start, stop, restart, or own runtime hosting.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -87,7 +87,7 @@ Starting a routine records local usage and prints its steps; it does not spawn b
|
|
|
87
87
|
|
|
88
88
|
Start or restart the GoodVibes runtime from GoodVibes TUI or the owning host before launching Agent. Agent status and companion/knowledge routes connect to that external runtime, normally on `http://127.0.0.1:3421`.
|
|
89
89
|
|
|
90
|
-
Agent reports unavailable, unauthenticated, or incompatible runtime state through `goodvibes-agent status`, `goodvibes-agent doctor`, and the TUI status
|
|
90
|
+
Agent reports unavailable, unauthenticated, or incompatible runtime state through `goodvibes-agent status`, `goodvibes-agent doctor`, and the TUI status views. It does not provide runtime hosting commands.
|
|
91
91
|
|
|
92
92
|
## Product Boundary
|
|
93
93
|
|
|
@@ -102,7 +102,7 @@ GoodVibes TUI owns coding execution: file edits, git/worktree workflows, coding
|
|
|
102
102
|
Package-facing docs:
|
|
103
103
|
|
|
104
104
|
- [Getting Started](docs/getting-started.md)
|
|
105
|
-
- [
|
|
105
|
+
- [Runtime Connection](docs/runtime-connection.md)
|
|
106
106
|
- [Release And Publishing](docs/release-and-publishing.md)
|
|
107
107
|
|
|
108
108
|
The package-facing Agent documentation is limited to the docs listed above.
|
package/docs/README.md
CHANGED
|
@@ -5,7 +5,7 @@ These are the package-facing docs for GoodVibes Agent, the personal operator ass
|
|
|
5
5
|
Current package docs:
|
|
6
6
|
|
|
7
7
|
- [Getting Started](getting-started.md)
|
|
8
|
-
- [
|
|
8
|
+
- [Runtime Connection](runtime-connection.md)
|
|
9
9
|
- [Release And Publishing](release-and-publishing.md)
|
|
10
10
|
|
|
11
11
|
Important baseline constraints:
|
|
@@ -14,7 +14,7 @@ Important baseline constraints:
|
|
|
14
14
|
- Agent uses Bun and TypeScript-authored source.
|
|
15
15
|
- Agent depends on `@pellux/goodvibes-sdk@0.33.35`.
|
|
16
16
|
- Agent connects to an externally managed GoodVibes runtime.
|
|
17
|
-
- Agent does not start, stop, restart, install, uninstall, or own runtime
|
|
17
|
+
- Agent does not start, stop, restart, install, uninstall, or own runtime hosting.
|
|
18
18
|
- Agent Knowledge/Wiki uses only `/api/goodvibes-agent/knowledge/*`; there is no default Knowledge/Wiki or non-Agent product fallback.
|
|
19
19
|
- Agent supports isolated runtime homes with `GOODVIBES_AGENT_HOME=<path>` and named profile homes with `goodvibes-agent profiles create <name> --template <starter> --yes` plus `--agent-profile <name>`.
|
|
20
20
|
- Agent ships starter profile templates for household, research, travel, operations, and personal productivity local state; `profiles templates export/import` and `/agent-profile guide` support local custom starters.
|
package/docs/getting-started.md
CHANGED
|
@@ -99,7 +99,7 @@ Start the runtime from GoodVibes TUI or the owning host before using runtime-bac
|
|
|
99
99
|
|
|
100
100
|
Agent Knowledge/Wiki is an Agent-owned product segment. Agent commands must not fall back to default Knowledge/Wiki or other product-specific knowledge spaces.
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
Runtime-hosting commands are not part of GoodVibes Agent. Use `goodvibes-agent status`, `goodvibes-agent doctor`, and the Agent TUI status views for diagnostics.
|
|
103
103
|
|
|
104
104
|
## Current Product Notes
|
|
105
105
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Runtime Connection
|
|
2
|
+
|
|
3
|
+
GoodVibes Agent is a TUI client for an already-running GoodVibes runtime. The package exposes one executable:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
goodvibes-agent
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The installed command is backed by TypeScript-authored source with a Bun shebang. Package install smoke must verify:
|
|
10
|
+
|
|
11
|
+
- `goodvibes-agent --help`
|
|
12
|
+
- `goodvibes-agent --version`
|
|
13
|
+
- `goodvibes-agent status --json`
|
|
14
|
+
- `goodvibes-agent` launches the TUI in a real PTY
|
|
15
|
+
|
|
16
|
+
## Runtime Prerequisite
|
|
17
|
+
|
|
18
|
+
Start the GoodVibes runtime from the owning GoodVibes host before launching Agent. Agent expects the runtime to expose public operator routes and the isolated Agent Knowledge routes:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
http://127.0.0.1:3421
|
|
22
|
+
/api/goodvibes-agent/knowledge/status
|
|
23
|
+
/api/goodvibes-agent/knowledge/ask
|
|
24
|
+
/api/goodvibes-agent/knowledge/search
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
If the runtime is unavailable, unauthenticated, or on an incompatible SDK version, Agent commands report actionable diagnostics without printing token values.
|
|
28
|
+
|
|
29
|
+
## Product Boundary
|
|
30
|
+
|
|
31
|
+
Agent owns the operator assistant TUI, local profiles, local memory/routines/skills/personas, isolated Agent Knowledge calls, companion chat, approvals/automation visibility, and explicit build delegation.
|
|
32
|
+
|
|
33
|
+
Agent does not host runtime connectivity. It does not provide commands to install, expose, start, stop, restart, or mutate the runtime host.
|
|
34
|
+
|
|
35
|
+
Agent Knowledge/Wiki is its own product segment. Agent uses `/api/goodvibes-agent/knowledge/*` only and must not fall back to default Knowledge/Wiki or other product-specific knowledge routes.
|
|
36
|
+
|
|
37
|
+
Normal assistant chat uses companion chat. Build/fix/review work is delegated explicitly to GoodVibes TUI through public runtime/session contracts, and WRFC is requested only when explicitly asked for delegated build/fix/review work.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.72",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
|
|
6
6
|
"type": "module",
|
|
@@ -16,17 +16,58 @@
|
|
|
16
16
|
"!src/test",
|
|
17
17
|
"!src/**/*.test.ts",
|
|
18
18
|
"!src/**/__tests__",
|
|
19
|
+
"!src/input/commands/branch-runtime.ts",
|
|
20
|
+
"!src/input/commands/control-room-runtime.ts",
|
|
21
|
+
"!src/input/commands/discovery-runtime.ts",
|
|
22
|
+
"!src/input/commands/hooks-runtime.ts",
|
|
23
|
+
"!src/input/commands/incident-runtime.ts",
|
|
24
|
+
"!src/input/commands/integration-runtime.ts",
|
|
25
|
+
"!src/input/commands/local-setup.ts",
|
|
26
|
+
"!src/input/commands/managed-runtime.ts",
|
|
27
|
+
"!src/input/commands/marketplace-runtime.ts",
|
|
28
|
+
"!src/input/commands/memory-product-runtime.ts",
|
|
29
|
+
"!src/input/commands/operator-panel-runtime.ts",
|
|
30
|
+
"!src/input/commands/platform-services-runtime.ts",
|
|
31
|
+
"!src/input/commands/profile-sync-runtime.ts",
|
|
32
|
+
"!src/input/commands/provider.ts",
|
|
33
|
+
"!src/input/commands/remote-runtime.ts",
|
|
34
|
+
"!src/input/commands/remote-runtime-pool.ts",
|
|
35
|
+
"!src/input/commands/remote-runtime-setup.ts",
|
|
36
|
+
"!src/input/commands/replay-runtime.ts",
|
|
37
|
+
"!src/input/commands/services-runtime.ts",
|
|
38
|
+
"!src/input/commands/settings-sync-runtime.ts",
|
|
39
|
+
"!src/input/commands/share-runtime.ts",
|
|
40
|
+
"!src/input/commands/skills-runtime.ts",
|
|
41
|
+
"!src/input/commands/teleport-runtime.ts",
|
|
42
|
+
"!src/panels/cockpit-panel.ts",
|
|
43
|
+
"!src/panels/communication-panel.ts",
|
|
44
|
+
"!src/panels/control-plane-panel.ts",
|
|
19
45
|
"!src/panels/diff-panel.ts",
|
|
46
|
+
"!src/panels/forensics-panel.ts",
|
|
20
47
|
"!src/panels/git-panel.ts",
|
|
48
|
+
"!src/panels/hooks-panel.ts",
|
|
49
|
+
"!src/panels/incident-review-panel.ts",
|
|
50
|
+
"!src/panels/marketplace-panel.ts",
|
|
51
|
+
"!src/panels/ops-control-panel.ts",
|
|
52
|
+
"!src/panels/ops-strategy-panel.ts",
|
|
53
|
+
"!src/panels/orchestration-panel.ts",
|
|
54
|
+
"!src/panels/plugins-panel.ts",
|
|
55
|
+
"!src/panels/remote-panel.ts",
|
|
56
|
+
"!src/panels/routes-panel.ts",
|
|
21
57
|
"!src/panels/sandbox-panel.ts",
|
|
58
|
+
"!src/panels/services-panel.ts",
|
|
59
|
+
"!src/panels/settings-sync-panel.ts",
|
|
60
|
+
"!src/panels/skills-panel.ts",
|
|
61
|
+
"!src/panels/watchers-panel.ts",
|
|
22
62
|
"!src/panels/worktree-panel.ts",
|
|
23
63
|
"!src/panels/wrfc-panel.ts",
|
|
64
|
+
"!src/verification",
|
|
24
65
|
"tsconfig.json",
|
|
25
66
|
"README.md",
|
|
26
67
|
"CHANGELOG.md",
|
|
27
68
|
"docs/README.md",
|
|
28
69
|
"docs/getting-started.md",
|
|
29
|
-
"docs/
|
|
70
|
+
"docs/runtime-connection.md",
|
|
30
71
|
"docs/release-and-publishing.md"
|
|
31
72
|
],
|
|
32
73
|
"scripts": {
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { promises as fsPromises } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import type { ShellPathService } from '@/runtime/index.ts';
|
|
4
|
+
import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
|
|
5
|
+
|
|
6
|
+
export type SkillOrigin = 'project-local' | 'global' | 'custom';
|
|
7
|
+
|
|
8
|
+
export interface SkillRecord {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
path: string;
|
|
12
|
+
origin: SkillOrigin;
|
|
13
|
+
dependencies: string[];
|
|
14
|
+
includes: string[];
|
|
15
|
+
frontmatter: Record<string, string>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function parseFrontmatter(content: string): Record<string, string> {
|
|
19
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
20
|
+
if (!match) return {};
|
|
21
|
+
const result: Record<string, string> = {};
|
|
22
|
+
for (const line of match[1].split('\n')) {
|
|
23
|
+
const [key, ...rest] = line.split(':');
|
|
24
|
+
if (key && rest.length > 0) {
|
|
25
|
+
result[key.trim()] = rest.join(':').trim();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getSkillDirectories(cwd: string, homeDir: string): Array<{ root: string; origin: SkillOrigin }> {
|
|
32
|
+
return [
|
|
33
|
+
{ root: join(cwd, '.goodvibes', 'skills'), origin: 'project-local' },
|
|
34
|
+
{ root: join(cwd, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'skills'), origin: 'project-local' },
|
|
35
|
+
{ root: join(homeDir, '.goodvibes', 'skills'), origin: 'global' },
|
|
36
|
+
{ root: join(homeDir, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'skills'), origin: 'global' },
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function readSkillFile(path: string, origin: SkillOrigin): Promise<SkillRecord | null> {
|
|
41
|
+
let content = '';
|
|
42
|
+
try {
|
|
43
|
+
content = await fsPromises.readFile(path, 'utf-8');
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const frontmatter = parseFrontmatter(content);
|
|
49
|
+
const body = content.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
50
|
+
const name = frontmatter.name ?? path.split(/[\\/]/).pop()?.replace(/\.md$/, '') ?? 'skill';
|
|
51
|
+
const description = frontmatter.description ?? frontmatter.summary ?? '';
|
|
52
|
+
const dependencies = frontmatter.depends_on
|
|
53
|
+
? frontmatter.depends_on.split(',').map((item) => item.trim()).filter(Boolean)
|
|
54
|
+
: [];
|
|
55
|
+
const includes: string[] = [];
|
|
56
|
+
const includeRegex = /^@([\w/-]+)/gm;
|
|
57
|
+
let match: RegExpExecArray | null;
|
|
58
|
+
while ((match = includeRegex.exec(body)) !== null) {
|
|
59
|
+
includes.push(match[1]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
name,
|
|
64
|
+
description,
|
|
65
|
+
path,
|
|
66
|
+
origin,
|
|
67
|
+
dependencies,
|
|
68
|
+
includes,
|
|
69
|
+
frontmatter,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function scanSkillDirectory(root: string, origin: SkillOrigin): Promise<SkillRecord[]> {
|
|
74
|
+
let entries: string[] = [];
|
|
75
|
+
try {
|
|
76
|
+
entries = await fsPromises.readdir(root);
|
|
77
|
+
} catch {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const records: SkillRecord[] = [];
|
|
82
|
+
for (const entry of entries.sort((a, b) => a.localeCompare(b))) {
|
|
83
|
+
if (entry.endsWith('.md')) {
|
|
84
|
+
const record = await readSkillFile(join(root, entry), origin);
|
|
85
|
+
if (record) records.push(record);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const markerPath = join(root, entry, 'SKILL.md');
|
|
90
|
+
const record = await readSkillFile(markerPath, origin);
|
|
91
|
+
if (record) records.push(record);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return records;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export async function discoverSkills(shellPaths: Pick<ShellPathService, 'workingDirectory' | 'homeDirectory'>): Promise<SkillRecord[]> {
|
|
98
|
+
const cwd = shellPaths.workingDirectory;
|
|
99
|
+
const homeDir = shellPaths.homeDirectory;
|
|
100
|
+
const seen = new Set<string>();
|
|
101
|
+
const records: SkillRecord[] = [];
|
|
102
|
+
|
|
103
|
+
for (const { root, origin } of getSkillDirectories(cwd, homeDir)) {
|
|
104
|
+
for (const record of await scanSkillDirectory(root, origin)) {
|
|
105
|
+
if (seen.has(record.name.toLowerCase())) continue;
|
|
106
|
+
seen.add(record.name.toLowerCase());
|
|
107
|
+
records.push(record);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return records.sort((a, b) => {
|
|
112
|
+
const originRank = a.origin === b.origin
|
|
113
|
+
? 0
|
|
114
|
+
: a.origin === 'project-local'
|
|
115
|
+
? -1
|
|
116
|
+
: 1;
|
|
117
|
+
return originRank || a.name.localeCompare(b.name);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
@@ -150,10 +150,6 @@ export function applyRuntimeCommandEndpointFlagOverrides(
|
|
|
150
150
|
flags: Pick<GoodVibesCliFlags, 'hostname' | 'port'>,
|
|
151
151
|
): readonly string[] {
|
|
152
152
|
if (flags.hostname === undefined && flags.port === undefined) return [];
|
|
153
|
-
if (command === '
|
|
154
|
-
if (command === 'listener') return applyRuntimeEndpointFlagOverrides(configManager, 'httpListener', flags);
|
|
155
|
-
if (command === 'control-plane' || command === 'pair' || command === 'serve') {
|
|
156
|
-
return applyRuntimeEndpointFlagOverrides(configManager, 'controlPlane', flags);
|
|
157
|
-
}
|
|
153
|
+
if (command === 'pair') return applyRuntimeEndpointFlagOverrides(configManager, 'controlPlane', flags);
|
|
158
154
|
return [];
|
|
159
155
|
}
|
package/src/cli/entrypoint.ts
CHANGED
|
@@ -88,12 +88,6 @@ export async function prepareShellCliRuntime(
|
|
|
88
88
|
process.exit(0);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
if (cli.command === 'serve') {
|
|
92
|
-
console.error(`${binary} connects to an already-running GoodVibes runtime and does not start or own runtime lifecycle.`);
|
|
93
|
-
console.error('Start or manage the runtime from GoodVibes TUI or host tooling, then run this Agent against it.');
|
|
94
|
-
process.exit(2);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
91
|
let ownership: ShellEntrypointOwnership;
|
|
98
92
|
try {
|
|
99
93
|
ownership = resolveShellEntrypointOwnership(
|
package/src/cli/help.ts
CHANGED
|
@@ -232,21 +232,6 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
232
232
|
summary: 'Inspect in-process runtime tasks. Agent blocks copied task submission; use run for one-shot work or delegate for explicit build/fix/review handoff.',
|
|
233
233
|
examples: ['tasks list', 'tasks show task-123', 'run "check provider readiness"', 'delegate "fix the failing tests"'],
|
|
234
234
|
},
|
|
235
|
-
surfaces: {
|
|
236
|
-
usage: ['surfaces [list]', 'surfaces check', 'surfaces show <surfaceId>'],
|
|
237
|
-
summary: 'Inspect advanced browser, channel, and runtime connection surfaces. Agent does not mutate runtime connection posture.',
|
|
238
|
-
examples: ['surfaces', 'surfaces check', 'surfaces show slack'],
|
|
239
|
-
},
|
|
240
|
-
listener: {
|
|
241
|
-
usage: ['listener test'],
|
|
242
|
-
summary: 'Check advanced inbound webhook readiness, network posture, auth, and enabled channel requirements.',
|
|
243
|
-
examples: ['listener test', 'listener test --json'],
|
|
244
|
-
},
|
|
245
|
-
'control-plane': {
|
|
246
|
-
usage: ['control-plane status'],
|
|
247
|
-
summary: 'Inspect advanced runtime API reachability, local auth, bootstrap credentials, and operator tokens.',
|
|
248
|
-
examples: ['control-plane status', 'control-plane status --json'],
|
|
249
|
-
},
|
|
250
235
|
bundle: {
|
|
251
236
|
usage: ['bundle export [path]', 'bundle inspect <path>', 'bundle import <path>'],
|
|
252
237
|
summary: 'Export, inspect, or import setup/profile/trust/support bundle data.',
|
|
@@ -257,31 +242,11 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
257
242
|
summary: 'Print companion pairing connection details and a QR code.',
|
|
258
243
|
examples: ['pair', 'qrcode'],
|
|
259
244
|
},
|
|
260
|
-
web: {
|
|
261
|
-
usage: ['web [--open]'],
|
|
262
|
-
summary: 'Show the configured browser surface URL, bind address, and enablement state.',
|
|
263
|
-
examples: ['web', 'web --open', 'web --hostname 0.0.0.0 --port 3423'],
|
|
264
|
-
},
|
|
265
|
-
service: {
|
|
266
|
-
usage: ['service status', 'service check'],
|
|
267
|
-
summary: 'Inspect the externally owned GoodVibes runtime service posture. Agent does not install, start, stop, restart, or uninstall the runtime.',
|
|
268
|
-
examples: ['service status', 'service check --json'],
|
|
269
|
-
},
|
|
270
245
|
completion: {
|
|
271
246
|
usage: ['completion <bash|zsh|fish>'],
|
|
272
247
|
summary: 'Generate shell completion scripts.',
|
|
273
248
|
examples: ['completion bash', 'completion zsh'],
|
|
274
249
|
},
|
|
275
|
-
serve: {
|
|
276
|
-
usage: ['serve [--hostname <host>] [--port <port>]', 'daemon [--hostname <host>] [--port <port>]'],
|
|
277
|
-
summary: 'Unavailable in GoodVibes Agent. Agent connects to an already-running GoodVibes runtime owned by GoodVibes TUI/host tooling.',
|
|
278
|
-
examples: [],
|
|
279
|
-
},
|
|
280
|
-
remote: {
|
|
281
|
-
usage: ['remote', 'bridge'],
|
|
282
|
-
summary: 'Inspect remote runner/node posture and bridge readiness.',
|
|
283
|
-
examples: ['remote', 'bridge'],
|
|
284
|
-
},
|
|
285
250
|
};
|
|
286
251
|
|
|
287
252
|
const HELP_ALIASES: Record<string, string> = {
|
|
@@ -295,16 +260,8 @@ const HELP_ALIASES: Record<string, string> = {
|
|
|
295
260
|
secret: 'secrets',
|
|
296
261
|
session: 'sessions',
|
|
297
262
|
task: 'tasks',
|
|
298
|
-
surface: 'surfaces',
|
|
299
|
-
webhook: 'listener',
|
|
300
|
-
controlplane: 'control-plane',
|
|
301
|
-
cp: 'control-plane',
|
|
302
263
|
qrcode: 'pair',
|
|
303
264
|
qr: 'pair',
|
|
304
|
-
daemon: 'serve',
|
|
305
|
-
server: 'serve',
|
|
306
|
-
services: 'service',
|
|
307
|
-
bridge: 'remote',
|
|
308
265
|
};
|
|
309
266
|
|
|
310
267
|
function normalizeHelpTopic(topic: string): string {
|
package/src/cli/index.ts
CHANGED
|
@@ -5,7 +5,5 @@ export * from './status.ts';
|
|
|
5
5
|
export * from './completion.ts';
|
|
6
6
|
export * from './config-overrides.ts';
|
|
7
7
|
export * from './endpoints.ts';
|
|
8
|
-
export * from './surface-command.ts';
|
|
9
|
-
export * from './service-command.ts';
|
|
10
8
|
export * from './bundle-command.ts';
|
|
11
9
|
export * from './management.ts';
|
|
@@ -8,9 +8,8 @@ import { inspectProviderAuth } from '@/runtime/index.ts';
|
|
|
8
8
|
import { getOrCreateCompanionToken, buildCompanionConnectionInfo, encodeConnectionPayload, formatConnectionBlock } from '@pellux/goodvibes-sdk/platform/pairing';
|
|
9
9
|
import { generateQrMatrix, renderQrToString } from '@pellux/goodvibes-sdk/platform/pairing';
|
|
10
10
|
import { resolveRuntimeEndpointBinding } from './endpoints.ts';
|
|
11
|
-
import { classifyBindPosture, isNetworkFacing } from './network-posture.ts';
|
|
12
11
|
import type { CliCommandRuntime } from './management.ts';
|
|
13
|
-
import { extractAuthorizationCode, formatJsonOrText, hasCommandFlag, openBrowser,
|
|
12
|
+
import { extractAuthorizationCode, formatJsonOrText, hasCommandFlag, openBrowser, urlHostForBindHost, withRuntimeServices, yesNo } from './management.ts';
|
|
14
13
|
import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../config/surface.ts';
|
|
15
14
|
|
|
16
15
|
export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<string> {
|
|
@@ -300,71 +299,6 @@ export async function handleTasks(runtime: CliCommandRuntime): Promise<string> {
|
|
|
300
299
|
});
|
|
301
300
|
}
|
|
302
301
|
|
|
303
|
-
export interface ControlPlaneStatusResult {
|
|
304
|
-
readonly enabled: unknown;
|
|
305
|
-
readonly hostMode: string;
|
|
306
|
-
readonly configuredHost: string;
|
|
307
|
-
readonly host: string;
|
|
308
|
-
readonly port: number;
|
|
309
|
-
readonly posture: ReturnType<typeof classifyBindPosture>;
|
|
310
|
-
readonly reachable: boolean;
|
|
311
|
-
readonly auth: ReturnType<typeof readAuthPaths>;
|
|
312
|
-
readonly service: {
|
|
313
|
-
readonly enabled: unknown;
|
|
314
|
-
readonly autostart: unknown;
|
|
315
|
-
readonly restartOnFailure: unknown;
|
|
316
|
-
};
|
|
317
|
-
readonly issues: readonly string[];
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
export async function buildControlPlaneStatusResult(runtime: CliCommandRuntime): Promise<ControlPlaneStatusResult> {
|
|
321
|
-
const binding = resolveRuntimeEndpointBinding(runtime.configManager, 'controlPlane');
|
|
322
|
-
const enabled = runtime.configManager.get('controlPlane.enabled');
|
|
323
|
-
const reachable = enabled === true ? await probeTcp(binding.host, binding.port) : false;
|
|
324
|
-
const auth = readAuthPaths(runtime);
|
|
325
|
-
const service = {
|
|
326
|
-
enabled: runtime.configManager.get('service.enabled'),
|
|
327
|
-
autostart: runtime.configManager.get('service.autostart'),
|
|
328
|
-
restartOnFailure: runtime.configManager.get('service.restartOnFailure'),
|
|
329
|
-
};
|
|
330
|
-
const issues: string[] = [];
|
|
331
|
-
if (enabled === true && !reachable) issues.push(`Runtime API is enabled but not reachable on ${binding.host}:${binding.port}.`);
|
|
332
|
-
if (enabled === true && service.enabled !== true) issues.push('Runtime API is enabled on the external runtime config, but Agent service ownership is disabled.');
|
|
333
|
-
if (enabled === true && service.autostart !== true) issues.push('Runtime API is enabled on the external runtime config, but autostart is off.');
|
|
334
|
-
if (enabled === true && service.restartOnFailure !== true) issues.push('Runtime API is enabled on the external runtime config, but restart-on-failure is off.');
|
|
335
|
-
if (isNetworkFacing(enabled, binding) && !auth.userStorePresent) issues.push('Network-facing Runtime API has no local auth user store.');
|
|
336
|
-
if (isNetworkFacing(enabled, binding) && auth.bootstrapCredentialPresent) issues.push('Network-facing Runtime API still has a bootstrap credential file.');
|
|
337
|
-
return {
|
|
338
|
-
enabled,
|
|
339
|
-
...binding,
|
|
340
|
-
posture: classifyBindPosture(binding),
|
|
341
|
-
reachable,
|
|
342
|
-
auth,
|
|
343
|
-
service,
|
|
344
|
-
issues,
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
export function formatControlPlaneStatus(runtime: CliCommandRuntime, value: ControlPlaneStatusResult): string {
|
|
349
|
-
return formatJsonOrText(runtime.cli)(value, [
|
|
350
|
-
'GoodVibes runtime API status',
|
|
351
|
-
` enabled: ${yesNo(value.enabled)}`,
|
|
352
|
-
` bind: ${value.hostMode} ${value.host}:${value.port}`,
|
|
353
|
-
` bind posture: ${value.posture.label}`,
|
|
354
|
-
` reachable: ${yesNo(value.reachable)}`,
|
|
355
|
-
` service: enabled=${yesNo(value.service.enabled)} autostart=${yesNo(value.service.autostart)} restartOnFailure=${yesNo(value.service.restartOnFailure)}`,
|
|
356
|
-
` local auth users: ${value.auth.userStorePresent ? 'present' : 'missing'}`,
|
|
357
|
-
` bootstrap credential: ${value.auth.bootstrapCredentialPresent ? 'present' : 'missing'}`,
|
|
358
|
-
` operator tokens: ${value.auth.operatorTokenPresent ? 'present' : 'missing'}`,
|
|
359
|
-
value.issues.length === 0 ? ' readiness: ready' : ' readiness: needs attention',
|
|
360
|
-
...value.issues.map((issue) => ` - ${issue}`),
|
|
361
|
-
].join('\n'));
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
export async function renderControlPlaneStatus(runtime: CliCommandRuntime): Promise<string> {
|
|
365
|
-
return formatControlPlaneStatus(runtime, await buildControlPlaneStatusResult(runtime));
|
|
366
|
-
}
|
|
367
|
-
|
|
368
302
|
export async function renderPairing(runtime: CliCommandRuntime): Promise<string> {
|
|
369
303
|
const daemonHomeDir = join(runtime.homeDirectory, '.goodvibes', 'daemon');
|
|
370
304
|
const tokenRecord = getOrCreateCompanionToken(GOODVIBES_AGENT_PAIRING_SURFACE, { daemonHomeDir });
|
|
@@ -380,45 +314,3 @@ export async function renderPairing(runtime: CliCommandRuntime): Promise<string>
|
|
|
380
314
|
const qr = renderQrToString(generateQrMatrix(payload));
|
|
381
315
|
return [formatConnectionBlock(info, payload), '', qr].join('\n');
|
|
382
316
|
}
|
|
383
|
-
|
|
384
|
-
export async function renderRemote(runtime: CliCommandRuntime, label: 'remote' | 'bridge'): Promise<string> {
|
|
385
|
-
return await withRuntimeServices(runtime, (services) => {
|
|
386
|
-
const pools = services.remoteRunnerRegistry.listPools?.() ?? [];
|
|
387
|
-
const contracts = services.remoteRunnerRegistry.listContracts();
|
|
388
|
-
const artifacts = services.remoteRunnerRegistry.listArtifacts();
|
|
389
|
-
const value = {
|
|
390
|
-
pools: pools.length,
|
|
391
|
-
contracts: contracts.length,
|
|
392
|
-
artifacts: artifacts.length,
|
|
393
|
-
remoteFetchPrivateHosts: runtime.configManager.get('network.remoteFetch.allowPrivateHosts'),
|
|
394
|
-
};
|
|
395
|
-
return formatJsonOrText(runtime.cli)(value, [
|
|
396
|
-
`GoodVibes ${label} status`,
|
|
397
|
-
` runner pools: ${value.pools}`,
|
|
398
|
-
` contracts: ${value.contracts}`,
|
|
399
|
-
` review artifacts: ${value.artifacts}`,
|
|
400
|
-
` private-host remote fetch: ${yesNo(value.remoteFetchPrivateHosts)}`,
|
|
401
|
-
].join('\n'));
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
export function renderWeb(runtime: CliCommandRuntime): string {
|
|
406
|
-
const binding = resolveRuntimeEndpointBinding(runtime.configManager, 'web');
|
|
407
|
-
const publicBaseUrl = String(runtime.configManager.get('web.publicBaseUrl') ?? '');
|
|
408
|
-
const hasEndpointOverride = runtime.cli.flags.hostname !== undefined || runtime.cli.flags.port !== undefined;
|
|
409
|
-
const url = !hasEndpointOverride && publicBaseUrl
|
|
410
|
-
? publicBaseUrl
|
|
411
|
-
: `http://${urlHostForBindHost(binding.host)}:${binding.port}`;
|
|
412
|
-
const value = {
|
|
413
|
-
enabled: runtime.configManager.get('web.enabled'),
|
|
414
|
-
...binding,
|
|
415
|
-
url,
|
|
416
|
-
};
|
|
417
|
-
return formatJsonOrText(runtime.cli)(value, [
|
|
418
|
-
'GoodVibes web',
|
|
419
|
-
` enabled: ${yesNo(value.enabled)}`,
|
|
420
|
-
` bind: ${value.hostMode} ${value.host}:${value.port}`,
|
|
421
|
-
` url: ${value.url}`,
|
|
422
|
-
...(runtime.cli.flags.open ? [` open: ${openBrowser(value.url)}`] : []),
|
|
423
|
-
].join('\n'));
|
|
424
|
-
}
|
package/src/cli/management.ts
CHANGED
|
@@ -28,10 +28,8 @@ import { classifyProviderSetup } from './provider-classification.ts';
|
|
|
28
28
|
import { resolveRuntimeEndpointBinding } from './endpoints.ts';
|
|
29
29
|
import { applyRuntimeEndpointFlagOverrides } from './config-overrides.ts';
|
|
30
30
|
import type { RuntimeEndpointId } from './endpoints.ts';
|
|
31
|
-
import { handleServiceCommand } from './service-command.ts';
|
|
32
31
|
import { handleBundleCommand } from './bundle-command.ts';
|
|
33
|
-
import {
|
|
34
|
-
import { buildControlPlaneStatusResult, formatControlPlaneStatus, handleSecrets, handleSessions, handleTasks, renderPairing, renderRemote, renderSubscriptions, renderWeb } from './management-commands.ts';
|
|
32
|
+
import { handleSecrets, handleSessions, handleTasks, renderPairing, renderSubscriptions } from './management-commands.ts';
|
|
35
33
|
import { handleAgentKnowledgeCommand, handleAgentKnowledgeShortcutCommand, handleCompatCommand, handleDelegateCommand } from './agent-knowledge-command.ts';
|
|
36
34
|
import { handleProfilesCommand } from './profiles-command.ts';
|
|
37
35
|
import { handleRoutinesCommand } from './routines-command.ts';
|
|
@@ -672,14 +670,6 @@ export async function handleGoodVibesCliCommand(runtime: CliCommandRuntime): Pro
|
|
|
672
670
|
switch (runtime.cli.command) {
|
|
673
671
|
case 'run':
|
|
674
672
|
return { handled: true, exitCode: await runNonInteractiveAgent(runtime) };
|
|
675
|
-
case 'web':
|
|
676
|
-
console.log(renderWeb(runtime));
|
|
677
|
-
return { handled: true, exitCode: 0 };
|
|
678
|
-
case 'service': {
|
|
679
|
-
const result = await handleServiceCommand(runtime);
|
|
680
|
-
console.log(result.output);
|
|
681
|
-
return { handled: true, exitCode: result.exitCode };
|
|
682
|
-
}
|
|
683
673
|
case 'providers': {
|
|
684
674
|
const output = await renderProviders(runtime);
|
|
685
675
|
console.log(output);
|
|
@@ -747,21 +737,6 @@ export async function handleGoodVibesCliCommand(runtime: CliCommandRuntime): Pro
|
|
|
747
737
|
if (output) console.log(output);
|
|
748
738
|
return { handled: true, exitCode: exitCodeForText(output) };
|
|
749
739
|
}
|
|
750
|
-
case 'surfaces': {
|
|
751
|
-
const result = await handleSurfacesCommand(runtime);
|
|
752
|
-
console.log(result.output);
|
|
753
|
-
return { handled: true, exitCode: result.exitCode };
|
|
754
|
-
}
|
|
755
|
-
case 'listener': {
|
|
756
|
-
const result = await buildListenerTestResult(runtime);
|
|
757
|
-
console.log(formatListenerTestResult(runtime, result));
|
|
758
|
-
return { handled: true, exitCode: result.issues.length > 0 ? 1 : 0 };
|
|
759
|
-
}
|
|
760
|
-
case 'control-plane': {
|
|
761
|
-
const result = await buildControlPlaneStatusResult(runtime);
|
|
762
|
-
console.log(formatControlPlaneStatus(runtime, result));
|
|
763
|
-
return { handled: true, exitCode: result.issues.length > 0 ? 1 : 0 };
|
|
764
|
-
}
|
|
765
740
|
case 'pair':
|
|
766
741
|
console.log(await renderPairing(runtime));
|
|
767
742
|
return { handled: true, exitCode: 0 };
|
|
@@ -770,12 +745,6 @@ export async function handleGoodVibesCliCommand(runtime: CliCommandRuntime): Pro
|
|
|
770
745
|
console.log(result.output);
|
|
771
746
|
return { handled: true, exitCode: result.exitCode };
|
|
772
747
|
}
|
|
773
|
-
case 'remote':
|
|
774
|
-
console.log(await renderRemote(runtime, 'remote'));
|
|
775
|
-
return { handled: true, exitCode: 0 };
|
|
776
|
-
case 'bridge':
|
|
777
|
-
console.log(await renderRemote(runtime, 'bridge'));
|
|
778
|
-
return { handled: true, exitCode: 0 };
|
|
779
748
|
default:
|
|
780
749
|
return { handled: false, exitCode: 0 };
|
|
781
750
|
}
|
|
@@ -39,7 +39,7 @@ const REQUIRED_TARBALL_PATHS = [
|
|
|
39
39
|
'tsconfig.json',
|
|
40
40
|
'docs/README.md',
|
|
41
41
|
'docs/getting-started.md',
|
|
42
|
-
'docs/
|
|
42
|
+
'docs/runtime-connection.md',
|
|
43
43
|
'docs/release-and-publishing.md',
|
|
44
44
|
] as const;
|
|
45
45
|
const FORBIDDEN_TARBALL_PREFIXES = ['.github/', 'src/test/', 'src/.test/', '.goodvibes/', 'vendor/'] as const;
|
|
@@ -53,7 +53,7 @@ const PACKAGE_FACING_TEXT_PATHS = [
|
|
|
53
53
|
'CHANGELOG.md',
|
|
54
54
|
'docs/README.md',
|
|
55
55
|
'docs/getting-started.md',
|
|
56
|
-
'docs/
|
|
56
|
+
'docs/runtime-connection.md',
|
|
57
57
|
'docs/release-and-publishing.md',
|
|
58
58
|
] as const;
|
|
59
59
|
const PACKAGE_FACING_FORBIDDEN_TEXT = [
|
|
@@ -75,8 +75,15 @@ const PACKAGE_FACING_FORBIDDEN_TEXT = [
|
|
|
75
75
|
['capabilities', ' command'].join(''),
|
|
76
76
|
['near', '-fork'].join(''),
|
|
77
77
|
['goodvibes-agent', 'serve'].join(' '),
|
|
78
|
-
['goodvibes-agent', 'service
|
|
79
|
-
['goodvibes-agent', '
|
|
78
|
+
['goodvibes-agent', 'service'].join(' '),
|
|
79
|
+
['goodvibes-agent', 'services'].join(' '),
|
|
80
|
+
['goodvibes-agent', 'surfaces'].join(' '),
|
|
81
|
+
['goodvibes-agent', 'surface'].join(' '),
|
|
82
|
+
['goodvibes-agent', 'listener'].join(' '),
|
|
83
|
+
['goodvibes-agent', 'control-plane'].join(' '),
|
|
84
|
+
['goodvibes-agent', 'remote'].join(' '),
|
|
85
|
+
['goodvibes-agent', 'bridge'].join(' '),
|
|
86
|
+
['goodvibes-agent', 'web'].join(' '),
|
|
80
87
|
'Every plan must have a multi-agent execution strategy',
|
|
81
88
|
'NEVER skip WRFC',
|
|
82
89
|
'ALWAYS work in parallel when implementing a plan',
|
|
@@ -92,6 +99,7 @@ const PACKAGE_FACING_REQUIRED_TEXT: readonly {
|
|
|
92
99
|
{ path: 'README.md', required: ['/api/goodvibes-agent/knowledge'] },
|
|
93
100
|
{ path: 'docs/README.md', required: ['/api/goodvibes-agent/knowledge'] },
|
|
94
101
|
{ path: 'docs/getting-started.md', required: ['/api/goodvibes-agent/knowledge'] },
|
|
102
|
+
{ path: 'docs/runtime-connection.md', required: ['/api/goodvibes-agent/knowledge'] },
|
|
95
103
|
{ path: 'docs/release-and-publishing.md', required: ['/api/goodvibes-agent/knowledge'] },
|
|
96
104
|
];
|
|
97
105
|
|