@pellux/goodvibes-agent 1.1.6 → 1.2.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/CHANGELOG.md +176 -0
- package/README.md +46 -30
- package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
- package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
- package/dist/package/main.js +132662 -91399
- package/docs/README.md +14 -7
- package/docs/channels-remote-and-api.md +8 -5
- package/docs/connected-host.md +14 -12
- package/docs/getting-started.md +56 -30
- package/docs/knowledge-artifacts-and-multimodal.md +7 -5
- package/docs/project-planning.md +2 -2
- package/docs/providers-and-routing.md +11 -3
- package/docs/tools-and-commands.md +114 -45
- package/docs/voice-and-live-tts.md +3 -1
- package/package.json +3 -2
- package/release/release-notes.md +130 -5
- package/release/release-readiness.json +120 -90
- package/src/agent/assistant-cockpit.ts +247 -0
- package/src/agent/autonomy-schedule-format.ts +96 -0
- package/src/agent/autonomy-schedule.ts +514 -0
- package/src/agent/channel-delivery-receipts.ts +292 -0
- package/src/agent/competitive-feature-inventory.ts +296 -0
- package/src/agent/document-registry-types.ts +106 -0
- package/src/agent/document-registry.ts +734 -0
- package/src/agent/harness-control.ts +2 -2
- package/src/agent/memory-prompt.ts +2 -2
- package/src/agent/operator-actions.ts +50 -6
- package/src/agent/persona-registry.ts +8 -0
- package/src/agent/project-context-files.ts +273 -0
- package/src/agent/prompt-context-receipts.ts +502 -0
- package/src/agent/reminder-schedule-format.ts +16 -2
- package/src/agent/research-run-registry.ts +582 -0
- package/src/agent/research-source-registry.ts +441 -0
- package/src/agent/routine-registry.ts +19 -3
- package/src/agent/routine-schedule-format.ts +27 -2
- package/src/agent/runtime-profile-starters.ts +7 -0
- package/src/agent/runtime-profile.ts +106 -4
- package/src/agent/schedule-edit-format.ts +129 -0
- package/src/agent/schedule-edit.ts +496 -0
- package/src/agent/schedule-next-routes.ts +42 -0
- package/src/agent/setup-wizard-checkpoint.ts +140 -0
- package/src/agent/setup-wizard.ts +447 -0
- package/src/agent/skill-registry-types.ts +102 -0
- package/src/agent/skill-registry.ts +81 -107
- package/src/agent/vibe-confirmation-routes.ts +62 -0
- package/src/agent/vibe-file.ts +285 -0
- package/src/cli/agent-knowledge-command.ts +45 -2
- package/src/cli/help.ts +3 -0
- package/src/cli/profiles-command.ts +25 -11
- package/src/config/agent-settings-policy.ts +1 -18
- package/src/input/agent-workspace-activation.ts +53 -0
- package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
- package/src/input/agent-workspace-artifact-metadata.ts +17 -0
- package/src/input/agent-workspace-basic-command-editors.ts +5 -1
- package/src/input/agent-workspace-categories.ts +153 -155
- package/src/input/agent-workspace-channel-triage.ts +481 -0
- package/src/input/agent-workspace-channels.ts +263 -0
- package/src/input/agent-workspace-command-editor.ts +152 -0
- package/src/input/agent-workspace-context-snapshot.ts +349 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
- package/src/input/agent-workspace-document-editor.ts +502 -0
- package/src/input/agent-workspace-document-ops-editor.ts +523 -0
- package/src/input/agent-workspace-host-category.ts +1 -1
- package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
- package/src/input/agent-workspace-model-compare-editor.ts +376 -0
- package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
- package/src/input/agent-workspace-model-compare-types.ts +82 -0
- package/src/input/agent-workspace-model-compare-utils.ts +35 -0
- package/src/input/agent-workspace-onboarding-categories.ts +141 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
- package/src/input/agent-workspace-operations-command-editors.ts +22 -0
- package/src/input/agent-workspace-research-report-editor.ts +212 -0
- package/src/input/agent-workspace-research-run-editor.ts +144 -0
- package/src/input/agent-workspace-research-source-editor.ts +167 -0
- package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
- package/src/input/agent-workspace-review-packet-utils.ts +265 -0
- package/src/input/agent-workspace-settings.ts +262 -30
- package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
- package/src/input/agent-workspace-setup-snapshot.ts +198 -0
- package/src/input/agent-workspace-setup.ts +34 -1
- package/src/input/agent-workspace-snapshot.ts +162 -147
- package/src/input/agent-workspace-types.ts +287 -2
- package/src/input/agent-workspace.ts +18 -0
- package/src/input/command-registry.ts +9 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
- package/src/input/commands/channels-runtime.ts +102 -114
- package/src/input/commands/delegation-runtime.ts +87 -24
- package/src/input/commands/knowledge-browser-flags.ts +12 -0
- package/src/input/commands/knowledge.ts +28 -14
- package/src/input/commands/operator-actions-runtime.ts +6 -3
- package/src/input/commands/schedule-runtime.ts +71 -14
- package/src/input/commands/session-content.ts +2 -2
- package/src/input/commands/shell-core.ts +2 -0
- package/src/input/commands/vibe-runtime.ts +140 -0
- package/src/input/commands.ts +2 -0
- package/src/input/connected-host-routes.ts +123 -0
- package/src/input/settings-modal-types.ts +14 -0
- package/src/main.ts +15 -15
- package/src/panels/qr-panel.ts +2 -2
- package/src/renderer/agent-workspace-context-lines.ts +686 -0
- package/src/renderer/agent-workspace.ts +30 -419
- package/src/renderer/settings-modal-helpers.ts +12 -0
- package/src/renderer/settings-modal.ts +12 -0
- package/src/runtime/bootstrap-command-context.ts +11 -1
- package/src/runtime/bootstrap-command-parts.ts +14 -3
- package/src/runtime/bootstrap-core.ts +43 -1
- package/src/runtime/bootstrap-shell.ts +6 -0
- package/src/runtime/bootstrap.ts +113 -30
- package/src/runtime/connected-host-auth.ts +3 -2
- package/src/runtime/execution-ledger.ts +231 -0
- package/src/runtime/services.ts +88 -10
- package/src/runtime/tool-permission-safety.ts +287 -0
- package/src/shell/session-continuity-hints.ts +39 -0
- package/src/tools/agent-artifacts-tool.ts +606 -0
- package/src/tools/agent-audit-tool.ts +155 -0
- package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
- package/src/tools/agent-autonomy-tool.ts +140 -0
- package/src/tools/agent-channel-send-tool.ts +24 -2
- package/src/tools/agent-channels-tool.ts +140 -0
- package/src/tools/agent-computer-tool.ts +168 -0
- package/src/tools/agent-context-policy.ts +267 -10
- package/src/tools/agent-context-tool.ts +143 -0
- package/src/tools/agent-delegation-tool.ts +128 -0
- package/src/tools/agent-device-tool.ts +240 -0
- package/src/tools/agent-documents-tool.ts +684 -0
- package/src/tools/agent-execution-tool.ts +230 -0
- package/src/tools/agent-harness-agent-orchestration.ts +703 -0
- package/src/tools/agent-harness-autonomy-intake.ts +785 -0
- package/src/tools/agent-harness-autonomy-live-records.ts +588 -0
- package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
- package/src/tools/agent-harness-autonomy-queue.ts +560 -0
- package/src/tools/agent-harness-background-processes-types.ts +35 -0
- package/src/tools/agent-harness-background-processes.ts +794 -0
- package/src/tools/agent-harness-browser-cockpit-route.ts +219 -0
- package/src/tools/agent-harness-browser-control.ts +338 -0
- package/src/tools/agent-harness-channel-metadata.ts +168 -10
- package/src/tools/agent-harness-cli-command-policy.ts +110 -0
- package/src/tools/agent-harness-command-catalog.ts +4 -2
- package/src/tools/agent-harness-command-runner.ts +42 -0
- package/src/tools/agent-harness-connected-host-status.ts +7 -4
- package/src/tools/agent-harness-delegation-posture.ts +234 -19
- package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
- package/src/tools/agent-harness-document-ops-types.ts +72 -0
- package/src/tools/agent-harness-document-ops.ts +671 -0
- package/src/tools/agent-harness-execution-history.ts +489 -0
- package/src/tools/agent-harness-execution-posture.ts +382 -0
- package/src/tools/agent-harness-file-recovery.ts +135 -0
- package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
- package/src/tools/agent-harness-learning-curator-common.ts +102 -0
- package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
- package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
- package/src/tools/agent-harness-learning-curator-types.ts +151 -0
- package/src/tools/agent-harness-learning-curator.ts +417 -0
- package/src/tools/agent-harness-local-model-benchmarks.ts +199 -0
- package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
- package/src/tools/agent-harness-local-model-endpoints.ts +673 -0
- package/src/tools/agent-harness-media-posture.ts +208 -2
- package/src/tools/agent-harness-memory-posture.ts +556 -0
- package/src/tools/agent-harness-metadata.ts +100 -168
- package/src/tools/agent-harness-mode-catalog.ts +84 -33
- package/src/tools/agent-harness-model-catalog.ts +162 -0
- package/src/tools/agent-harness-model-provider-health.ts +186 -0
- package/src/tools/agent-harness-model-readiness.ts +406 -0
- package/src/tools/agent-harness-model-routing-types.ts +266 -0
- package/src/tools/agent-harness-model-routing-utils.ts +30 -0
- package/src/tools/agent-harness-model-routing.ts +137 -190
- package/src/tools/agent-harness-operator-methods.ts +115 -133
- package/src/tools/agent-harness-pairing-posture.ts +431 -18
- package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
- package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
- package/src/tools/agent-harness-personal-ops-lanes.ts +204 -0
- package/src/tools/agent-harness-personal-ops-records.ts +732 -0
- package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
- package/src/tools/agent-harness-personal-ops-types.ts +222 -0
- package/src/tools/agent-harness-personal-ops.ts +606 -0
- package/src/tools/agent-harness-project-context.ts +144 -0
- package/src/tools/agent-harness-prompt-context.ts +589 -0
- package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
- package/src/tools/agent-harness-release-evidence.ts +9 -7
- package/src/tools/agent-harness-release-readiness.ts +9 -7
- package/src/tools/agent-harness-research-briefing.ts +427 -0
- package/src/tools/agent-harness-research-queue.ts +250 -0
- package/src/tools/agent-harness-research-runs.ts +295 -0
- package/src/tools/agent-harness-research-workflow.ts +322 -0
- package/src/tools/agent-harness-security-posture.ts +2 -2
- package/src/tools/agent-harness-service-posture.ts +9 -9
- package/src/tools/agent-harness-session-metadata.ts +3 -3
- package/src/tools/agent-harness-setup-connected-host.ts +501 -0
- package/src/tools/agent-harness-setup-describe.ts +557 -0
- package/src/tools/agent-harness-setup-handoffs.ts +502 -0
- package/src/tools/agent-harness-setup-model-helpers.ts +101 -0
- package/src/tools/agent-harness-setup-plan.ts +253 -0
- package/src/tools/agent-harness-setup-posture-types.ts +218 -0
- package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
- package/src/tools/agent-harness-setup-posture.ts +449 -221
- package/src/tools/agent-harness-setup-smoke.ts +508 -0
- package/src/tools/agent-harness-sudo-posture.ts +114 -0
- package/src/tools/agent-harness-tool-schema.ts +120 -7
- package/src/tools/agent-harness-tool-types.ts +78 -0
- package/src/tools/agent-harness-tool-utils.ts +43 -0
- package/src/tools/agent-harness-tool.ts +311 -370
- package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
- package/src/tools/agent-harness-ui-surface-types.ts +46 -0
- package/src/tools/agent-harness-vibe-health.ts +105 -0
- package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
- package/src/tools/agent-harness-workspace-actions.ts +114 -8
- package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
- package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
- package/src/tools/agent-host-tool.ts +159 -0
- package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
- package/src/tools/agent-learning-consolidation-core.ts +327 -0
- package/src/tools/agent-learning-consolidation-tool.ts +758 -0
- package/src/tools/agent-memory-tool.ts +214 -0
- package/src/tools/agent-model-compare-export.ts +315 -0
- package/src/tools/agent-model-compare-handoff.ts +592 -0
- package/src/tools/agent-model-compare-judgment.ts +633 -0
- package/src/tools/agent-model-compare-run.ts +722 -0
- package/src/tools/agent-model-compare-tool.ts +698 -0
- package/src/tools/agent-model-compare-types.ts +191 -0
- package/src/tools/agent-model-compare-utils.ts +93 -0
- package/src/tools/agent-models-tool.ts +208 -0
- package/src/tools/agent-operator-action-tool.ts +1 -1
- package/src/tools/agent-operator-method-tool.ts +643 -0
- package/src/tools/agent-personal-ops-tool.ts +197 -0
- package/src/tools/agent-policy-explanation.ts +415 -0
- package/src/tools/agent-research-report-tool.ts +608 -0
- package/src/tools/agent-research-runs-tool.ts +434 -0
- package/src/tools/agent-research-sources-tool.ts +443 -0
- package/src/tools/agent-research-tool.ts +687 -0
- package/src/tools/agent-review-packet-presets-core.ts +757 -0
- package/src/tools/agent-review-packet-presets-tool.ts +466 -0
- package/src/tools/agent-review-packet-share-tool.ts +305 -0
- package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
- package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
- package/src/tools/agent-route-planner-candidates-work.ts +251 -0
- package/src/tools/agent-route-planner-helpers.ts +667 -0
- package/src/tools/agent-route-planner.ts +185 -0
- package/src/tools/agent-route-tool.ts +105 -0
- package/src/tools/agent-schedule-edit-tool.ts +210 -0
- package/src/tools/agent-schedule-tool.ts +282 -0
- package/src/tools/agent-security-tool.ts +145 -0
- package/src/tools/agent-sessions-tool.ts +122 -0
- package/src/tools/agent-settings-import-tool.ts +104 -0
- package/src/tools/agent-settings-tool.ts +176 -0
- package/src/tools/agent-setup-tool.ts +226 -0
- package/src/tools/agent-support-tool.ts +122 -0
- package/src/tools/agent-terminal-process-tools.ts +167 -0
- package/src/tools/agent-tool-policy-guard-types.ts +77 -0
- package/src/tools/agent-tool-policy-guard.ts +110 -89
- package/src/tools/agent-vibe-tool.ts +297 -0
- package/src/tools/agent-work-plan-tool.ts +265 -6
- package/src/tools/agent-workspace-tool.ts +305 -0
- package/src/tools/artifact-archive.ts +169 -0
- package/src/tools/tool-definition-compaction.ts +36 -0
- package/src/tools/tool-execution-safety.ts +41 -0
- package/src/version.ts +1 -1
|
@@ -1,248 +1,124 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { getOrCreateCompanionToken } from '@pellux/goodvibes-sdk/platform/pairing';
|
|
3
|
+
import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../config/surface.ts';
|
|
3
4
|
import type { CommandContext } from '../input/command-registry.ts';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import { requireShellPaths } from '../input/commands/runtime-services.ts';
|
|
6
|
+
import { deriveStep1Capabilities, deriveStep1CapabilityFlags } from '../runtime/onboarding/index.ts';
|
|
7
|
+
import { connectedHostOperatorTokenFingerprint, connectedHostOperatorTokenPath, readConnectedHostOperatorToken } from '../runtime/connected-host-auth.ts';
|
|
8
|
+
import { clearSetupWizardCheckpoint, saveSetupWizardCheckpoint } from '../agent/setup-wizard-checkpoint.ts';
|
|
9
|
+
import { DEFAULT_AGENT_SETUP_WIZARD_CLEAR_CHECKPOINT_ROUTE, DEFAULT_AGENT_SETUP_WIZARD_INSPECT_CHECKPOINT_ROUTE, DEFAULT_AGENT_SETUP_WIZARD_MARK_CHECKPOINT_ROUTE, DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE, DEFAULT_AGENT_SETUP_WIZARD_RERUN_SMOKE_ROUTE, DEFAULT_AGENT_SETUP_WIZARD_SAVE_SMOKE_ROUTE } from '../agent/setup-wizard.ts';
|
|
6
10
|
import { previewHarnessText } from './agent-harness-text.ts';
|
|
11
|
+
import type { AgentHarnessSetupArgs, SetupResolution } from './agent-harness-setup-posture-types.ts';
|
|
12
|
+
import { buildSetupPlan } from './agent-harness-setup-plan.ts';
|
|
13
|
+
import { buildSetupWizard, describeInstallSmokeCheck, installSmokeNextAction, installSmokeRunResult, installSmokeRunSummary, latestSetupSmokeEvidence, saveSetupSmokeArtifact, setupCompletionMarkerExists, setupSmokeEvidenceFields, setupSmokeEvidenceHistory } from './agent-harness-setup-smoke.ts';
|
|
14
|
+
import { confirmedRepairCandidates, describeCandidate, describeHandoffCard, describeItem, describePlanItem, describeRepairCard, describeRepairDecision, describeServiceLifecycleDecision, nextSetupHandoffSummaries, planSearchText, planSummary, primarySetupRepairDecision, setupRepairTarget } from './agent-harness-setup-describe.ts';
|
|
15
|
+
import { setupHandoffsForItem } from './agent-harness-setup-handoffs.ts';
|
|
16
|
+
import { collectServicePosture, collectSnapshot, itemSearchText, lookupFromArgs, quoteRouteValue, readLimit, readString, safeFileMode, safeIso, summarizeLocalBehavior } from './agent-harness-setup-posture-utils.ts';
|
|
7
17
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
type SetupResolution =
|
|
17
|
-
| { readonly status: 'found'; readonly item: Record<string, unknown> }
|
|
18
|
-
| { readonly status: 'ambiguous'; readonly input: string; readonly candidates: readonly Record<string, unknown>[] }
|
|
19
|
-
| { readonly status: 'missing_lookup'; readonly usage: string };
|
|
20
|
-
|
|
21
|
-
type SetupLookupSource = 'setupItemId' | 'target' | 'query';
|
|
22
|
-
|
|
23
|
-
interface SurfaceRegistryLike {
|
|
24
|
-
syncConfiguredSurfaces(): readonly OnboardingSurfaceRecord[];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function readString(value: unknown): string {
|
|
28
|
-
return typeof value === 'string' ? value.trim() : '';
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function readLimit(value: unknown, fallback: number): number {
|
|
32
|
-
const parsed = typeof value === 'string' && value.trim() ? Number(value) : value;
|
|
33
|
-
if (typeof parsed !== 'number' || !Number.isFinite(parsed)) return fallback;
|
|
34
|
-
return Math.max(1, Math.min(500, Math.trunc(parsed)));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function safeIso(value: number | null | undefined): string | null {
|
|
38
|
-
if (typeof value !== 'number' || !Number.isFinite(value)) return null;
|
|
39
|
-
return new Date(value).toISOString();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function surfaceRegistry(context: CommandContext): SurfaceRegistryLike | undefined {
|
|
43
|
-
const candidate = (context.platform as { readonly surfaceRegistry?: unknown }).surfaceRegistry;
|
|
44
|
-
if (candidate && typeof candidate === 'object' && 'syncConfiguredSurfaces' in candidate) {
|
|
45
|
-
return candidate as SurfaceRegistryLike;
|
|
46
|
-
}
|
|
47
|
-
return undefined;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function collectSnapshot(context: CommandContext) {
|
|
51
|
-
const registry = surfaceRegistry(context);
|
|
52
|
-
return await collectOnboardingSnapshot({
|
|
53
|
-
config: requirePlatform(context).configManager,
|
|
54
|
-
shellPaths: requireShellPaths(context),
|
|
55
|
-
acknowledgementScope: 'project',
|
|
56
|
-
subscriptions: requireSubscriptionManager(context),
|
|
57
|
-
secrets: requireSecretsManager(context),
|
|
58
|
-
auth: requireLocalUserAuthManager(context),
|
|
59
|
-
services: requireServiceRegistry(context),
|
|
60
|
-
...(registry ? {
|
|
61
|
-
surfaces: {
|
|
62
|
-
list: () => registry.syncConfiguredSurfaces(),
|
|
63
|
-
},
|
|
64
|
-
} : {}),
|
|
65
|
-
providerAccounts: {
|
|
66
|
-
loadSnapshot: () => buildProviderAccountSnapshot({
|
|
67
|
-
providerModels: requireProvider(context).providerRegistry,
|
|
68
|
-
services: requireServiceRegistry(context),
|
|
69
|
-
subscriptions: requireSubscriptionManager(context),
|
|
70
|
-
environment: {
|
|
71
|
-
hasEnvironmentVariable: (name: string) => Boolean(process.env[name]),
|
|
72
|
-
},
|
|
73
|
-
}),
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function lookupFromArgs(args: AgentHarnessSetupArgs): { readonly source: SetupLookupSource; readonly input: string } | null {
|
|
79
|
-
const setupItemId = readString(args.setupItemId);
|
|
80
|
-
if (setupItemId) return { source: 'setupItemId', input: setupItemId };
|
|
81
|
-
const target = readString(args.target);
|
|
82
|
-
if (target) return { source: 'target', input: target };
|
|
83
|
-
const query = readString(args.query);
|
|
84
|
-
return query ? { source: 'query', input: query } : null;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function itemSearchText(item: OnboardingStep1CapabilityItem): string {
|
|
88
|
-
return [
|
|
89
|
-
item.id,
|
|
90
|
-
item.label,
|
|
91
|
-
item.detail,
|
|
92
|
-
item.selected ? 'selected ready configured enabled' : 'optional attention unselected',
|
|
93
|
-
].join('\n').toLowerCase();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function summarizeLocalBehavior(snapshot: Awaited<ReturnType<typeof collectSnapshot>>): Record<string, unknown> {
|
|
97
|
-
const discovery = snapshot.localBehaviorDiscovery;
|
|
98
|
-
return {
|
|
99
|
-
personas: discovery.personas,
|
|
100
|
-
skills: discovery.skills,
|
|
101
|
-
routines: discovery.routines,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function signalsForItem(
|
|
106
|
-
item: OnboardingStep1CapabilityItem,
|
|
107
|
-
snapshot: Awaited<ReturnType<typeof collectSnapshot>>,
|
|
108
|
-
): Record<string, unknown> {
|
|
109
|
-
if (item.id === 'provider-access') {
|
|
110
|
-
return {
|
|
111
|
-
currentRoute: snapshot.providerRouting,
|
|
112
|
-
providerAccounts: {
|
|
113
|
-
providers: snapshot.providerAccounts?.providers.length ?? 0,
|
|
114
|
-
configured: snapshot.providerAccounts?.configuredCount ?? 0,
|
|
115
|
-
issues: snapshot.providerAccounts?.issueCount ?? 0,
|
|
116
|
-
},
|
|
117
|
-
subscriptions: {
|
|
118
|
-
active: snapshot.subscriptions.active.length,
|
|
119
|
-
pending: snapshot.subscriptions.pending.length,
|
|
120
|
-
activeProviderIds: snapshot.subscriptions.activeProviderIds,
|
|
121
|
-
pendingProviderIds: snapshot.subscriptions.pendingProviderIds,
|
|
122
|
-
},
|
|
123
|
-
credentialReferences: snapshot.secrets.records.length,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
if (item.id === 'local-behavior') {
|
|
127
|
-
return summarizeLocalBehavior(snapshot);
|
|
128
|
-
}
|
|
129
|
-
if (item.id === 'communication-channels') {
|
|
130
|
-
return {
|
|
131
|
-
configuredEnabledKinds: snapshot.surfaces.configuredEnabledKinds,
|
|
132
|
-
surfaces: snapshot.surfaces.records.map((surface) => ({
|
|
133
|
-
id: surface.id,
|
|
134
|
-
kind: surface.kind,
|
|
135
|
-
label: surface.label,
|
|
136
|
-
enabled: surface.enabled,
|
|
137
|
-
state: surface.state,
|
|
138
|
-
capabilities: surface.capabilities,
|
|
139
|
-
})),
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
if (item.id === 'automation-review') {
|
|
143
|
-
return {
|
|
144
|
-
permissionsMode: snapshot.runtimeDefaults.permissionsMode,
|
|
145
|
-
helperEnabled: snapshot.providerRouting.helperEnabled,
|
|
146
|
-
toolLlmEnabled: snapshot.providerRouting.toolLlmEnabled,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
if (item.id === 'operator-terminal') {
|
|
150
|
-
return {
|
|
151
|
-
display: snapshot.runtimeDefaults.display,
|
|
152
|
-
setupMarker: {
|
|
153
|
-
scope: snapshot.acknowledgements.scope,
|
|
154
|
-
exists: snapshot.acknowledgements.exists,
|
|
155
|
-
updatedAt: safeIso(snapshot.acknowledgements.updatedAt),
|
|
156
|
-
source: snapshot.acknowledgements.source,
|
|
157
|
-
mode: snapshot.acknowledgements.mode ?? null,
|
|
158
|
-
},
|
|
159
|
-
collectionIssues: snapshot.collectionIssues,
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
return {
|
|
163
|
-
status: item.selected ? 'covered' : 'available',
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function describeItem(
|
|
168
|
-
item: OnboardingStep1CapabilityItem,
|
|
169
|
-
snapshot: Awaited<ReturnType<typeof collectSnapshot>>,
|
|
170
|
-
options: {
|
|
171
|
-
readonly includeParameters?: boolean;
|
|
172
|
-
readonly lookup?: Record<string, unknown>;
|
|
173
|
-
} = {},
|
|
174
|
-
): Record<string, unknown> {
|
|
18
|
+
export async function setupPostureCatalogStatus(context: CommandContext): Promise<Record<string, unknown>> {
|
|
19
|
+
const snapshot = await collectSnapshot(context);
|
|
20
|
+
const servicePosture = await collectServicePosture(context);
|
|
21
|
+
const plan = buildSetupPlan(context, snapshot, deriveStep1Capabilities(snapshot), servicePosture);
|
|
22
|
+
const setupSmokeEvidence = latestSetupSmokeEvidence(context);
|
|
23
|
+
const setupSmokeHistory = setupSmokeEvidenceHistory(context);
|
|
24
|
+
const setupWizard = buildSetupWizard(plan, context);
|
|
175
25
|
return {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
},
|
|
190
|
-
modelAccess: {
|
|
191
|
-
inspectSetup: 'agent_harness mode:"setup_posture"',
|
|
192
|
-
inspectSetupItem: 'agent_harness mode:"setup_item"',
|
|
193
|
-
openOnboarding: 'agent_harness mode:"open_ui_surface" surfaceId:"onboarding" confirm:true explicitUserRequest:"..."',
|
|
194
|
-
setupWorkspace: 'agent_harness mode:"workspace_action" target:"setup"',
|
|
195
|
-
settings: 'agent_harness mode:"settings"; inspect or mutate with get_setting, set_setting, or reset_setting',
|
|
196
|
-
providerRouting: 'agent_harness mode:"model_routing"',
|
|
197
|
-
providerAccounts: 'agent_harness mode:"provider_accounts"',
|
|
198
|
-
channels: 'agent_harness mode:"channels"',
|
|
199
|
-
media: 'agent_harness mode:"media_posture"',
|
|
200
|
-
security: 'agent_harness mode:"security_posture"',
|
|
201
|
-
},
|
|
202
|
-
}
|
|
203
|
-
: {
|
|
204
|
-
summary: previewHarnessText(item.detail),
|
|
205
|
-
}),
|
|
26
|
+
modes: ['setup_posture', 'setup_item', 'setup_repair', 'setup_checkpoint', 'mark_setup_checkpoint', 'clear_setup_checkpoint', 'provision_connected_host_token', 'run_setup_smoke'],
|
|
27
|
+
capabilities: deriveStep1Capabilities(snapshot).length,
|
|
28
|
+
planItems: plan.length,
|
|
29
|
+
blockedPlanItems: plan.filter((item) => item.status === 'blocked').length,
|
|
30
|
+
autonomyBlockers: plan.filter((item) => item.blocksAutonomy && item.status !== 'ready').length,
|
|
31
|
+
nextSetupHandoffs: nextSetupHandoffSummaries(plan, 5),
|
|
32
|
+
setupWizard,
|
|
33
|
+
setupCloseout: setupWizard.closeout,
|
|
34
|
+
collectionIssues: snapshot.collectionIssues.length,
|
|
35
|
+
setupMarkerExists: setupCompletionMarkerExists(context),
|
|
36
|
+
setupSmokeEvidence,
|
|
37
|
+
setupSmokeHistory,
|
|
38
|
+
readOnly: true,
|
|
206
39
|
};
|
|
207
40
|
}
|
|
208
41
|
|
|
209
|
-
function
|
|
210
|
-
|
|
211
|
-
|
|
42
|
+
export async function setupRepairSummary(context: CommandContext, args: AgentHarnessSetupArgs): Promise<Record<string, unknown>> {
|
|
43
|
+
const snapshot = await collectSnapshot(context);
|
|
44
|
+
const servicePosture = await collectServicePosture(context);
|
|
45
|
+
const plan = buildSetupPlan(context, snapshot, deriveStep1Capabilities(snapshot), servicePosture);
|
|
46
|
+
const setupWizard = buildSetupWizard(plan, context);
|
|
47
|
+
const includeParameters = args.includeParameters === true;
|
|
48
|
+
const target = setupRepairTarget(plan, setupWizard, args);
|
|
49
|
+
if ('error' in target) return target.error;
|
|
212
50
|
|
|
213
|
-
|
|
51
|
+
const item = target.item;
|
|
52
|
+
const decision = primarySetupRepairDecision(item);
|
|
53
|
+
const handoffs = setupHandoffsForItem(item);
|
|
54
|
+
const alternatives = handoffs
|
|
55
|
+
.filter((handoff) => handoff.id !== decision.id)
|
|
56
|
+
.slice(0, includeParameters ? 8 : 3)
|
|
57
|
+
.map((handoff) => describeHandoffCard(handoff, includeParameters));
|
|
58
|
+
const confirmedCandidates = confirmedRepairCandidates(item);
|
|
214
59
|
return {
|
|
60
|
+
mode: 'setup_repair',
|
|
61
|
+
capturedAt: new Date(snapshot.capturedAt).toISOString(),
|
|
215
62
|
setupItemId: item.id,
|
|
216
63
|
label: item.label,
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
64
|
+
status: item.status,
|
|
65
|
+
blocksAutonomy: item.blocksAutonomy,
|
|
66
|
+
lookup: target.lookup,
|
|
67
|
+
decision: describeRepairDecision(decision, includeParameters),
|
|
68
|
+
nextAction: previewHarnessText(item.nextAction, includeParameters ? 220 : 140),
|
|
69
|
+
userRoute: previewHarnessText(item.userRoute, includeParameters ? 160 : 120),
|
|
70
|
+
modelRoute: previewHarnessText(item.modelRoute, includeParameters ? 160 : 120),
|
|
71
|
+
alternatives,
|
|
72
|
+
...(confirmedCandidates.length > 0 ? {
|
|
73
|
+
possibleConfirmedRepairs: confirmedCandidates.map((candidate) => describeRepairDecision(candidate, includeParameters)),
|
|
74
|
+
} : {}),
|
|
75
|
+
...(item.serviceProbe ? { serviceProbe: item.serviceProbe } : {}),
|
|
76
|
+
...(item.serviceLifecycleDecision ? { serviceLifecycleDecision: describeServiceLifecycleDecision(item.serviceLifecycleDecision) } : {}),
|
|
77
|
+
...(includeParameters && item.repairCards ? { repairCards: item.repairCards.map(describeRepairCard) } : {}),
|
|
78
|
+
...(includeParameters && item.bootstrapPlan ? { bootstrapPlan: item.bootstrapPlan } : {}),
|
|
79
|
+
...(includeParameters && item.authPosture ? { authPosture: item.authPosture } : {}),
|
|
80
|
+
setupWizard: {
|
|
81
|
+
status: setupWizard.status,
|
|
82
|
+
currentStepId: setupWizard.currentStepId,
|
|
83
|
+
currentStepLabel: setupWizard.currentStepLabel,
|
|
84
|
+
closeout: setupWizard.closeout,
|
|
85
|
+
},
|
|
86
|
+
routes: {
|
|
87
|
+
inspectSetup: DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
88
|
+
inspectItem: `setup action:"item" setupItemId:"${quoteRouteValue(item.id)}" includeParameters:true`,
|
|
89
|
+
rerunRepair: `setup action:"repair" setupItemId:"${quoteRouteValue(item.id)}" includeParameters:true`,
|
|
90
|
+
},
|
|
91
|
+
policy: {
|
|
92
|
+
effect: 'read-only-repair-decision',
|
|
93
|
+
boundary: 'This route chooses the safest next setup repair route only. It never starts, installs, restarts, writes tokens, imports settings, or opens UI by itself.',
|
|
94
|
+
confirmation: 'Any returned confirmed-effect route still requires confirm:true and explicitUserRequest tied to the user request.',
|
|
95
|
+
hostOwnership: 'GoodVibes Agent does not take ambient ownership of the GoodVibes host lifecycle; disconnected hosts use user-run bootstrap guidance, and reachable hosts use daemon receipts before lifecycle mutation.',
|
|
96
|
+
},
|
|
230
97
|
};
|
|
231
98
|
}
|
|
232
99
|
|
|
233
100
|
export async function setupPostureSummary(context: CommandContext, args: AgentHarnessSetupArgs): Promise<Record<string, unknown>> {
|
|
234
101
|
const snapshot = await collectSnapshot(context);
|
|
102
|
+
const servicePosture = await collectServicePosture(context);
|
|
235
103
|
const query = readString(args.query).toLowerCase();
|
|
236
104
|
const includeParameters = args.includeParameters === true;
|
|
237
105
|
const all = deriveStep1Capabilities(snapshot);
|
|
106
|
+
const plan = buildSetupPlan(context, snapshot, all, servicePosture);
|
|
107
|
+
const setupSmokeEvidence = latestSetupSmokeEvidence(context);
|
|
108
|
+
const setupSmokeHistory = setupSmokeEvidenceHistory(context);
|
|
109
|
+
const setupWizard = buildSetupWizard(plan, context);
|
|
238
110
|
const filtered = all
|
|
239
111
|
.filter((item) => !query || itemSearchText(item).includes(query))
|
|
240
112
|
.slice(0, readLimit(args.limit, 100));
|
|
113
|
+
const filteredPlan = plan
|
|
114
|
+
.filter((item) => !query || planSearchText(item).includes(query))
|
|
115
|
+
.slice(0, readLimit(args.limit, 100));
|
|
241
116
|
return {
|
|
242
117
|
capturedAt: new Date(snapshot.capturedAt).toISOString(),
|
|
243
118
|
setupMarker: {
|
|
244
119
|
scope: snapshot.acknowledgements.scope,
|
|
245
120
|
exists: snapshot.acknowledgements.exists,
|
|
121
|
+
completionExists: setupCompletionMarkerExists(context),
|
|
246
122
|
updatedAt: safeIso(snapshot.acknowledgements.updatedAt),
|
|
247
123
|
source: snapshot.acknowledgements.source,
|
|
248
124
|
mode: snapshot.acknowledgements.mode ?? null,
|
|
@@ -265,9 +141,26 @@ export async function setupPostureSummary(context: CommandContext, args: AgentHa
|
|
|
265
141
|
enabledSurfaceKinds: snapshot.surfaces.configuredEnabledKinds.length,
|
|
266
142
|
localBehavior: summarizeLocalBehavior(snapshot),
|
|
267
143
|
capabilityFlags: deriveStep1CapabilityFlags(snapshot),
|
|
144
|
+
readinessPlan: planSummary(plan),
|
|
145
|
+
setupSmokeEvidence,
|
|
146
|
+
setupSmokeHistory,
|
|
147
|
+
setupWizard: {
|
|
148
|
+
status: setupWizard.status,
|
|
149
|
+
progressLabel: setupWizard.progressLabel,
|
|
150
|
+
currentStepId: setupWizard.currentStepId,
|
|
151
|
+
currentStepLabel: setupWizard.currentStepLabel,
|
|
152
|
+
repeatedBlocker: setupWizard.repeatedBlocker,
|
|
153
|
+
},
|
|
154
|
+
setupCloseout: setupWizard.closeout,
|
|
268
155
|
},
|
|
156
|
+
setupSmokeEvidence,
|
|
157
|
+
setupSmokeHistory,
|
|
158
|
+
setupWizard,
|
|
159
|
+
setupCloseout: setupWizard.closeout,
|
|
269
160
|
currentRoute: snapshot.providerRouting,
|
|
270
161
|
issues: snapshot.collectionIssues,
|
|
162
|
+
readinessPlan: filteredPlan.map((item) => describePlanItem(item, includeParameters)),
|
|
163
|
+
nextSetupActions: nextSetupHandoffSummaries(plan, 5),
|
|
271
164
|
capabilities: filtered.map((item) => describeItem(item, snapshot, { includeParameters })),
|
|
272
165
|
returned: filtered.length,
|
|
273
166
|
total: all.length,
|
|
@@ -275,6 +168,330 @@ export async function setupPostureSummary(context: CommandContext, args: AgentHa
|
|
|
275
168
|
};
|
|
276
169
|
}
|
|
277
170
|
|
|
171
|
+
export async function setupCheckpointSummary(context: CommandContext): Promise<Record<string, unknown>> {
|
|
172
|
+
const snapshot = await collectSnapshot(context);
|
|
173
|
+
const servicePosture = await collectServicePosture(context);
|
|
174
|
+
const plan = buildSetupPlan(context, snapshot, deriveStep1Capabilities(snapshot), servicePosture);
|
|
175
|
+
const setupWizard = buildSetupWizard(plan, context);
|
|
176
|
+
return {
|
|
177
|
+
mode: 'setup_checkpoint',
|
|
178
|
+
checkpoint: setupWizard.checkpoint,
|
|
179
|
+
currentStep: setupWizard.currentStepId
|
|
180
|
+
? setupWizard.steps.find((step) => step.id === setupWizard.currentStepId) ?? null
|
|
181
|
+
: null,
|
|
182
|
+
setupWizard: {
|
|
183
|
+
status: setupWizard.status,
|
|
184
|
+
progressLabel: setupWizard.progressLabel,
|
|
185
|
+
currentStepId: setupWizard.currentStepId,
|
|
186
|
+
currentStepLabel: setupWizard.currentStepLabel,
|
|
187
|
+
next: setupWizard.next,
|
|
188
|
+
},
|
|
189
|
+
routes: {
|
|
190
|
+
inspectSetup: DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
191
|
+
markCurrent: DEFAULT_AGENT_SETUP_WIZARD_MARK_CHECKPOINT_ROUTE,
|
|
192
|
+
clear: DEFAULT_AGENT_SETUP_WIZARD_CLEAR_CHECKPOINT_ROUTE,
|
|
193
|
+
},
|
|
194
|
+
policy: 'Read-only checkpoint inspection. Saving or clearing the setup wizard checkpoint requires a confirmed route with explicit user request.',
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export async function markSetupCheckpoint(context: CommandContext, args: AgentHarnessSetupArgs): Promise<Record<string, unknown>> {
|
|
199
|
+
const snapshot = await collectSnapshot(context);
|
|
200
|
+
const servicePosture = await collectServicePosture(context);
|
|
201
|
+
const plan = buildSetupPlan(context, snapshot, deriveStep1Capabilities(snapshot), servicePosture);
|
|
202
|
+
const setupWizard = buildSetupWizard(plan, context);
|
|
203
|
+
const requestedStepId = readString(args.setupItemId);
|
|
204
|
+
const step = requestedStepId
|
|
205
|
+
? setupWizard.steps.find((candidate) => candidate.id === requestedStepId)
|
|
206
|
+
: setupWizard.currentStepId
|
|
207
|
+
? setupWizard.steps.find((candidate) => candidate.id === setupWizard.currentStepId)
|
|
208
|
+
: null;
|
|
209
|
+
if (!step) {
|
|
210
|
+
return {
|
|
211
|
+
status: 'no_checkpoint_written',
|
|
212
|
+
mode: 'mark_setup_checkpoint',
|
|
213
|
+
reason: requestedStepId
|
|
214
|
+
? `Unknown setup wizard step ${requestedStepId}.`
|
|
215
|
+
: 'Setup wizard has no current step to checkpoint.',
|
|
216
|
+
setupWizard: {
|
|
217
|
+
status: setupWizard.status,
|
|
218
|
+
currentStepId: setupWizard.currentStepId,
|
|
219
|
+
currentStepLabel: setupWizard.currentStepLabel,
|
|
220
|
+
},
|
|
221
|
+
routes: {
|
|
222
|
+
inspectSetup: DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
if (step.sourceStatus === 'ready') {
|
|
227
|
+
return {
|
|
228
|
+
status: 'no_checkpoint_written',
|
|
229
|
+
mode: 'mark_setup_checkpoint',
|
|
230
|
+
reason: `Setup wizard step ${step.label} is already ready.`,
|
|
231
|
+
step,
|
|
232
|
+
routes: {
|
|
233
|
+
inspectSetup: DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
234
|
+
clear: DEFAULT_AGENT_SETUP_WIZARD_CLEAR_CHECKPOINT_ROUTE,
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
const shellPaths = requireShellPaths(context);
|
|
239
|
+
const checkpoint = saveSetupWizardCheckpoint(shellPaths, {
|
|
240
|
+
currentStepId: step.id,
|
|
241
|
+
currentStepLabel: step.label,
|
|
242
|
+
source: 'harness',
|
|
243
|
+
note: 'User-confirmed setup wizard checkpoint.',
|
|
244
|
+
});
|
|
245
|
+
const updatedWizard = buildSetupWizard(plan, context);
|
|
246
|
+
return {
|
|
247
|
+
status: 'checkpoint_saved',
|
|
248
|
+
mode: 'mark_setup_checkpoint',
|
|
249
|
+
explicitUserRequest: previewHarnessText(readString(args.explicitUserRequest), 160),
|
|
250
|
+
step,
|
|
251
|
+
checkpoint,
|
|
252
|
+
setupWizard: {
|
|
253
|
+
status: updatedWizard.status,
|
|
254
|
+
progressLabel: updatedWizard.progressLabel,
|
|
255
|
+
currentStepId: updatedWizard.currentStepId,
|
|
256
|
+
currentStepLabel: updatedWizard.currentStepLabel,
|
|
257
|
+
checkpoint: updatedWizard.checkpoint,
|
|
258
|
+
},
|
|
259
|
+
routes: {
|
|
260
|
+
inspectCheckpoint: DEFAULT_AGENT_SETUP_WIZARD_INSPECT_CHECKPOINT_ROUTE,
|
|
261
|
+
inspectSetup: DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
262
|
+
clear: DEFAULT_AGENT_SETUP_WIZARD_CLEAR_CHECKPOINT_ROUTE,
|
|
263
|
+
},
|
|
264
|
+
policy: {
|
|
265
|
+
effect: 'confirmed-setup-checkpoint-save',
|
|
266
|
+
boundary: 'Only the current setup wizard step id, label, source, timestamp, and generic note were saved in Agent-owned setup state.',
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function clearSetupCheckpoint(context: CommandContext, args: AgentHarnessSetupArgs): Record<string, unknown> {
|
|
272
|
+
const shellPaths = requireShellPaths(context);
|
|
273
|
+
const checkpoint = clearSetupWizardCheckpoint(shellPaths);
|
|
274
|
+
return {
|
|
275
|
+
status: 'checkpoint_cleared',
|
|
276
|
+
mode: 'clear_setup_checkpoint',
|
|
277
|
+
explicitUserRequest: previewHarnessText(readString(args.explicitUserRequest), 160),
|
|
278
|
+
checkpoint,
|
|
279
|
+
routes: {
|
|
280
|
+
inspectCheckpoint: DEFAULT_AGENT_SETUP_WIZARD_INSPECT_CHECKPOINT_ROUTE,
|
|
281
|
+
inspectSetup: DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
282
|
+
markCurrent: DEFAULT_AGENT_SETUP_WIZARD_MARK_CHECKPOINT_ROUTE,
|
|
283
|
+
},
|
|
284
|
+
policy: {
|
|
285
|
+
effect: 'confirmed-setup-checkpoint-clear',
|
|
286
|
+
boundary: 'Removed only the Agent-owned setup wizard checkpoint file.',
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export function provisionConnectedHostOperatorToken(context: CommandContext, args: AgentHarnessSetupArgs): Record<string, unknown> {
|
|
292
|
+
const setupItemId = readString(args.setupItemId);
|
|
293
|
+
if (setupItemId && setupItemId !== 'connected-host-auth') {
|
|
294
|
+
return {
|
|
295
|
+
status: 'unsupported_setup_item',
|
|
296
|
+
usage: 'provision_connected_host_token supports setupItemId:"connected-host-auth" only.',
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const shellPaths = requireShellPaths(context);
|
|
301
|
+
const before = readConnectedHostOperatorToken(shellPaths.homeDirectory);
|
|
302
|
+
const explicitUserRequest = readString(args.explicitUserRequest);
|
|
303
|
+
const beforeFingerprint = before.token ? connectedHostOperatorTokenFingerprint(before.token) : null;
|
|
304
|
+
if (before.token && before.path.startsWith('env:')) {
|
|
305
|
+
return {
|
|
306
|
+
status: 'already_usable_env_token',
|
|
307
|
+
mode: 'provision_connected_host_token',
|
|
308
|
+
setupItemId: 'connected-host-auth',
|
|
309
|
+
explicitUserRequest: previewHarnessText(explicitUserRequest, 160),
|
|
310
|
+
token: {
|
|
311
|
+
path: before.path,
|
|
312
|
+
present: true,
|
|
313
|
+
usable: true,
|
|
314
|
+
fingerprint: beforeFingerprint,
|
|
315
|
+
rawValueReturned: false,
|
|
316
|
+
},
|
|
317
|
+
mutation: {
|
|
318
|
+
performed: false,
|
|
319
|
+
reason: 'Environment-provided connected-host token is already effective; no local token file was written.',
|
|
320
|
+
},
|
|
321
|
+
routes: {
|
|
322
|
+
inspectAuth: 'setup action:"item" setupItemId:"connected-host-auth"',
|
|
323
|
+
inspectStatus: 'host action:"status" includeParameters:true',
|
|
324
|
+
pairingPosture: 'agent_harness mode:"pairing_posture" includeParameters:true',
|
|
325
|
+
},
|
|
326
|
+
policy: {
|
|
327
|
+
effect: 'confirmed-local-token-provisioning',
|
|
328
|
+
secrets: 'Raw connected-host tokens are never returned.',
|
|
329
|
+
boundary: 'Environment-provided tokens take precedence and are not modified by this route.',
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const daemonHomeDir = join(shellPaths.homeDirectory, '.goodvibes', 'daemon');
|
|
335
|
+
const canonicalPath = connectedHostOperatorTokenPath(shellPaths.homeDirectory);
|
|
336
|
+
try {
|
|
337
|
+
const record = getOrCreateCompanionToken(GOODVIBES_AGENT_PAIRING_SURFACE, { daemonHomeDir });
|
|
338
|
+
const after = readConnectedHostOperatorToken(shellPaths.homeDirectory);
|
|
339
|
+
if (!after.token) {
|
|
340
|
+
return {
|
|
341
|
+
status: 'failed',
|
|
342
|
+
mode: 'provision_connected_host_token',
|
|
343
|
+
setupItemId: 'connected-host-auth',
|
|
344
|
+
explicitUserRequest: previewHarnessText(explicitUserRequest, 160),
|
|
345
|
+
error: after.error ? previewHarnessText(after.error, 160) : 'SDK token provisioning completed but no usable connected-host token was readable.',
|
|
346
|
+
token: {
|
|
347
|
+
path: after.path,
|
|
348
|
+
present: after.present,
|
|
349
|
+
usable: false,
|
|
350
|
+
rawValueReturned: false,
|
|
351
|
+
},
|
|
352
|
+
routes: {
|
|
353
|
+
inspectAuth: 'setup action:"item" setupItemId:"connected-host-auth"',
|
|
354
|
+
inspectStatus: 'host action:"status" includeParameters:true',
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
const afterFingerprint = connectedHostOperatorTokenFingerprint(after.token);
|
|
359
|
+
const changed = beforeFingerprint !== afterFingerprint;
|
|
360
|
+
const result = before.token
|
|
361
|
+
? changed ? 'repaired' : 'already_usable'
|
|
362
|
+
: before.present ? 'repaired' : 'created';
|
|
363
|
+
return {
|
|
364
|
+
status: result,
|
|
365
|
+
mode: 'provision_connected_host_token',
|
|
366
|
+
setupItemId: 'connected-host-auth',
|
|
367
|
+
explicitUserRequest: previewHarnessText(explicitUserRequest, 160),
|
|
368
|
+
token: {
|
|
369
|
+
path: after.path,
|
|
370
|
+
canonicalPath,
|
|
371
|
+
present: true,
|
|
372
|
+
usable: true,
|
|
373
|
+
fingerprint: afterFingerprint,
|
|
374
|
+
rawValueReturned: false,
|
|
375
|
+
fileMode: safeFileMode(canonicalPath),
|
|
376
|
+
},
|
|
377
|
+
companionRecord: {
|
|
378
|
+
surface: GOODVIBES_AGENT_PAIRING_SURFACE,
|
|
379
|
+
peerId: record.peerId,
|
|
380
|
+
createdAt: safeIso(record.createdAt),
|
|
381
|
+
},
|
|
382
|
+
mutation: {
|
|
383
|
+
performed: result === 'created' || result === 'repaired',
|
|
384
|
+
result,
|
|
385
|
+
existingTokenPreserved: result === 'already_usable',
|
|
386
|
+
source: 'getOrCreateCompanionToken',
|
|
387
|
+
},
|
|
388
|
+
routes: {
|
|
389
|
+
inspectAuth: 'setup action:"item" setupItemId:"connected-host-auth"',
|
|
390
|
+
inspectStatus: 'host action:"status" includeParameters:true',
|
|
391
|
+
pairingPosture: 'agent_harness mode:"pairing_posture" includeParameters:true',
|
|
392
|
+
runSetupSmoke: DEFAULT_AGENT_SETUP_WIZARD_RERUN_SMOKE_ROUTE,
|
|
393
|
+
},
|
|
394
|
+
policy: {
|
|
395
|
+
effect: 'confirmed-local-token-provisioning',
|
|
396
|
+
source: 'SDK platform pairing helper writes the canonical connected-host operator token file with owner-only permissions.',
|
|
397
|
+
secrets: 'Only path, fingerprint, peer id, and timestamps are returned; the raw token is not returned.',
|
|
398
|
+
rotation: 'This route preserves a valid existing token and only creates or repairs the local canonical file.',
|
|
399
|
+
},
|
|
400
|
+
};
|
|
401
|
+
} catch (error) {
|
|
402
|
+
return {
|
|
403
|
+
status: 'failed',
|
|
404
|
+
mode: 'provision_connected_host_token',
|
|
405
|
+
setupItemId: 'connected-host-auth',
|
|
406
|
+
explicitUserRequest: previewHarnessText(explicitUserRequest, 160),
|
|
407
|
+
error: previewHarnessText(error instanceof Error ? error.message : String(error), 160),
|
|
408
|
+
token: {
|
|
409
|
+
path: canonicalPath,
|
|
410
|
+
present: before.present,
|
|
411
|
+
usable: false,
|
|
412
|
+
rawValueReturned: false,
|
|
413
|
+
},
|
|
414
|
+
routes: {
|
|
415
|
+
inspectAuth: 'setup action:"item" setupItemId:"connected-host-auth"',
|
|
416
|
+
inspectStatus: 'host action:"status" includeParameters:true',
|
|
417
|
+
},
|
|
418
|
+
policy: {
|
|
419
|
+
effect: 'confirmed-local-token-provisioning',
|
|
420
|
+
secrets: 'Raw connected-host tokens are never returned.',
|
|
421
|
+
},
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
export async function runSetupInstallSmoke(context: CommandContext, args: AgentHarnessSetupArgs): Promise<Record<string, unknown>> {
|
|
427
|
+
const setupItemId = readString(args.setupItemId);
|
|
428
|
+
if (setupItemId && setupItemId !== 'install-smoke') {
|
|
429
|
+
return {
|
|
430
|
+
status: 'unsupported_setup_item',
|
|
431
|
+
usage: 'run_setup_smoke currently supports setupItemId:"install-smoke" only.',
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const snapshot = await collectSnapshot(context);
|
|
436
|
+
const servicePosture = await collectServicePosture(context);
|
|
437
|
+
const plan = buildSetupPlan(context, snapshot, deriveStep1Capabilities(snapshot), servicePosture);
|
|
438
|
+
const installSmoke = plan.find((item) => item.id === 'install-smoke');
|
|
439
|
+
const smokePlan = installSmoke?.installSmokePlan;
|
|
440
|
+
if (!smokePlan) {
|
|
441
|
+
return {
|
|
442
|
+
status: 'missing_smoke_plan',
|
|
443
|
+
usage: 'Install smoke plan is not available. Inspect mode:"setup_posture" for setup readiness.',
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const includeParameters = args.includeParameters === true;
|
|
448
|
+
const summary = installSmokeRunSummary(smokePlan);
|
|
449
|
+
const blockedChecks = smokePlan.checks.filter((check) => check.status === 'blocked').map((check) => check.id);
|
|
450
|
+
const userRunChecks = smokePlan.checks.filter((check) => check.status === 'user-run').map((check) => check.id);
|
|
451
|
+
const capturedAt = new Date(snapshot.capturedAt).toISOString();
|
|
452
|
+
const explicitUserRequest = readString(args.explicitUserRequest);
|
|
453
|
+
const evidenceFields = setupSmokeEvidenceFields(args.fields);
|
|
454
|
+
const artifact = await saveSetupSmokeArtifact({
|
|
455
|
+
context,
|
|
456
|
+
capturedAt,
|
|
457
|
+
explicitUserRequest,
|
|
458
|
+
smokePlan,
|
|
459
|
+
summary,
|
|
460
|
+
blockedChecks,
|
|
461
|
+
userRunChecks,
|
|
462
|
+
evidenceFields,
|
|
463
|
+
});
|
|
464
|
+
return {
|
|
465
|
+
status: 'executed',
|
|
466
|
+
mode: 'run_setup_smoke',
|
|
467
|
+
setupItemId: 'install-smoke',
|
|
468
|
+
capturedAt,
|
|
469
|
+
smokeStatus: smokePlan.status,
|
|
470
|
+
result: installSmokeRunResult(smokePlan),
|
|
471
|
+
explicitUserRequest: previewHarnessText(explicitUserRequest, 160),
|
|
472
|
+
summary,
|
|
473
|
+
blockedChecks,
|
|
474
|
+
userRunChecks,
|
|
475
|
+
checks: smokePlan.checks.map((check) => describeInstallSmokeCheck(check, includeParameters)),
|
|
476
|
+
artifact,
|
|
477
|
+
successCriteria: includeParameters ? smokePlan.successCriteria : smokePlan.successCriteria.map((entry) => previewHarnessText(entry, 120)),
|
|
478
|
+
nextAction: installSmokeNextAction(smokePlan),
|
|
479
|
+
routes: {
|
|
480
|
+
inspectSetup: DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
481
|
+
inspectSmoke: 'setup action:"item" setupItemId:"install-smoke"',
|
|
482
|
+
rerunSmoke: DEFAULT_AGENT_SETUP_WIZARD_RERUN_SMOKE_ROUTE,
|
|
483
|
+
saveEvidence: DEFAULT_AGENT_SETUP_WIZARD_SAVE_SMOKE_ROUTE,
|
|
484
|
+
},
|
|
485
|
+
policy: {
|
|
486
|
+
effect: 'confirmed-redacted-setup-smoke',
|
|
487
|
+
shell: 'No package, host, or shell commands were executed implicitly.',
|
|
488
|
+
secrets: 'Secrets and connected-host tokens are never returned; token evidence remains presence, path, and fingerprint only.',
|
|
489
|
+
source: smokePlan.policy,
|
|
490
|
+
},
|
|
491
|
+
source: smokePlan.source,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
|
|
278
495
|
export async function describeHarnessSetupItem(context: CommandContext, args: AgentHarnessSetupArgs): Promise<SetupResolution> {
|
|
279
496
|
const lookup = lookupFromArgs(args);
|
|
280
497
|
if (!lookup) {
|
|
@@ -284,19 +501,30 @@ export async function describeHarnessSetupItem(context: CommandContext, args: Ag
|
|
|
284
501
|
};
|
|
285
502
|
}
|
|
286
503
|
const snapshot = await collectSnapshot(context);
|
|
504
|
+
const servicePosture = await collectServicePosture(context);
|
|
287
505
|
const items = deriveStep1Capabilities(snapshot);
|
|
506
|
+
const plan = buildSetupPlan(context, snapshot, items, servicePosture);
|
|
288
507
|
const normalized = lookup.input.toLowerCase();
|
|
289
508
|
const exact = items.find((item) => item.id === lookup.input);
|
|
290
509
|
if (exact) return { status: 'found', item: describeItem(exact, snapshot, { includeParameters: true, lookup: { ...lookup, resolvedBy: 'id' } }) };
|
|
510
|
+
const exactPlan = plan.find((item) => item.id === lookup.input);
|
|
511
|
+
if (exactPlan) return { status: 'found', item: { ...describePlanItem(exactPlan, true), lookup: { ...lookup, resolvedBy: 'plan-id' } } };
|
|
291
512
|
const insensitive = items.find((item) => item.id.toLowerCase() === normalized);
|
|
292
513
|
if (insensitive) return { status: 'found', item: describeItem(insensitive, snapshot, { includeParameters: true, lookup: { ...lookup, resolvedBy: 'case-insensitive-id' } }) };
|
|
514
|
+
const insensitivePlan = plan.find((item) => item.id.toLowerCase() === normalized);
|
|
515
|
+
if (insensitivePlan) return { status: 'found', item: { ...describePlanItem(insensitivePlan, true), lookup: { ...lookup, resolvedBy: 'case-insensitive-plan-id' } } };
|
|
293
516
|
const searched = items.filter((item) => itemSearchText(item).includes(normalized));
|
|
294
|
-
|
|
295
|
-
if (searched.length
|
|
517
|
+
const searchedPlan = plan.filter((item) => planSearchText(item).includes(normalized));
|
|
518
|
+
if (searched.length === 1 && searchedPlan.length === 0) return { status: 'found', item: describeItem(searched[0]!, snapshot, { includeParameters: true, lookup: { ...lookup, resolvedBy: 'search' } }) };
|
|
519
|
+
if (searched.length === 0 && searchedPlan.length === 1) return { status: 'found', item: { ...describePlanItem(searchedPlan[0]!, true), lookup: { ...lookup, resolvedBy: 'plan-search' } } };
|
|
520
|
+
if (searched.length > 0 || searchedPlan.length > 0) {
|
|
296
521
|
return {
|
|
297
522
|
status: 'ambiguous',
|
|
298
523
|
input: lookup.input,
|
|
299
|
-
candidates:
|
|
524
|
+
candidates: [
|
|
525
|
+
...searched.map(describeCandidate),
|
|
526
|
+
...searchedPlan.map((item) => describePlanItem(item, false)),
|
|
527
|
+
].slice(0, 8),
|
|
300
528
|
};
|
|
301
529
|
}
|
|
302
530
|
return {
|