@pellux/goodvibes-agent 0.1.116 → 0.1.117
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 +41 -663
- package/README.md +38 -52
- package/dist/package/main.js +37826 -35924
- package/docs/README.md +5 -4
- package/docs/{connected-services.md → connected-host.md} +18 -10
- package/docs/getting-started.md +41 -44
- package/docs/release-and-publishing.md +6 -4
- package/package.json +3 -3
- package/src/agent/behavior-discovery-summary.ts +1 -3
- package/src/agent/persona-discovery.ts +1 -3
- package/src/agent/persona-registry.ts +5 -3
- package/src/agent/reminder-schedule-format.ts +6 -6
- package/src/agent/reminder-schedule.ts +1 -1
- package/src/agent/routine-registry.ts +43 -4
- package/src/agent/routine-schedule-format.ts +6 -6
- package/src/agent/routine-schedule-promotion.ts +1 -1
- package/src/agent/routine-schedule-receipts.ts +1 -1
- package/src/agent/runtime-profile-starters.ts +3 -3
- package/src/agent/runtime-profile.ts +78 -0
- package/src/agent/skill-registry.ts +190 -13
- package/src/cli/agent-knowledge-command.ts +2 -2
- package/src/cli/agent-knowledge-format.ts +2 -2
- package/src/cli/agent-knowledge-runtime.ts +1 -1
- package/src/cli/bundle-command.ts +1 -1
- package/src/cli/entrypoint.ts +16 -7
- package/src/cli/help.ts +26 -19
- package/src/cli/local-library-command.ts +75 -21
- package/src/cli/management-commands.ts +7 -6
- package/src/cli/management.ts +6 -51
- package/src/cli/parser.ts +23 -2
- package/src/cli/profiles-command.ts +119 -1
- package/src/cli/routines-command.ts +139 -11
- package/src/cli/service-posture.ts +11 -11
- package/src/cli/status.ts +21 -25
- package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
- package/src/input/agent-workspace-access-command-editors.ts +170 -0
- package/src/input/agent-workspace-activation.ts +2 -1
- package/src/input/agent-workspace-basic-command-editor-submission.ts +345 -92
- package/src/input/agent-workspace-basic-command-editors.ts +480 -7
- package/src/input/agent-workspace-categories.ts +175 -15
- package/src/input/agent-workspace-channel-command-editor-submission.ts +49 -0
- package/src/input/agent-workspace-channel-command-editors.ts +47 -0
- package/src/input/agent-workspace-command-editor.ts +23 -1
- package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
- package/src/input/agent-workspace-editors.ts +27 -0
- package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
- package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
- package/src/input/agent-workspace-learned-behavior.ts +67 -0
- package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
- package/src/input/agent-workspace-library-command-editors.ts +35 -0
- package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
- package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
- package/src/input/agent-workspace-memory-command-editors.ts +180 -0
- package/src/input/agent-workspace-navigation.ts +45 -0
- package/src/input/agent-workspace-notify-editor-submission.ts +107 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +146 -0
- package/src/input/agent-workspace-operations-command-editors.ts +119 -0
- package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
- package/src/input/agent-workspace-provider-command-editors.ts +93 -0
- package/src/input/agent-workspace-requirements.ts +11 -0
- package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
- package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
- package/src/input/agent-workspace-session-command-editors.ts +249 -0
- package/src/input/agent-workspace-setup.ts +24 -14
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
- package/src/input/agent-workspace-snapshot.ts +50 -8
- package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
- package/src/input/agent-workspace-task-command-editors.ts +47 -0
- package/src/input/agent-workspace-types.ts +120 -0
- package/src/input/agent-workspace-voice-media.ts +1 -1
- package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
- package/src/input/agent-workspace.ts +47 -37
- package/src/input/command-registry.ts +1 -1
- package/src/input/commands/agent-runtime-profile-runtime.ts +89 -4
- package/src/input/commands/agent-skills-runtime.ts +76 -12
- package/src/input/commands/agent-workspace-runtime.ts +4 -3
- package/src/input/commands/brief-runtime.ts +38 -9
- package/src/input/commands/channels-runtime.ts +3 -3
- package/src/input/commands/compat-runtime.ts +32 -0
- package/src/input/commands/health-runtime.ts +22 -24
- package/src/input/commands/knowledge.ts +26 -5
- package/src/input/commands/local-provider-runtime.ts +7 -3
- package/src/input/commands/local-setup-review.ts +4 -14
- package/src/input/commands/mcp-runtime.ts +8 -12
- package/src/input/commands/operator-runtime.ts +8 -67
- package/src/input/commands/personas-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +7 -70
- package/src/input/commands/policy-dispatch.ts +1 -1
- package/src/input/commands/policy.ts +1 -5
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/qrcode-runtime.ts +6 -4
- package/src/input/commands/routines-runtime.ts +44 -6
- package/src/input/commands/runtime-services.ts +1 -14
- package/src/input/commands/security-runtime.ts +3 -8
- package/src/input/commands/session-content.ts +1 -1
- package/src/input/commands/session-workflow.ts +5 -14
- package/src/input/commands/shell-core.ts +8 -2
- package/src/input/commands/subscription-runtime.ts +1 -6
- package/src/input/commands/support-bundle-runtime.ts +53 -0
- package/src/input/commands/tasks-runtime.ts +2 -2
- package/src/input/commands.ts +4 -0
- package/src/input/feed-context-factory.ts +0 -1
- package/src/input/handler-content-actions.ts +0 -25
- package/src/input/handler-feed.ts +0 -2
- package/src/input/handler-interactions.ts +2 -31
- package/src/input/handler-onboarding.ts +29 -12
- package/src/input/handler-shortcuts.ts +1 -3
- package/src/input/handler.ts +4 -7
- package/src/input/keybindings.ts +9 -9
- package/src/input/mcp-workspace.ts +90 -26
- package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +49 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +81 -3
- package/src/input/onboarding/onboarding-wizard-steps.ts +14 -7
- package/src/input/onboarding/onboarding-wizard-types.ts +1 -0
- package/src/input/onboarding/onboarding-wizard.ts +19 -2
- package/src/input/profile-picker-modal.ts +2 -2
- package/src/input/settings-modal-agent-policy.ts +6 -6
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal.ts +14 -14
- package/src/main.ts +0 -2
- package/src/panels/automation-control-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +2 -2
- package/src/panels/builtin/session.ts +26 -18
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/project-planning-panel.ts +1 -1
- package/src/panels/provider-health-domains.ts +3 -3
- package/src/panels/qr-panel.ts +44 -20
- package/src/panels/subscription-panel.ts +3 -3
- package/src/panels/system-messages-panel.ts +2 -2
- package/src/panels/tasks-panel.ts +4 -4
- package/src/planning/project-planning-coordinator.ts +2 -2
- package/src/renderer/agent-workspace.ts +26 -5
- package/src/renderer/block-actions.ts +1 -3
- package/src/renderer/help-overlay.ts +13 -8
- package/src/renderer/mcp-workspace.ts +32 -13
- package/src/renderer/model-picker-overlay.ts +0 -1
- package/src/renderer/model-workspace.ts +0 -2
- package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
- package/src/renderer/panel-picker-overlay.ts +1 -1
- package/src/renderer/profile-picker-modal.ts +2 -2
- package/src/renderer/settings-modal-helpers.ts +23 -23
- package/src/renderer/settings-modal.ts +18 -18
- package/src/renderer/system-message.ts +1 -1
- package/src/runtime/agent-runtime-events.ts +129 -0
- package/src/runtime/bootstrap-command-parts.ts +3 -2
- package/src/runtime/bootstrap-core.ts +4 -64
- package/src/runtime/bootstrap-shell.ts +42 -4
- package/src/runtime/bootstrap.ts +8 -27
- package/src/runtime/connected-host-auth.ts +42 -0
- package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
- package/src/runtime/index.ts +1 -5
- package/src/runtime/onboarding/apply.ts +213 -0
- package/src/runtime/onboarding/derivation.ts +5 -5
- package/src/runtime/onboarding/snapshot.ts +2 -2
- package/src/runtime/onboarding/types.ts +26 -1
- package/src/runtime/onboarding/verify.ts +81 -2
- package/src/runtime/operator-token-cleanup.ts +2 -2
- package/src/runtime/services.ts +27 -12
- package/src/shell/service-settings-sync.ts +7 -7
- package/src/shell/ui-openers.ts +27 -38
- package/src/tools/agent-local-registry-tool.ts +10 -4
- package/src/tools/agent-tool-policy-guard.ts +5 -7
- package/src/version.ts +1 -1
- package/src/cli/package-verification.ts +0 -274
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
|
-
- [Connected
|
|
8
|
+
- [Connected Host](connected-host.md)
|
|
9
9
|
- [Release And Publishing](release-and-publishing.md)
|
|
10
10
|
|
|
11
11
|
Important baseline constraints:
|
|
@@ -13,12 +13,13 @@ Important baseline constraints:
|
|
|
13
13
|
- Agent installs one executable: `goodvibes-agent`.
|
|
14
14
|
- Agent uses Bun and TypeScript-authored source.
|
|
15
15
|
- Agent depends on `@pellux/goodvibes-sdk@0.33.35`.
|
|
16
|
-
- Agent connects to GoodVibes
|
|
17
|
-
- Agent does not start, stop, restart, install, uninstall, or own
|
|
16
|
+
- Agent connects to a GoodVibes host owned outside this product.
|
|
17
|
+
- Agent does not start, stop, restart, install, uninstall, or own the connected GoodVibes host.
|
|
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 Agent homes with `GOODVIBES_AGENT_HOME=<path>` and named profile homes with `goodvibes-agent profiles create <name> --template <starter> --yes` plus `--agent-profile <name>`.
|
|
20
|
-
- Agent supports connected-
|
|
20
|
+
- Agent supports connected-host URL overrides with `--runtime-url http://host:port` or `GOODVIBES_AGENT_RUNTIME_URL=http://host:port`; these only change the Agent connection target.
|
|
21
21
|
- 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.
|
|
22
|
+
- First-run setup can seed an initial local persona, skill, and routine without writing to connected-host knowledge or non-Agent segments.
|
|
22
23
|
- Local memory, personas, routines, and Agent skills are stored under the Agent home and are injected only into the serial Agent conversation.
|
|
23
24
|
- Normal assistant chat is not coding-session delegation.
|
|
24
25
|
- Build/fix/review delegation to GoodVibes TUI must be explicit; WRFC is not the default Agent behavior.
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# Connected
|
|
1
|
+
# Connected Host
|
|
2
2
|
|
|
3
|
-
GoodVibes Agent is a TUI client for connected GoodVibes
|
|
3
|
+
GoodVibes Agent is a TUI client for a connected GoodVibes host owned outside this package. The package exposes one executable:
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
6
|
goodvibes-agent
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
The installed command is backed by TypeScript-authored source with a Bun shebang. Package install smoke
|
|
9
|
+
The installed command is backed by TypeScript-authored source with a Bun shebang. Package install smoke verifies the executable path:
|
|
10
10
|
|
|
11
11
|
- `goodvibes-agent --help`
|
|
12
12
|
- `goodvibes-agent --version`
|
|
13
13
|
- `goodvibes-agent status --json`
|
|
14
14
|
- `goodvibes-agent` launches the TUI in a real PTY
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Host Prerequisite
|
|
17
17
|
|
|
18
|
-
Start
|
|
18
|
+
Start the owning GoodVibes host before launching Agent. Agent expects that host to expose public operator routes and the isolated Agent Knowledge routes:
|
|
19
19
|
|
|
20
20
|
```text
|
|
21
21
|
http://127.0.0.1:3421
|
|
@@ -24,10 +24,10 @@ http://127.0.0.1:3421
|
|
|
24
24
|
/api/goodvibes-agent/knowledge/search
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
If the GoodVibes API is on a different host or port, use a one-off override:
|
|
27
|
+
If the GoodVibes API is on a different host or port, use a one-off override when launching the TUI:
|
|
28
28
|
|
|
29
29
|
```sh
|
|
30
|
-
goodvibes-agent --runtime-url http://127.0.0.1:3421
|
|
30
|
+
goodvibes-agent --runtime-url http://127.0.0.1:3421
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
For a persistent shell/session override, set:
|
|
@@ -36,15 +36,23 @@ For a persistent shell/session override, set:
|
|
|
36
36
|
export GOODVIBES_AGENT_RUNTIME_URL=http://127.0.0.1:3421
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
`GOODVIBES_AGENT_BASE_URL` is accepted as a legacy alias. These values only select the connected GoodVibes API root; they do not make Agent own
|
|
39
|
+
`GOODVIBES_AGENT_BASE_URL` is accepted as a legacy alias. These values only select the connected GoodVibes API root; they do not make Agent own host processes.
|
|
40
40
|
|
|
41
|
-
If connected
|
|
41
|
+
If the connected host is unavailable, unauthenticated, or on an incompatible SDK version, the Agent TUI reports actionable diagnostics without printing token values.
|
|
42
|
+
|
|
43
|
+
Use the TUI first for those checks:
|
|
44
|
+
|
|
45
|
+
- Agent Workspace -> Home -> Host compatibility
|
|
46
|
+
- Agent Workspace -> Home -> Doctor diagnostics
|
|
47
|
+
- Agent Workspace -> Home -> Review health
|
|
48
|
+
|
|
49
|
+
`goodvibes-agent status --json`, `goodvibes-agent doctor`, and `goodvibes-agent compat` are scriptable equivalents for install checks and automation.
|
|
42
50
|
|
|
43
51
|
## Product Boundary
|
|
44
52
|
|
|
45
53
|
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.
|
|
46
54
|
|
|
47
|
-
Agent does not own connected-
|
|
55
|
+
Agent does not own connected-host lifecycle. It does not provide commands to install, expose, start, stop, restart, or mutate the connected GoodVibes host.
|
|
48
56
|
|
|
49
57
|
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.
|
|
50
58
|
|
package/docs/getting-started.md
CHANGED
|
@@ -5,12 +5,12 @@ GoodVibes Agent is the installable public alpha of the personal operator assista
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
7
|
- Bun `1.3.10` or newer
|
|
8
|
-
-
|
|
9
|
-
- A token/config path accepted by connected
|
|
8
|
+
- A connected GoodVibes host compatible with `@pellux/goodvibes-sdk@0.33.35`
|
|
9
|
+
- A token/config path accepted by the connected host
|
|
10
10
|
|
|
11
|
-
Agent does not launch connected
|
|
11
|
+
Agent does not launch the connected host for you.
|
|
12
12
|
|
|
13
|
-
Use the interactive TUI first. CLI subcommands are secondary support paths for install checks, setup inspection, and scriptable
|
|
13
|
+
Use the interactive TUI first. CLI subcommands are secondary support paths for install checks, setup inspection, and scriptable mirrors of workflows that are already reachable from the workspace.
|
|
14
14
|
|
|
15
15
|
## Install From Package
|
|
16
16
|
|
|
@@ -18,10 +18,6 @@ Use the interactive TUI first. CLI subcommands are secondary support paths for i
|
|
|
18
18
|
bun add -g @pellux/goodvibes-agent
|
|
19
19
|
goodvibes-agent --help
|
|
20
20
|
goodvibes-agent
|
|
21
|
-
goodvibes-agent status
|
|
22
|
-
goodvibes-agent personas list
|
|
23
|
-
goodvibes-agent skills list
|
|
24
|
-
goodvibes-agent memory list
|
|
25
21
|
```
|
|
26
22
|
|
|
27
23
|
If the installed command is not found, add Bun's global bin directory to `PATH`:
|
|
@@ -44,74 +40,75 @@ bun run dev
|
|
|
44
40
|
|
|
45
41
|
`goodvibes-agent` starts the interactive Agent TUI. On a fresh Agent home, the TUI opens Agent setup first.
|
|
46
42
|
|
|
47
|
-
After setup has been
|
|
43
|
+
After setup has been applied once, the TUI opens directly into the Agent operator workspace. You can also reopen it with `/agent`, `/home`, or `/operator`. That fullscreen workspace is the current front door for setup/config, provider/model selection, Agent Knowledge, local memory/skills/routines/personas, channel readiness, voice/media setup, read-only work/approval/automation views, and explicit GoodVibes TUI build delegation.
|
|
48
44
|
|
|
49
|
-
The setup workspace scans local Agent behavior folders and shows importable persona, skill, and routine files before asking you to create blank records. Use `/personas discover`, `/agent-skills discover`, and `/routines discover` to preview files, then use the matching import action in the workspace after review.
|
|
45
|
+
The setup workspace scans local Agent behavior folders and shows importable persona, skill, and routine files before asking you to create blank records. It can also create one initial local persona, skill, and routine from the setup form. Use `/personas discover`, `/agent-skills discover`, and `/routines discover` to preview files, then use the matching import action in the workspace after review.
|
|
50
46
|
|
|
51
47
|
Use `/agent-profile guide` inside that workspace to walk through starter-profile authoring. It lists built-in and local starters, exports a JSON starter for editing, imports the edited starter back into this Agent home, and creates isolated profiles from the result.
|
|
52
48
|
|
|
53
|
-
Use
|
|
49
|
+
Use the Profiles workspace form to assemble a local starter template and isolated Agent profile from reviewed discovered persona, skill, and routine files. Scriptable profile commands mirror the same flow for automation; use them only when you intentionally want a shell-driven setup path.
|
|
54
50
|
|
|
55
51
|
Use the Knowledge area in that workspace to ingest a source URL without leaving the TUI. The form requires typed confirmation and writes only to the isolated Agent Knowledge segment.
|
|
56
52
|
|
|
57
|
-
Use
|
|
53
|
+
Use the Routines workspace receipt actions to review redacted local routine promotion history and reconcile those receipts with live connected schedules through public `schedules.list`. The `/schedule receipts` and `/schedule reconcile` commands are the power-user equivalents inside the TUI.
|
|
58
54
|
|
|
59
|
-
The local behavior libraries are
|
|
55
|
+
The local behavior libraries are configured in the TUI first:
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
- Memory & Skills -> Create memory or Capture learned behavior.
|
|
58
|
+
- Personas -> Create persona, Use selected, Review selected, or Delete selected.
|
|
59
|
+
- Skills -> Create skill, Create bundle, Enable selected, Review selected, or Delete selected.
|
|
60
|
+
- Routines -> Create routine, Start selected, Enable selected, Promote to schedule, or Review receipts.
|
|
61
|
+
|
|
62
|
+
The installed CLI mirrors these libraries for scripts, but it is not the primary user workflow.
|
|
67
63
|
|
|
68
64
|
## Isolated Agent Profiles
|
|
69
65
|
|
|
70
|
-
Use a separate Agent home when you want isolated local state:
|
|
66
|
+
Use a separate Agent home when you want isolated local state. The normal launch still opens the TUI:
|
|
71
67
|
|
|
72
68
|
```sh
|
|
73
|
-
GOODVIBES_AGENT_HOME=/path/to/agent-home goodvibes-agent
|
|
69
|
+
GOODVIBES_AGENT_HOME=/path/to/agent-home goodvibes-agent
|
|
74
70
|
```
|
|
75
71
|
|
|
76
|
-
Use named Agent profiles for repeatable local identities
|
|
72
|
+
Use named Agent profiles for repeatable local identities from Agent Workspace -> Profiles. The workspace can browse starter templates, create isolated Agent profiles, set or clear the default profile for the next launch, and export/import starter JSON.
|
|
73
|
+
|
|
74
|
+
Scriptable equivalents for automation and setup scripts:
|
|
77
75
|
|
|
78
76
|
```sh
|
|
79
77
|
goodvibes-agent profiles templates
|
|
80
78
|
goodvibes-agent profiles create household --template household --yes
|
|
79
|
+
goodvibes-agent profiles use household --yes
|
|
80
|
+
goodvibes-agent
|
|
81
81
|
goodvibes-agent profiles templates export research ./research-starter.json --yes
|
|
82
82
|
goodvibes-agent profiles templates import ./research-starter.json --yes
|
|
83
83
|
goodvibes-agent --agent-profile household status
|
|
84
84
|
goodvibes-agent --agent-profile household
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
Named profiles isolate Agent-local config, sessions, memory, personas, skills, routines, and setup state under a profile-specific home. Starter templates seed local personas, skills, and routines for household, research, travel, operations, and personal productivity profiles; exported starter JSON can be edited and re-imported as a local starter. They do not start or isolate connected
|
|
87
|
+
Named profiles isolate Agent-local config, sessions, memory, personas, skills, routines, and setup state under a profile-specific home. `profiles use <name> --yes` makes one profile the default for the next plain `goodvibes-agent` launch; `--agent-profile <name>` still overrides it for one launch, and `profiles default clear --yes` returns plain launches to the base Agent home. Starter templates seed local personas, skills, and routines for household, research, travel, operations, and personal productivity profiles; exported starter JSON can be edited and re-imported as a local starter. They do not start or isolate the connected host by themselves.
|
|
88
88
|
|
|
89
89
|
## Local Memory, Personas, Routines, And Skills
|
|
90
90
|
|
|
91
|
-
Memory, personas, routines, and reusable Agent skills are local to GoodVibes Agent. They do not write into default Knowledge/Wiki or non-Agent knowledge segments.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
/memory add fact "Prefers concise morning briefings" --scope project --tags preference
|
|
105
|
-
/memory search morning
|
|
106
|
-
```
|
|
91
|
+
Memory, personas, routines, and reusable Agent skills are local to GoodVibes Agent. First-run setup, TUI workspace forms, and CLI commands all write them to Agent-local registries. They do not write into default Knowledge/Wiki or non-Agent knowledge segments.
|
|
92
|
+
|
|
93
|
+
Use `Capture learned behavior` in the Agent workspace after reviewing a repeated workflow, lesson, or operating style. It saves one local skill, routine, or persona from the TUI and does not call connected-host mutation routes.
|
|
94
|
+
|
|
95
|
+
Day-one local behavior setup should stay in the fullscreen workspace:
|
|
96
|
+
|
|
97
|
+
- Personas -> Create persona, then Use selected.
|
|
98
|
+
- Routines -> Create routine, Start selected, or Promote to schedule after entering real timing and confirmation.
|
|
99
|
+
- Skills -> Create skill, Enable selected, and review setup requirements.
|
|
100
|
+
- Memory & Skills -> Create memory or Search memory.
|
|
101
|
+
- Channels -> inspect readiness before enabling notification delivery.
|
|
102
|
+
|
|
103
|
+
Typed slash commands are available for repeat users, but they are not required for the first-run workflow.
|
|
107
104
|
|
|
108
|
-
The active persona plus enabled Agent routines, reviewed memory, and skills are injected into the main serial assistant conversation. Starting a routine records local usage and prints its steps; it does not
|
|
105
|
+
The active persona plus enabled Agent routines, reviewed memory, and skills are injected into the main serial assistant conversation. Starting a routine records local usage and prints its steps; it does not launch local workers or automation jobs. Promoting a routine to a schedule is an explicit `schedules.create` call, requires `--yes`, writes a local redacted promotion receipt, and preserves the rule that Agent Knowledge never falls back to default Knowledge/Wiki or non-Agent knowledge segments.
|
|
109
106
|
|
|
110
107
|
Use `/channels` inside the TUI for a read-only channel readiness matrix. It shows enabled channels, missing config key names, delivery posture, and risk labels without sending messages or rendering token values.
|
|
111
108
|
|
|
112
|
-
## Connected GoodVibes
|
|
109
|
+
## Connected GoodVibes Host
|
|
113
110
|
|
|
114
|
-
Start
|
|
111
|
+
Start the owning GoodVibes host before using connected Agent features. Agent expects that host to expose the public operator/Agent routes, including:
|
|
115
112
|
|
|
116
113
|
- `/status`
|
|
117
114
|
- `/api/goodvibes-agent/knowledge/status`
|
|
@@ -119,11 +116,11 @@ Start connected GoodVibes services from GoodVibes TUI or the owning host before
|
|
|
119
116
|
- `/api/goodvibes-agent/knowledge/search`
|
|
120
117
|
- `/api/goodvibes-agent/knowledge/ingest/url`
|
|
121
118
|
|
|
122
|
-
If the GoodVibes API is not on `http://127.0.0.1:3421`,
|
|
119
|
+
If the GoodVibes API is not on `http://127.0.0.1:3421`, pass `--runtime-url http://host:port` for a one-off TUI launch or set `GOODVIBES_AGENT_RUNTIME_URL=http://host:port` before launching the TUI.
|
|
123
120
|
|
|
124
121
|
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.
|
|
125
122
|
|
|
126
|
-
|
|
123
|
+
Host lifecycle commands are not part of GoodVibes Agent. Use Agent Workspace -> Home -> Host compatibility, Doctor diagnostics, and Review health for diagnostics. CLI status/doctor/compat commands are scriptable mirrors for install checks.
|
|
127
124
|
|
|
128
125
|
## Current Product Notes
|
|
129
126
|
|
|
@@ -9,7 +9,7 @@ GoodVibes Agent's current installable public alpha version is recorded in `packa
|
|
|
9
9
|
- SDK dependency: exact pin to `@pellux/goodvibes-sdk@0.33.35`
|
|
10
10
|
- runtime: Bun
|
|
11
11
|
- source language: TypeScript
|
|
12
|
-
- connected
|
|
12
|
+
- connected host ownership: outside Agent
|
|
13
13
|
|
|
14
14
|
End users install and run GoodVibes Agent with Bun:
|
|
15
15
|
|
|
@@ -36,6 +36,8 @@ git diff --check
|
|
|
36
36
|
|
|
37
37
|
`bun run publish:package` publishes from a staged package directory to the package registry. If `NPM_CONFIG_USERCONFIG` is already set, the registry publish command uses it. Otherwise the script creates a temporary 0600 registry userconfig from `NODE_AUTH_TOKEN` or `NPM_TOKEN`, uses it for that publish command, and removes it with the staging directory. The publish script is idempotent for reruns: if the exact package version is already present on the registry, it reports that state and exits successfully instead of failing the release retry.
|
|
38
38
|
|
|
39
|
+
`bun run release` requires product release notes instead of raw git-log output. Pass `--notes-file ./release-notes.md` or set `GOODVIBES_AGENT_RELEASE_NOTES` before a real release. Release notes should describe what changed for Agent users: TUI behavior, setup, Agent Knowledge, local behavior libraries, connected-host compatibility, package/install behavior, and safety policy. Do not use commit hashes as the shipped changelog content.
|
|
40
|
+
|
|
39
41
|
The GitHub release workflow publishes to npm only when the repository variable `PUBLISH_NPM` is `true` and the repository secret `NPM_TOKEN` is configured. Without those repository settings, the workflow still validates and creates the GitHub release, but npm publish must be run from a local environment with an exported token.
|
|
40
42
|
|
|
41
43
|
Branch CI is the only workflow that runs the full test suite and release gates. It runs `bun run test` once for the release SHA, along with typecheck, architecture, performance, build, publish, and packed install checks. The release workflow must not run tests or duplicate those gates; it verifies that branch CI passed for the exact checked-out SHA and then performs only package packing, GitHub Release creation, and optional npm publish.
|
|
@@ -52,16 +54,16 @@ Also run the package install smoke from a packed artifact. It must prove:
|
|
|
52
54
|
- `goodvibes-agent --help` works
|
|
53
55
|
- `goodvibes-agent --version` reports the package version
|
|
54
56
|
- the installed TUI launches in a PTY and does not exit immediately
|
|
55
|
-
- connected-
|
|
57
|
+
- connected-host commands fail clearly when GoodVibes host is unavailable or unauthenticated
|
|
56
58
|
- no token value is printed
|
|
57
59
|
|
|
58
60
|
## Do Not Ship
|
|
59
61
|
|
|
60
|
-
Do not publish if package-facing docs or install commands refer to another package name, another executable, or Agent-owned connected-
|
|
62
|
+
Do not publish if package-facing docs or install commands refer to another package name, another executable, or Agent-owned connected-host lifecycle.
|
|
61
63
|
|
|
62
64
|
Do not publish if Agent Knowledge commands can fall back to default Knowledge/Wiki or another product-specific knowledge route. Agent Knowledge must use the isolated `/api/goodvibes-agent/knowledge/*` segment.
|
|
63
65
|
|
|
64
|
-
Do not ship GoodVibes service binaries from this package. If Agent later gets compiled artifacts, they must use Agent artifact names and remain separate from connected-
|
|
66
|
+
Do not ship GoodVibes service binaries from this package. If Agent later gets compiled artifacts, they must use Agent artifact names and remain separate from connected-host ownership.
|
|
65
67
|
|
|
66
68
|
## Product Rule
|
|
67
69
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.117",
|
|
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",
|
|
@@ -17,13 +17,14 @@
|
|
|
17
17
|
"!src/test",
|
|
18
18
|
"!src/**/*.test.ts",
|
|
19
19
|
"!src/**/__tests__",
|
|
20
|
+
"!src/cli/package-verification.ts",
|
|
20
21
|
"!src/verification",
|
|
21
22
|
"tsconfig.json",
|
|
22
23
|
"README.md",
|
|
23
24
|
"CHANGELOG.md",
|
|
24
25
|
"docs/README.md",
|
|
25
26
|
"docs/getting-started.md",
|
|
26
|
-
"docs/connected-
|
|
27
|
+
"docs/connected-host.md",
|
|
27
28
|
"docs/release-and-publishing.md"
|
|
28
29
|
],
|
|
29
30
|
"scripts": {
|
|
@@ -54,7 +55,6 @@
|
|
|
54
55
|
"build:all": "bun run scripts/build.ts --all",
|
|
55
56
|
"perf:check": "bun run scripts/perf-check.ts",
|
|
56
57
|
"architecture:check": "bun run scripts/check-architecture.ts",
|
|
57
|
-
"foundation:artifacts": "bun run scripts/export-foundation-artifacts.ts",
|
|
58
58
|
"verification:ledger": "bun run scripts/verification-ledger.ts",
|
|
59
59
|
"verification:live": "bun run scripts/verify-live.ts"
|
|
60
60
|
},
|
|
@@ -126,12 +126,10 @@ function definitions(shellPaths: Pick<ShellPathService, 'workingDirectory' | 'ho
|
|
|
126
126
|
roots: [
|
|
127
127
|
{ root: join(cwd, '.goodvibes', 'personas'), origin: 'project-local' },
|
|
128
128
|
{ root: join(cwd, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'personas'), origin: 'project-local' },
|
|
129
|
-
{ root: join(cwd, '.goodvibes', 'agents'), origin: 'project-local' },
|
|
130
129
|
{ root: join(homeDir, '.goodvibes', 'personas'), origin: 'global' },
|
|
131
130
|
{ root: join(homeDir, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'personas'), origin: 'global' },
|
|
132
|
-
{ root: join(homeDir, '.goodvibes', 'agents'), origin: 'global' },
|
|
133
131
|
],
|
|
134
|
-
markers: ['PERSONA.md', 'persona.md'
|
|
132
|
+
markers: ['PERSONA.md', 'persona.md'],
|
|
135
133
|
frontmatterBodyKey: 'system_prompt',
|
|
136
134
|
};
|
|
137
135
|
const skills: DiscoveryKindDefinition = {
|
|
@@ -14,7 +14,7 @@ export interface DiscoveredPersonaRecord {
|
|
|
14
14
|
readonly frontmatter: Record<string, string>;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const DIRECTORY_MARKERS: readonly string[] = ['PERSONA.md', 'persona.md'
|
|
17
|
+
const DIRECTORY_MARKERS: readonly string[] = ['PERSONA.md', 'persona.md'];
|
|
18
18
|
|
|
19
19
|
function parseFrontmatter(content: string): Record<string, string> {
|
|
20
20
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -33,10 +33,8 @@ function getPersonaDirectories(cwd: string, homeDir: string): Array<{ root: stri
|
|
|
33
33
|
return [
|
|
34
34
|
{ root: join(cwd, '.goodvibes', 'personas'), origin: 'project-local' },
|
|
35
35
|
{ root: join(cwd, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'personas'), origin: 'project-local' },
|
|
36
|
-
{ root: join(cwd, '.goodvibes', 'agents'), origin: 'project-local' },
|
|
37
36
|
{ root: join(homeDir, '.goodvibes', 'personas'), origin: 'global' },
|
|
38
37
|
{ root: join(homeDir, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'personas'), origin: 'global' },
|
|
39
|
-
{ root: join(homeDir, '.goodvibes', 'agents'), origin: 'global' },
|
|
40
38
|
];
|
|
41
39
|
}
|
|
42
40
|
|
|
@@ -158,14 +158,16 @@ function formatStore(store: PersonaStoreFile): string {
|
|
|
158
158
|
return `${JSON.stringify(store, null, 2)}\n`;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
type AgentLocalStorePaths = Pick<ShellPathService, 'resolveUserPath'>;
|
|
162
|
+
|
|
163
|
+
export function personaStorePath(shellPaths: AgentLocalStorePaths): string {
|
|
162
164
|
return shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, 'personas', 'personas.json');
|
|
163
165
|
}
|
|
164
166
|
|
|
165
167
|
export class AgentPersonaRegistry {
|
|
166
168
|
public constructor(private readonly storePath: string) {}
|
|
167
169
|
|
|
168
|
-
public static fromShellPaths(shellPaths:
|
|
170
|
+
public static fromShellPaths(shellPaths: AgentLocalStorePaths): AgentPersonaRegistry {
|
|
169
171
|
return new AgentPersonaRegistry(personaStorePath(shellPaths));
|
|
170
172
|
}
|
|
171
173
|
|
|
@@ -374,6 +376,6 @@ export function buildActivePersonaPrompt(shellPaths: ShellPathService): string |
|
|
|
374
376
|
'',
|
|
375
377
|
active.body,
|
|
376
378
|
'',
|
|
377
|
-
'Apply this persona inside the same serial assistant conversation. Do not
|
|
379
|
+
'Apply this persona inside the same serial assistant conversation. Do not launch local workers because a persona is active.',
|
|
378
380
|
].join('\n');
|
|
379
381
|
}
|
|
@@ -33,7 +33,7 @@ export function formatReminderSchedulePreview(preview: ReminderSchedulePreview):
|
|
|
33
33
|
` schedule: ${preview.payload.kind} ${scheduleValue(preview)}`,
|
|
34
34
|
` enabled: ${preview.payload.enabled === false ? 'no' : 'yes'}`,
|
|
35
35
|
` delivery: ${delivery?.mode ?? 'none'}${deliveryTargetCount > 0 ? ` (${deliveryTargetCount} target${deliveryTargetCount === 1 ? '' : 's'})` : ''}`,
|
|
36
|
-
' target: connected GoodVibes
|
|
36
|
+
' target: connected GoodVibes host/main conversation route',
|
|
37
37
|
' policy: reminder delivery only; isolated Agent Knowledge only; no default wiki/non-Agent fallback',
|
|
38
38
|
' next: rerun with --yes to create this connected reminder schedule',
|
|
39
39
|
].join('\n');
|
|
@@ -57,19 +57,19 @@ export function formatReminderScheduleFailure(failure: ReminderScheduleFailure):
|
|
|
57
57
|
return [
|
|
58
58
|
`GoodVibes reminder schedule error: ${failure.kind}`,
|
|
59
59
|
` ${failure.error}`,
|
|
60
|
-
failure.baseUrl ? `
|
|
60
|
+
failure.baseUrl ? ` host: ${failure.baseUrl}` : null,
|
|
61
61
|
` route: ${REMINDER_SCHEDULE_METHOD} ${failure.route}`,
|
|
62
62
|
failure.kind === 'version_mismatch' && failure.daemonVersion && failure.expectedSdkVersion
|
|
63
|
-
? ` versions:
|
|
63
|
+
? ` versions: host=${failure.daemonVersion} expected=${failure.expectedSdkVersion}`
|
|
64
64
|
: null,
|
|
65
65
|
failure.kind === 'auth_required'
|
|
66
|
-
? ' next: pair/authenticate with connected GoodVibes
|
|
66
|
+
? ' next: pair/authenticate with the connected GoodVibes host, then retry with --yes.'
|
|
67
67
|
: null,
|
|
68
68
|
failure.kind === 'daemon_unavailable'
|
|
69
|
-
? ' next: make connected GoodVibes
|
|
69
|
+
? ' next: make the connected GoodVibes host available outside Agent, then retry.'
|
|
70
70
|
: null,
|
|
71
71
|
failure.kind === 'version_mismatch' || failure.kind === 'daemon_route_unavailable'
|
|
72
|
-
? ' next: update connected GoodVibes
|
|
72
|
+
? ' next: update the connected GoodVibes host so public schedules.create is available.'
|
|
73
73
|
: null,
|
|
74
74
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
75
75
|
}
|
|
@@ -468,7 +468,7 @@ export async function createReminderSchedule(
|
|
|
468
468
|
return {
|
|
469
469
|
ok: false,
|
|
470
470
|
kind: 'auth_required',
|
|
471
|
-
error: `No
|
|
471
|
+
error: `No connected-host operator token found at ${connection.tokenPath}`,
|
|
472
472
|
route: REMINDER_SCHEDULE_ROUTE,
|
|
473
473
|
baseUrl: connection.baseUrl,
|
|
474
474
|
};
|
|
@@ -3,9 +3,18 @@ import { dirname } from 'node:path';
|
|
|
3
3
|
import type { ShellPathService } from '@/runtime/index.ts';
|
|
4
4
|
import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
|
|
5
5
|
import { assertNoSecretLikeText } from './persona-registry.ts';
|
|
6
|
+
import {
|
|
7
|
+
evaluateAgentSkillReadiness,
|
|
8
|
+
formatAgentSkillRequirement,
|
|
9
|
+
normalizeAgentSkillRequirements,
|
|
10
|
+
type AgentSkillReadiness,
|
|
11
|
+
type AgentSkillRequirement,
|
|
12
|
+
} from './skill-registry.ts';
|
|
6
13
|
|
|
7
14
|
export type AgentRoutineSource = 'user' | 'agent' | 'imported' | 'system';
|
|
8
15
|
export type AgentRoutineReviewState = 'fresh' | 'reviewed' | 'stale';
|
|
16
|
+
export type AgentRoutineRequirement = AgentSkillRequirement;
|
|
17
|
+
export type AgentRoutineReadiness = AgentSkillReadiness;
|
|
9
18
|
|
|
10
19
|
export interface AgentRoutineRecord {
|
|
11
20
|
readonly id: string;
|
|
@@ -14,6 +23,7 @@ export interface AgentRoutineRecord {
|
|
|
14
23
|
readonly steps: string;
|
|
15
24
|
readonly triggers: readonly string[];
|
|
16
25
|
readonly tags: readonly string[];
|
|
26
|
+
readonly requirements: readonly AgentRoutineRequirement[];
|
|
17
27
|
readonly enabled: boolean;
|
|
18
28
|
readonly source: AgentRoutineSource;
|
|
19
29
|
readonly provenance: string;
|
|
@@ -32,6 +42,7 @@ export interface AgentRoutineCreateInput {
|
|
|
32
42
|
readonly steps: string;
|
|
33
43
|
readonly triggers?: readonly string[];
|
|
34
44
|
readonly tags?: readonly string[];
|
|
45
|
+
readonly requirements?: readonly AgentRoutineRequirement[];
|
|
35
46
|
readonly enabled?: boolean;
|
|
36
47
|
readonly source?: AgentRoutineSource;
|
|
37
48
|
readonly provenance?: string;
|
|
@@ -43,6 +54,7 @@ export interface AgentRoutineUpdateInput {
|
|
|
43
54
|
readonly steps?: string;
|
|
44
55
|
readonly triggers?: readonly string[];
|
|
45
56
|
readonly tags?: readonly string[];
|
|
57
|
+
readonly requirements?: readonly AgentRoutineRequirement[];
|
|
46
58
|
readonly provenance?: string;
|
|
47
59
|
}
|
|
48
60
|
|
|
@@ -72,6 +84,18 @@ function readStringArray(value: unknown): string[] {
|
|
|
72
84
|
return value.filter((entry): entry is string => typeof entry === 'string').map((entry) => entry.trim()).filter(Boolean);
|
|
73
85
|
}
|
|
74
86
|
|
|
87
|
+
function readRequirementArray(value: unknown): readonly AgentRoutineRequirement[] {
|
|
88
|
+
if (!Array.isArray(value)) return [];
|
|
89
|
+
const requirements = value
|
|
90
|
+
.filter(isRecord)
|
|
91
|
+
.map((entry) => ({
|
|
92
|
+
kind: entry.kind === 'command' ? 'command' as const : 'env' as const,
|
|
93
|
+
name: readString(entry.name).trim(),
|
|
94
|
+
description: readString(entry.description).trim() || undefined,
|
|
95
|
+
}));
|
|
96
|
+
return normalizeAgentSkillRequirements(requirements);
|
|
97
|
+
}
|
|
98
|
+
|
|
75
99
|
function readNonNegativeInteger(value: unknown): number {
|
|
76
100
|
const parsed = typeof value === 'number' ? value : Number(value);
|
|
77
101
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : 0;
|
|
@@ -123,6 +147,7 @@ function parseRoutine(value: unknown): AgentRoutineRecord | null {
|
|
|
123
147
|
steps,
|
|
124
148
|
triggers: readStringArray(value.triggers),
|
|
125
149
|
tags: readStringArray(value.tags),
|
|
150
|
+
requirements: readRequirementArray(value.requirements),
|
|
126
151
|
enabled: value.enabled === true,
|
|
127
152
|
source,
|
|
128
153
|
provenance: readString(value.provenance, source).trim() || source,
|
|
@@ -151,14 +176,16 @@ function formatStore(store: RoutineStoreFile): string {
|
|
|
151
176
|
return `${JSON.stringify(store, null, 2)}\n`;
|
|
152
177
|
}
|
|
153
178
|
|
|
154
|
-
|
|
179
|
+
type AgentLocalStorePaths = Pick<ShellPathService, 'resolveUserPath'>;
|
|
180
|
+
|
|
181
|
+
export function routineStorePath(shellPaths: AgentLocalStorePaths): string {
|
|
155
182
|
return shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, 'routines', 'routines.json');
|
|
156
183
|
}
|
|
157
184
|
|
|
158
185
|
export class AgentRoutineRegistry {
|
|
159
186
|
public constructor(private readonly storePath: string) {}
|
|
160
187
|
|
|
161
|
-
public static fromShellPaths(shellPaths:
|
|
188
|
+
public static fromShellPaths(shellPaths: AgentLocalStorePaths): AgentRoutineRegistry {
|
|
162
189
|
return new AgentRoutineRegistry(routineStorePath(shellPaths));
|
|
163
190
|
}
|
|
164
191
|
|
|
@@ -200,7 +227,8 @@ export class AgentRoutineRegistry {
|
|
|
200
227
|
const description = input.description.trim();
|
|
201
228
|
const steps = input.steps.trim();
|
|
202
229
|
this.validateRequired(name, description, steps);
|
|
203
|
-
|
|
230
|
+
const requirements = normalizeAgentSkillRequirements(input.requirements);
|
|
231
|
+
assertNoSecretLikeText([name, description, steps, ...(input.tags ?? []), ...(input.triggers ?? []), ...requirements.flatMap((requirement) => [requirement.name, requirement.description ?? ''])]);
|
|
204
232
|
const duplicate = store.routines.find((routine) => routine.name.toLowerCase() === name.toLowerCase());
|
|
205
233
|
if (duplicate) throw new Error(`Routine already exists: ${duplicate.id}`);
|
|
206
234
|
const timestamp = nowIso();
|
|
@@ -211,6 +239,7 @@ export class AgentRoutineRegistry {
|
|
|
211
239
|
steps,
|
|
212
240
|
triggers: normalizeList(input.triggers),
|
|
213
241
|
tags: normalizeList(input.tags),
|
|
242
|
+
requirements,
|
|
214
243
|
enabled: input.enabled === true,
|
|
215
244
|
source: input.source ?? 'user',
|
|
216
245
|
provenance: input.provenance?.trim() || input.source || 'user',
|
|
@@ -231,7 +260,8 @@ export class AgentRoutineRegistry {
|
|
|
231
260
|
const description = input.description === undefined ? existing.description : input.description.trim();
|
|
232
261
|
const steps = input.steps === undefined ? existing.steps : input.steps.trim();
|
|
233
262
|
this.validateRequired(name, description, steps);
|
|
234
|
-
|
|
263
|
+
const requirements = input.requirements === undefined ? existing.requirements : normalizeAgentSkillRequirements(input.requirements);
|
|
264
|
+
assertNoSecretLikeText([name, description, steps, ...(input.tags ?? []), ...(input.triggers ?? []), ...requirements.flatMap((requirement) => [requirement.name, requirement.description ?? ''])]);
|
|
235
265
|
const duplicate = store.routines.find((routine) => routine.id !== existing.id && routine.name.toLowerCase() === name.toLowerCase());
|
|
236
266
|
if (duplicate) throw new Error(`Routine already exists: ${duplicate.id}`);
|
|
237
267
|
const updated: AgentRoutineRecord = {
|
|
@@ -241,6 +271,7 @@ export class AgentRoutineRegistry {
|
|
|
241
271
|
steps,
|
|
242
272
|
triggers: input.triggers === undefined ? existing.triggers : normalizeList(input.triggers),
|
|
243
273
|
tags: input.tags === undefined ? existing.tags : normalizeList(input.tags),
|
|
274
|
+
requirements,
|
|
244
275
|
provenance: input.provenance === undefined ? existing.provenance : input.provenance.trim() || existing.provenance,
|
|
245
276
|
reviewState: 'fresh',
|
|
246
277
|
staleReason: undefined,
|
|
@@ -370,6 +401,13 @@ export class AgentRoutineRegistry {
|
|
|
370
401
|
}
|
|
371
402
|
}
|
|
372
403
|
|
|
404
|
+
export function evaluateAgentRoutineReadiness(
|
|
405
|
+
routine: Pick<AgentRoutineRecord, 'requirements'>,
|
|
406
|
+
options: Parameters<typeof evaluateAgentSkillReadiness>[1] = {},
|
|
407
|
+
): AgentRoutineReadiness {
|
|
408
|
+
return evaluateAgentSkillReadiness(routine, options);
|
|
409
|
+
}
|
|
410
|
+
|
|
373
411
|
export function buildEnabledRoutinesPrompt(shellPaths: ShellPathService): string | null {
|
|
374
412
|
const enabled = AgentRoutineRegistry.fromShellPaths(shellPaths).snapshot().enabledRoutines;
|
|
375
413
|
if (enabled.length === 0) return null;
|
|
@@ -382,6 +420,7 @@ export function buildEnabledRoutinesPrompt(shellPaths: ShellPathService): string
|
|
|
382
420
|
`Description: ${routine.description}`,
|
|
383
421
|
`Review state: ${routine.reviewState}`,
|
|
384
422
|
`Triggers: ${routine.triggers.join(', ') || '(manual)'}`,
|
|
423
|
+
`Readiness: ${evaluateAgentRoutineReadiness(routine).ready ? 'ready' : `missing ${evaluateAgentRoutineReadiness(routine).missing.map(formatAgentSkillRequirement).join(', ')}`}`,
|
|
385
424
|
routine.steps,
|
|
386
425
|
'',
|
|
387
426
|
]),
|
|
@@ -111,13 +111,13 @@ export function formatRoutineScheduleCorrelation(result: RoutineScheduleCorrelat
|
|
|
111
111
|
result.baseUrl ? ` runtime: ${result.baseUrl}` : null,
|
|
112
112
|
` route: ${ROUTINE_SCHEDULE_LIST_METHOD} ${result.route}`,
|
|
113
113
|
result.kind === 'auth_required'
|
|
114
|
-
? ' next: pair/authenticate with connected GoodVibes
|
|
114
|
+
? ' next: pair/authenticate with the connected GoodVibes host, then retry.'
|
|
115
115
|
: null,
|
|
116
116
|
result.kind === 'daemon_unavailable'
|
|
117
|
-
? ' next: make connected GoodVibes
|
|
117
|
+
? ' next: make the connected GoodVibes host available outside Agent, then retry.'
|
|
118
118
|
: null,
|
|
119
119
|
result.kind === 'version_mismatch' || result.kind === 'daemon_route_unavailable'
|
|
120
|
-
? ' next: update connected GoodVibes
|
|
120
|
+
? ' next: update the connected GoodVibes host so public schedules.list is available.'
|
|
121
121
|
: null,
|
|
122
122
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
123
123
|
}
|
|
@@ -166,13 +166,13 @@ export function formatRoutineScheduleFailure(failure: RoutineSchedulePromotionFa
|
|
|
166
166
|
? ` versions: runtime=${failure.daemonVersion} expected=${failure.expectedSdkVersion}`
|
|
167
167
|
: null,
|
|
168
168
|
failure.kind === 'auth_required'
|
|
169
|
-
? ' next: pair/authenticate with connected GoodVibes
|
|
169
|
+
? ' next: pair/authenticate with the connected GoodVibes host, then retry with --yes.'
|
|
170
170
|
: null,
|
|
171
171
|
failure.kind === 'daemon_unavailable'
|
|
172
|
-
? ' next: make connected GoodVibes
|
|
172
|
+
? ' next: make the connected GoodVibes host available outside Agent, then retry.'
|
|
173
173
|
: null,
|
|
174
174
|
failure.kind === 'version_mismatch' || failure.kind === 'daemon_route_unavailable'
|
|
175
|
-
? ' next: update connected GoodVibes
|
|
175
|
+
? ' next: update the connected GoodVibes host so public schedules.create is available.'
|
|
176
176
|
: null,
|
|
177
177
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
178
178
|
}
|
|
@@ -416,7 +416,7 @@ export async function promoteRoutineToDaemonSchedule(
|
|
|
416
416
|
return {
|
|
417
417
|
ok: false,
|
|
418
418
|
kind: 'auth_required',
|
|
419
|
-
error: `No
|
|
419
|
+
error: `No connected-host operator token found at ${connection.tokenPath}`,
|
|
420
420
|
route: ROUTINE_SCHEDULE_ROUTE,
|
|
421
421
|
baseUrl: connection.baseUrl,
|
|
422
422
|
};
|