@pellux/goodvibes-agent 1.1.5 → 1.1.6
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
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Product-facing release notes for GoodVibes Agent.
|
|
4
4
|
|
|
5
|
+
## 1.1.6 - 2026-06-05
|
|
6
|
+
|
|
7
|
+
- Fixed Import GoodVibes settings so it also imports active and pending provider subscriptions from the GoodVibes TUI user store into Agent-owned subscription state.
|
|
8
|
+
- Preserved existing Agent-only subscriptions while merging imported provider sessions by provider id.
|
|
9
|
+
- Updated onboarding copy and added regression coverage for subscription import.
|
|
10
|
+
|
|
5
11
|
## 1.1.5 - 2026-06-05
|
|
6
12
|
|
|
7
13
|
- Replaced onboarding with the real Agent setup flow for subscription login, provider/model selection, settings persistence, channels, voice, local context, automation, and finish.
|
package/dist/package/main.js
CHANGED
|
@@ -450372,6 +450372,23 @@ function createSchema2(db) {
|
|
|
450372
450372
|
`);
|
|
450373
450373
|
db.run(`CREATE INDEX IF NOT EXISTS idx_knowledge_schedules_job_id ON knowledge_schedules(job_id)`);
|
|
450374
450374
|
}
|
|
450375
|
+
function getKnowledgeSchemaStatements() {
|
|
450376
|
+
const statements = [];
|
|
450377
|
+
createSchema2({
|
|
450378
|
+
run(sql) {
|
|
450379
|
+
const normalized = sql.trim();
|
|
450380
|
+
if (normalized.length > 0)
|
|
450381
|
+
statements.push(normalized);
|
|
450382
|
+
}
|
|
450383
|
+
});
|
|
450384
|
+
return statements;
|
|
450385
|
+
}
|
|
450386
|
+
function renderKnowledgeSchemaSql() {
|
|
450387
|
+
return `${getKnowledgeSchemaStatements().map((statement) => statement.endsWith(";") ? statement : `${statement};`).join(`
|
|
450388
|
+
|
|
450389
|
+
`)}
|
|
450390
|
+
`;
|
|
450391
|
+
}
|
|
450375
450392
|
function rowObject(columns, values2) {
|
|
450376
450393
|
return Object.fromEntries(columns.map((column, index) => [column, values2[index]]));
|
|
450377
450394
|
}
|
|
@@ -763654,6 +763671,9 @@ var init_ingest = __esm(() => {
|
|
|
763654
763671
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/browser-history/index.js
|
|
763655
763672
|
var init_browser_history = __esm(() => {
|
|
763656
763673
|
init_ingest();
|
|
763674
|
+
init_discover();
|
|
763675
|
+
init_readers();
|
|
763676
|
+
init_paths2();
|
|
763657
763677
|
});
|
|
763658
763678
|
|
|
763659
763679
|
// node_modules/graphql/jsutils/devAssert.mjs
|
|
@@ -781293,6 +781313,7 @@ var init_semantic = __esm(() => {
|
|
|
781293
781313
|
init_llm();
|
|
781294
781314
|
init_gap_repair();
|
|
781295
781315
|
init_service4();
|
|
781316
|
+
init_self_improvement();
|
|
781296
781317
|
});
|
|
781297
781318
|
|
|
781298
781319
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/helpers.js
|
|
@@ -785261,8 +785282,40 @@ var init_map_view = __esm(() => {
|
|
|
785261
785282
|
});
|
|
785262
785283
|
|
|
785263
785284
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/types.js
|
|
785264
|
-
var HOME_GRAPH_CAPABILITIES;
|
|
785285
|
+
var HOME_GRAPH_NODE_KINDS, HOME_GRAPH_RELATIONS, HOME_GRAPH_CAPABILITIES;
|
|
785265
785286
|
var init_types15 = __esm(() => {
|
|
785287
|
+
HOME_GRAPH_NODE_KINDS = [
|
|
785288
|
+
"ha_home",
|
|
785289
|
+
"ha_entity",
|
|
785290
|
+
"ha_device",
|
|
785291
|
+
"ha_area",
|
|
785292
|
+
"ha_automation",
|
|
785293
|
+
"ha_script",
|
|
785294
|
+
"ha_scene",
|
|
785295
|
+
"ha_label",
|
|
785296
|
+
"ha_integration",
|
|
785297
|
+
"ha_room",
|
|
785298
|
+
"ha_device_passport",
|
|
785299
|
+
"ha_maintenance_item",
|
|
785300
|
+
"ha_troubleshooting_case",
|
|
785301
|
+
"ha_purchase",
|
|
785302
|
+
"ha_network_node"
|
|
785303
|
+
];
|
|
785304
|
+
HOME_GRAPH_RELATIONS = [
|
|
785305
|
+
"controls",
|
|
785306
|
+
"located_in",
|
|
785307
|
+
"belongs_to_device",
|
|
785308
|
+
"has_manual",
|
|
785309
|
+
"has_receipt",
|
|
785310
|
+
"has_warranty",
|
|
785311
|
+
"has_issue",
|
|
785312
|
+
"fixed_by",
|
|
785313
|
+
"uses_battery",
|
|
785314
|
+
"connected_via",
|
|
785315
|
+
"part_of_network",
|
|
785316
|
+
"mentioned_by",
|
|
785317
|
+
"source_for"
|
|
785318
|
+
];
|
|
785266
785319
|
HOME_GRAPH_CAPABILITIES = [
|
|
785267
785320
|
"knowledge-space-isolation",
|
|
785268
785321
|
"snapshot-sync",
|
|
@@ -786669,6 +786722,7 @@ var init_service5 = __esm(() => {
|
|
|
786669
786722
|
var init_home_graph = __esm(() => {
|
|
786670
786723
|
init_service5();
|
|
786671
786724
|
init_extension();
|
|
786725
|
+
init_types15();
|
|
786672
786726
|
});
|
|
786673
786727
|
|
|
786674
786728
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/store-refinement.js
|
|
@@ -788996,10 +789050,14 @@ var init_service6 = __esm(() => {
|
|
|
788996
789050
|
var init_project_planning = __esm(() => {
|
|
788997
789051
|
init_service6();
|
|
788998
789052
|
init_helpers3();
|
|
789053
|
+
init_readiness();
|
|
788999
789054
|
});
|
|
789000
789055
|
|
|
789001
789056
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/persistence.js
|
|
789002
|
-
var init_persistence = () => {
|
|
789057
|
+
var init_persistence = __esm(() => {
|
|
789058
|
+
init_store_schema();
|
|
789059
|
+
init_store_load();
|
|
789060
|
+
});
|
|
789003
789061
|
|
|
789004
789062
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/projections.js
|
|
789005
789063
|
class KnowledgeProjectionService {
|
|
@@ -792507,21 +792565,21 @@ var init_service7 = __esm(() => {
|
|
|
792507
792565
|
var exports_knowledge = {};
|
|
792508
792566
|
__export(exports_knowledge, {
|
|
792509
792567
|
withKnowledgeSpace: () => withKnowledgeSpace,
|
|
792510
|
-
uniqKnowledgeValues: () =>
|
|
792511
|
-
stabilizeKnowledgeText: () =>
|
|
792512
|
-
runKnowledgeSemanticSelfImprovement: () =>
|
|
792568
|
+
uniqKnowledgeValues: () => uniq2,
|
|
792569
|
+
stabilizeKnowledgeText: () => stableText,
|
|
792570
|
+
runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement,
|
|
792513
792571
|
resolveProjectPlanningSpace: () => resolveProjectPlanningSpace,
|
|
792514
|
-
resolveKnowledgeDbPathFromControlPlaneDir: () =>
|
|
792572
|
+
resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir,
|
|
792515
792573
|
renderPacket: () => renderPacket,
|
|
792516
792574
|
renderKnowledgeSchemaSql: () => renderKnowledgeSchemaSql,
|
|
792517
792575
|
renderKnowledgeMap: () => renderKnowledgeMap,
|
|
792518
792576
|
readKnowledgeSearchText: () => readKnowledgeSearchText,
|
|
792519
|
-
readBrowserKnowledgeProfile: () =>
|
|
792577
|
+
readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile,
|
|
792520
792578
|
projectPlanningSourceId: () => projectPlanningSourceId,
|
|
792521
792579
|
projectPlanningProjectIdFromPath: () => projectPlanningProjectIdFromPath,
|
|
792522
792580
|
projectPlanningCanonicalUri: () => projectPlanningCanonicalUri,
|
|
792523
792581
|
projectKnowledgeSpaceId: () => projectKnowledgeSpaceId,
|
|
792524
|
-
parseKnowledgeJsonValue: () =>
|
|
792582
|
+
parseKnowledgeJsonValue: () => parseJsonValue,
|
|
792525
792583
|
normalizeProjectId: () => normalizeProjectId,
|
|
792526
792584
|
normalizeKnowledgeSpaceId: () => normalizeKnowledgeSpaceId,
|
|
792527
792585
|
normalizeHomeAssistantInstallationId: () => normalizeHomeAssistantInstallationId,
|
|
@@ -792529,12 +792587,12 @@ __export(exports_knowledge, {
|
|
|
792529
792587
|
materializeGeneratedKnowledgeProjection: () => materializeGeneratedKnowledgeProjection,
|
|
792530
792588
|
looksLikeRawPdfPayload: () => looksLikeRawPdfPayload,
|
|
792531
792589
|
looksBinaryLikeText: () => looksBinaryLikeText,
|
|
792532
|
-
loadKnowledgeStoreSnapshot: () =>
|
|
792590
|
+
loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot,
|
|
792533
792591
|
listGeneratedKnowledgePages: () => listGeneratedKnowledgePages,
|
|
792534
|
-
listBrowserKinds: () =>
|
|
792592
|
+
listBrowserKinds: () => listBrowserKinds,
|
|
792535
792593
|
knowledgeSpaceMetadata: () => knowledgeSpaceMetadata,
|
|
792536
792594
|
knowledgePageSourceWeight: () => knowledgePageSourceWeight,
|
|
792537
|
-
knowledgeNowMs: () =>
|
|
792595
|
+
knowledgeNowMs: () => nowMs,
|
|
792538
792596
|
knowledgeExtractionNeedsRefresh: () => knowledgeExtractionNeedsRefresh,
|
|
792539
792597
|
isUsefulKnowledgePageSourceCandidate: () => isUsefulKnowledgePageSourceCandidate,
|
|
792540
792598
|
isUsefulKnowledgePageSource: () => isUsefulKnowledgePageSource,
|
|
@@ -792554,12 +792612,12 @@ __export(exports_knowledge, {
|
|
|
792554
792612
|
generatedKnowledgeSourceId: () => generatedKnowledgeSourceId,
|
|
792555
792613
|
generatedKnowledgeCanonicalUri: () => generatedKnowledgeCanonicalUri,
|
|
792556
792614
|
extractKnowledgeArtifact: () => extractKnowledgeArtifact,
|
|
792557
|
-
evaluateProjectPlanningReadiness: () =>
|
|
792558
|
-
discoverBrowserKnowledgeProfiles: () =>
|
|
792615
|
+
evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness,
|
|
792616
|
+
discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles,
|
|
792559
792617
|
createWebKnowledgeGapRepairer: () => createWebKnowledgeGapRepairer,
|
|
792560
792618
|
createProviderBackedKnowledgeSemanticLlm: () => createProviderBackedKnowledgeSemanticLlm,
|
|
792561
792619
|
createMemoryApi: () => createMemoryApi,
|
|
792562
|
-
createKnowledgeSchema: () =>
|
|
792620
|
+
createKnowledgeSchema: () => createSchema2,
|
|
792563
792621
|
createKnowledgeApi: () => createKnowledgeApi,
|
|
792564
792622
|
createDefaultKnowledgeConnectorRegistry: () => createDefaultKnowledgeConnectorRegistry,
|
|
792565
792623
|
compareKnowledgePageSources: () => compareKnowledgePageSources,
|
|
@@ -794998,7 +795056,7 @@ var init_delivery_manager = __esm(() => {
|
|
|
794998
795056
|
});
|
|
794999
795057
|
|
|
795000
795058
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/automation/scheduler-capacity.js
|
|
795001
|
-
function computeSchedulerCapacity(slotsTotal, runs,
|
|
795059
|
+
function computeSchedulerCapacity(slotsTotal, runs, nowMs2 = Date.now()) {
|
|
795002
795060
|
let slotsInUse = 0;
|
|
795003
795061
|
const queuedRuns = [];
|
|
795004
795062
|
for (const run7 of runs) {
|
|
@@ -795008,7 +795066,7 @@ function computeSchedulerCapacity(slotsTotal, runs, nowMs3 = Date.now()) {
|
|
|
795008
795066
|
queuedRuns.push(run7);
|
|
795009
795067
|
}
|
|
795010
795068
|
const queueDepth = queuedRuns.length;
|
|
795011
|
-
const oldestQueuedAgeMs = queueDepth > 0 ?
|
|
795069
|
+
const oldestQueuedAgeMs = queueDepth > 0 ? nowMs2 - Math.min(...queuedRuns.map((r6) => r6.queuedAt)) : null;
|
|
795012
795070
|
return { slotsTotal, slotsInUse, queueDepth, oldestQueuedAgeMs };
|
|
795013
795071
|
}
|
|
795014
795072
|
|
|
@@ -817034,7 +817092,7 @@ var createStyledCell = (char, overrides = {}) => ({
|
|
|
817034
817092
|
// src/version.ts
|
|
817035
817093
|
import { readFileSync } from "fs";
|
|
817036
817094
|
import { join } from "path";
|
|
817037
|
-
var _version = "1.1.
|
|
817095
|
+
var _version = "1.1.6";
|
|
817038
817096
|
try {
|
|
817039
817097
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
|
|
817040
817098
|
_version = typeof pkg.version === "string" ? pkg.version : _version;
|
|
@@ -839547,7 +839605,7 @@ var WORK_PLAN_STATUSES = [
|
|
|
839547
839605
|
"failed",
|
|
839548
839606
|
"cancelled"
|
|
839549
839607
|
];
|
|
839550
|
-
function
|
|
839608
|
+
function nowMs2() {
|
|
839551
839609
|
return Date.now();
|
|
839552
839610
|
}
|
|
839553
839611
|
function isObject4(value) {
|
|
@@ -839653,7 +839711,7 @@ class WorkPlanStore {
|
|
|
839653
839711
|
if (!normalizedTitle)
|
|
839654
839712
|
throw new Error("Work plan item title is required.");
|
|
839655
839713
|
const plan = this.readPlan();
|
|
839656
|
-
const time4 =
|
|
839714
|
+
const time4 = nowMs2();
|
|
839657
839715
|
const item = {
|
|
839658
839716
|
id: createItemId(),
|
|
839659
839717
|
title: normalizedTitle,
|
|
@@ -839677,7 +839735,7 @@ class WorkPlanStore {
|
|
|
839677
839735
|
updateItem(idOrPrefix, patch2) {
|
|
839678
839736
|
const plan = this.readPlan();
|
|
839679
839737
|
const item = this.resolveItem(plan, idOrPrefix);
|
|
839680
|
-
const time4 =
|
|
839738
|
+
const time4 = nowMs2();
|
|
839681
839739
|
const nextStatus = patch2.status ?? item.status;
|
|
839682
839740
|
const next = this.pruneItem({
|
|
839683
839741
|
...item,
|
|
@@ -839710,7 +839768,7 @@ class WorkPlanStore {
|
|
|
839710
839768
|
removeItem(idOrPrefix) {
|
|
839711
839769
|
const plan = this.readPlan();
|
|
839712
839770
|
const item = this.resolveItem(plan, idOrPrefix);
|
|
839713
|
-
const time4 =
|
|
839771
|
+
const time4 = nowMs2();
|
|
839714
839772
|
const remaining = plan.items.filter((candidate) => candidate.id !== item.id);
|
|
839715
839773
|
this.writePlan({
|
|
839716
839774
|
...plan,
|
|
@@ -839730,7 +839788,7 @@ class WorkPlanStore {
|
|
|
839730
839788
|
...plan,
|
|
839731
839789
|
items: remaining,
|
|
839732
839790
|
activeItemId: remaining[0]?.id,
|
|
839733
|
-
updatedAt:
|
|
839791
|
+
updatedAt: nowMs2()
|
|
839734
839792
|
});
|
|
839735
839793
|
return removed;
|
|
839736
839794
|
}
|
|
@@ -839769,7 +839827,7 @@ class WorkPlanStore {
|
|
|
839769
839827
|
const parsed = JSON.parse(raw);
|
|
839770
839828
|
if (!isObject4(parsed))
|
|
839771
839829
|
return this.createEmptyPlan();
|
|
839772
|
-
const time4 =
|
|
839830
|
+
const time4 = nowMs2();
|
|
839773
839831
|
const createdAt = typeof parsed.createdAt === "number" ? parsed.createdAt : time4;
|
|
839774
839832
|
const updatedAt = typeof parsed.updatedAt === "number" ? parsed.updatedAt : createdAt;
|
|
839775
839833
|
const items = Array.isArray(parsed.items) ? parsed.items.map((item) => normalizeItem(item, createdAt)).filter((item) => item !== null) : [];
|
|
@@ -839788,7 +839846,7 @@ class WorkPlanStore {
|
|
|
839788
839846
|
};
|
|
839789
839847
|
}
|
|
839790
839848
|
createEmptyPlan() {
|
|
839791
|
-
const time4 =
|
|
839849
|
+
const time4 = nowMs2();
|
|
839792
839850
|
return {
|
|
839793
839851
|
id: createPlanId(this.options.projectId, this.options.projectRoot),
|
|
839794
839852
|
projectId: this.options.projectId,
|
|
@@ -890625,7 +890683,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890625
890683
|
summary: "Import preferences, sign in, and choose the main model.",
|
|
890626
890684
|
detail: "Start here on a fresh install. Every row either saves state, opens the shared model picker, or opens a confirmed in-modal form.",
|
|
890627
890685
|
actions: [
|
|
890628
|
-
{ id: "import-goodvibes-tui-settings", label: "Import GoodVibes settings", detail: "Copy existing display, provider, behavior, permission, TTS, channel, helper, tool, release, and automation values into Agent-owned
|
|
890686
|
+
{ id: "import-goodvibes-tui-settings", label: "Import GoodVibes settings", detail: "Copy existing display, provider, subscription, behavior, permission, TTS, channel, helper, tool, release, and automation values into Agent-owned state.", kind: "settings-import", safety: "safe" },
|
|
890629
890687
|
{ id: "subscription-login-start", label: "Start subscription login", detail: "Start one provider sign-in flow, save pending state, and return here.", editorKind: "subscription-login-start", kind: "editor", safety: "safe" },
|
|
890630
890688
|
{ id: "subscription-login-finish", label: "Finish subscription login", detail: "Exchange a code or redirect URL and save the provider subscription session.", editorKind: "subscription-login-finish", kind: "editor", safety: "safe" },
|
|
890631
890689
|
{ id: "setup-provider-model", label: "Choose main model", detail: "Open the shared provider/model picker for normal assistant turns.", kind: "model-picker", modelPickerFlow: "providerModel", modelPickerTarget: "main", safety: "safe" },
|
|
@@ -896068,6 +896126,62 @@ function canImportTuiSetting(key) {
|
|
|
896068
896126
|
function valuesMatch(left, right) {
|
|
896069
896127
|
return JSON.stringify(left) === JSON.stringify(right);
|
|
896070
896128
|
}
|
|
896129
|
+
function readRecordMap(record2, key) {
|
|
896130
|
+
const value = record2[key];
|
|
896131
|
+
return isRecord45(value) ? Object.values(value) : [];
|
|
896132
|
+
}
|
|
896133
|
+
function isProviderSubscription(value) {
|
|
896134
|
+
return isRecord45(value) && typeof value.provider === "string" && typeof value.accessToken === "string" && typeof value.tokenType === "string" && value.authMode === "oauth" && typeof value.overrideAmbientApiKeys === "boolean" && typeof value.createdAt === "number" && typeof value.updatedAt === "number";
|
|
896135
|
+
}
|
|
896136
|
+
function isPendingSubscriptionLogin(value) {
|
|
896137
|
+
return isRecord45(value) && typeof value.provider === "string" && typeof value.state === "string" && typeof value.verifier === "string" && typeof value.redirectUri === "string" && typeof value.createdAt === "number";
|
|
896138
|
+
}
|
|
896139
|
+
function importTuiSubscriptions(context, parseErrors) {
|
|
896140
|
+
const shellPaths3 = context.workspace.shellPaths;
|
|
896141
|
+
const manager5 = context.platform.subscriptionManager;
|
|
896142
|
+
const result2 = {
|
|
896143
|
+
importedActive: [],
|
|
896144
|
+
importedPending: [],
|
|
896145
|
+
unchangedActive: [],
|
|
896146
|
+
unchangedPending: [],
|
|
896147
|
+
skipped: []
|
|
896148
|
+
};
|
|
896149
|
+
if (!shellPaths3 || !manager5)
|
|
896150
|
+
return result2;
|
|
896151
|
+
const sourcePath = shellPaths3.resolveUserPath(GOODVIBES_TUI_SURFACE_ROOT, "subscriptions.json");
|
|
896152
|
+
try {
|
|
896153
|
+
const store2 = readJsonRecord(sourcePath);
|
|
896154
|
+
if (!store2)
|
|
896155
|
+
return result2;
|
|
896156
|
+
for (const entry of readRecordMap(store2, "subscriptions")) {
|
|
896157
|
+
if (!isProviderSubscription(entry)) {
|
|
896158
|
+
result2.skipped.push("active subscription with invalid shape");
|
|
896159
|
+
continue;
|
|
896160
|
+
}
|
|
896161
|
+
if (valuesMatch(manager5.get(entry.provider), entry)) {
|
|
896162
|
+
result2.unchangedActive.push(entry.provider);
|
|
896163
|
+
continue;
|
|
896164
|
+
}
|
|
896165
|
+
manager5.saveSubscription(entry);
|
|
896166
|
+
result2.importedActive.push(entry.provider);
|
|
896167
|
+
}
|
|
896168
|
+
for (const entry of readRecordMap(store2, "pending")) {
|
|
896169
|
+
if (!isPendingSubscriptionLogin(entry)) {
|
|
896170
|
+
result2.skipped.push("pending subscription with invalid shape");
|
|
896171
|
+
continue;
|
|
896172
|
+
}
|
|
896173
|
+
if (valuesMatch(manager5.getPending(entry.provider), entry)) {
|
|
896174
|
+
result2.unchangedPending.push(entry.provider);
|
|
896175
|
+
continue;
|
|
896176
|
+
}
|
|
896177
|
+
manager5.savePending(entry);
|
|
896178
|
+
result2.importedPending.push(entry.provider);
|
|
896179
|
+
}
|
|
896180
|
+
} catch (error53) {
|
|
896181
|
+
parseErrors.push(`subscriptions: ${error53 instanceof Error ? error53.message : String(error53)}`);
|
|
896182
|
+
}
|
|
896183
|
+
return result2;
|
|
896184
|
+
}
|
|
896071
896185
|
function agentWorkspaceSettingSchema(context, key) {
|
|
896072
896186
|
return context?.platform?.configManager?.getSchema().find((setting) => setting.key === key) ?? null;
|
|
896073
896187
|
}
|
|
@@ -896171,7 +896285,7 @@ async function applyAgentWorkspaceSettingValue(context, setting, value) {
|
|
|
896171
896285
|
async function importAgentWorkspaceTuiSettings(context) {
|
|
896172
896286
|
const shellPaths3 = context?.workspace?.shellPaths;
|
|
896173
896287
|
const configManager = context?.platform?.configManager;
|
|
896174
|
-
if (!shellPaths3 || !configManager) {
|
|
896288
|
+
if (!context || !shellPaths3 || !configManager) {
|
|
896175
896289
|
return {
|
|
896176
896290
|
status: "GoodVibes TUI settings import is unavailable in this runtime.",
|
|
896177
896291
|
runtimeSnapshot: null,
|
|
@@ -896205,8 +896319,11 @@ async function importAgentWorkspaceTuiSettings(context) {
|
|
|
896205
896319
|
parseErrors.push(`${source.label}: ${error53 instanceof Error ? error53.message : String(error53)}`);
|
|
896206
896320
|
}
|
|
896207
896321
|
}
|
|
896208
|
-
|
|
896209
|
-
|
|
896322
|
+
const subscriptions = importTuiSubscriptions(context, parseErrors);
|
|
896323
|
+
const subscriptionImports = subscriptions.importedActive.length + subscriptions.importedPending.length;
|
|
896324
|
+
const subscriptionUnchanged = subscriptions.unchangedActive.length + subscriptions.unchangedPending.length;
|
|
896325
|
+
if (values2.size === 0 && subscriptionImports === 0 && subscriptionUnchanged === 0 && subscriptions.skipped.length === 0) {
|
|
896326
|
+
const detail = parseErrors.length > 0 ? `No importable settings or subscriptions found. ${parseErrors.join("; ")}` : "No GoodVibes TUI settings or subscription store with importable Agent-owned state was found.";
|
|
896210
896327
|
return {
|
|
896211
896328
|
status: "No GoodVibes TUI settings imported.",
|
|
896212
896329
|
runtimeSnapshot: null,
|
|
@@ -896236,15 +896353,20 @@ async function importAgentWorkspaceTuiSettings(context) {
|
|
|
896236
896353
|
skipped.push(`${setting.key}: ${error53 instanceof Error ? error53.message : String(error53)}`);
|
|
896237
896354
|
}
|
|
896238
896355
|
}
|
|
896356
|
+
skipped.push(...subscriptions.skipped);
|
|
896357
|
+
const changedCount = imported.length + subscriptionImports;
|
|
896358
|
+
const unchangedCount = unchanged.length + subscriptionUnchanged;
|
|
896239
896359
|
return {
|
|
896240
|
-
status:
|
|
896360
|
+
status: changedCount > 0 ? `Imported ${changedCount} GoodVibes TUI item(s).` : "No GoodVibes TUI settings changed.",
|
|
896241
896361
|
runtimeSnapshot: context ? buildAgentWorkspaceRuntimeSnapshot(context) : null,
|
|
896242
896362
|
result: {
|
|
896243
|
-
kind: skipped.length > 0 &&
|
|
896244
|
-
title:
|
|
896363
|
+
kind: skipped.length > 0 && changedCount === 0 ? "error" : changedCount > 0 ? "refreshed" : "guidance",
|
|
896364
|
+
title: changedCount > 0 ? "GoodVibes TUI settings imported" : "No settings changed",
|
|
896245
896365
|
detail: [
|
|
896246
896366
|
imported.length > 0 ? `Imported: ${imported.slice(0, 10).join(", ")}${imported.length > 10 ? `, +${imported.length - 10} more` : ""}.` : "",
|
|
896247
|
-
|
|
896367
|
+
subscriptions.importedActive.length > 0 ? `Imported active subscription(s): ${subscriptions.importedActive.join(", ")}.` : "",
|
|
896368
|
+
subscriptions.importedPending.length > 0 ? `Imported pending subscription(s): ${subscriptions.importedPending.join(", ")}.` : "",
|
|
896369
|
+
unchangedCount > 0 ? `${unchangedCount} item(s) already matched.` : "",
|
|
896248
896370
|
skipped.length > 0 ? `Skipped: ${skipped.slice(0, 5).join("; ")}${skipped.length > 5 ? `; +${skipped.length - 5} more` : ""}.` : "",
|
|
896249
896371
|
parseErrors.length > 0 ? `Parse issues: ${parseErrors.join("; ")}.` : ""
|
|
896250
896372
|
].filter((line2) => line2.length > 0).join(" "),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
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",
|
|
@@ -43,7 +43,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
43
43
|
summary: 'Import preferences, sign in, and choose the main model.',
|
|
44
44
|
detail: 'Start here on a fresh install. Every row either saves state, opens the shared model picker, or opens a confirmed in-modal form.',
|
|
45
45
|
actions: [
|
|
46
|
-
{ id: 'import-goodvibes-tui-settings', label: 'Import GoodVibes settings', detail: 'Copy existing display, provider, behavior, permission, TTS, channel, helper, tool, release, and automation values into Agent-owned
|
|
46
|
+
{ id: 'import-goodvibes-tui-settings', label: 'Import GoodVibes settings', detail: 'Copy existing display, provider, subscription, behavior, permission, TTS, channel, helper, tool, release, and automation values into Agent-owned state.', kind: 'settings-import', safety: 'safe' },
|
|
47
47
|
{ id: 'subscription-login-start', label: 'Start subscription login', detail: 'Start one provider sign-in flow, save pending state, and return here.', editorKind: 'subscription-login-start', kind: 'editor', safety: 'safe' },
|
|
48
48
|
{ id: 'subscription-login-finish', label: 'Finish subscription login', detail: 'Exchange a code or redirect URL and save the provider subscription session.', editorKind: 'subscription-login-finish', kind: 'editor', safety: 'safe' },
|
|
49
49
|
{ id: 'setup-provider-model', label: 'Choose main model', detail: 'Open the shared provider/model picker for normal assistant turns.', kind: 'model-picker', modelPickerFlow: 'providerModel', modelPickerTarget: 'main', safety: 'safe' },
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import type { ConfigKey, ConfigSetting } from '@pellux/goodvibes-sdk/platform/config';
|
|
3
|
+
import type { PendingSubscriptionLogin, ProviderSubscription } from '@pellux/goodvibes-sdk/platform/config';
|
|
3
4
|
import { setHarnessSetting } from '../agent/harness-control.ts';
|
|
4
5
|
import { isExternalHostOwnedSettingKey } from '../config/agent-settings-policy.ts';
|
|
5
6
|
import { buildAgentWorkspaceRuntimeSnapshot } from './agent-workspace-snapshot.ts';
|
|
@@ -83,6 +84,83 @@ function valuesMatch(left: unknown, right: unknown): boolean {
|
|
|
83
84
|
return JSON.stringify(left) === JSON.stringify(right);
|
|
84
85
|
}
|
|
85
86
|
|
|
87
|
+
function readRecordMap(record: Record<string, unknown>, key: string): readonly unknown[] {
|
|
88
|
+
const value = record[key];
|
|
89
|
+
return isRecord(value) ? Object.values(value) : [];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function isProviderSubscription(value: unknown): value is ProviderSubscription {
|
|
93
|
+
return isRecord(value)
|
|
94
|
+
&& typeof value.provider === 'string'
|
|
95
|
+
&& typeof value.accessToken === 'string'
|
|
96
|
+
&& typeof value.tokenType === 'string'
|
|
97
|
+
&& value.authMode === 'oauth'
|
|
98
|
+
&& typeof value.overrideAmbientApiKeys === 'boolean'
|
|
99
|
+
&& typeof value.createdAt === 'number'
|
|
100
|
+
&& typeof value.updatedAt === 'number';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function isPendingSubscriptionLogin(value: unknown): value is PendingSubscriptionLogin {
|
|
104
|
+
return isRecord(value)
|
|
105
|
+
&& typeof value.provider === 'string'
|
|
106
|
+
&& typeof value.state === 'string'
|
|
107
|
+
&& typeof value.verifier === 'string'
|
|
108
|
+
&& typeof value.redirectUri === 'string'
|
|
109
|
+
&& typeof value.createdAt === 'number';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function importTuiSubscriptions(context: CommandContext, parseErrors: string[]): {
|
|
113
|
+
readonly importedActive: string[];
|
|
114
|
+
readonly importedPending: string[];
|
|
115
|
+
readonly unchangedActive: string[];
|
|
116
|
+
readonly unchangedPending: string[];
|
|
117
|
+
readonly skipped: string[];
|
|
118
|
+
} {
|
|
119
|
+
const shellPaths = context.workspace.shellPaths;
|
|
120
|
+
const manager = context.platform.subscriptionManager;
|
|
121
|
+
const result = {
|
|
122
|
+
importedActive: [] as string[],
|
|
123
|
+
importedPending: [] as string[],
|
|
124
|
+
unchangedActive: [] as string[],
|
|
125
|
+
unchangedPending: [] as string[],
|
|
126
|
+
skipped: [] as string[],
|
|
127
|
+
};
|
|
128
|
+
if (!shellPaths || !manager) return result;
|
|
129
|
+
|
|
130
|
+
const sourcePath = shellPaths.resolveUserPath(GOODVIBES_TUI_SURFACE_ROOT, 'subscriptions.json');
|
|
131
|
+
try {
|
|
132
|
+
const store = readJsonRecord(sourcePath);
|
|
133
|
+
if (!store) return result;
|
|
134
|
+
for (const entry of readRecordMap(store, 'subscriptions')) {
|
|
135
|
+
if (!isProviderSubscription(entry)) {
|
|
136
|
+
result.skipped.push('active subscription with invalid shape');
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (valuesMatch(manager.get(entry.provider), entry)) {
|
|
140
|
+
result.unchangedActive.push(entry.provider);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
manager.saveSubscription(entry);
|
|
144
|
+
result.importedActive.push(entry.provider);
|
|
145
|
+
}
|
|
146
|
+
for (const entry of readRecordMap(store, 'pending')) {
|
|
147
|
+
if (!isPendingSubscriptionLogin(entry)) {
|
|
148
|
+
result.skipped.push('pending subscription with invalid shape');
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (valuesMatch(manager.getPending(entry.provider), entry)) {
|
|
152
|
+
result.unchangedPending.push(entry.provider);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
manager.savePending(entry);
|
|
156
|
+
result.importedPending.push(entry.provider);
|
|
157
|
+
}
|
|
158
|
+
} catch (error) {
|
|
159
|
+
parseErrors.push(`subscriptions: ${error instanceof Error ? error.message : String(error)}`);
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
|
|
86
164
|
export function agentWorkspaceSettingSchema(context: CommandContext | null, key: string): ConfigSetting | null {
|
|
87
165
|
return context?.platform?.configManager
|
|
88
166
|
?.getSchema()
|
|
@@ -200,7 +278,7 @@ export async function applyAgentWorkspaceSettingValue(
|
|
|
200
278
|
export async function importAgentWorkspaceTuiSettings(context: CommandContext | null): Promise<TuiSettingsImportOutcome> {
|
|
201
279
|
const shellPaths = context?.workspace?.shellPaths;
|
|
202
280
|
const configManager = context?.platform?.configManager;
|
|
203
|
-
if (!shellPaths || !configManager) {
|
|
281
|
+
if (!context || !shellPaths || !configManager) {
|
|
204
282
|
return {
|
|
205
283
|
status: 'GoodVibes TUI settings import is unavailable in this runtime.',
|
|
206
284
|
runtimeSnapshot: null,
|
|
@@ -232,11 +310,14 @@ export async function importAgentWorkspaceTuiSettings(context: CommandContext |
|
|
|
232
310
|
parseErrors.push(`${source.label}: ${error instanceof Error ? error.message : String(error)}`);
|
|
233
311
|
}
|
|
234
312
|
}
|
|
313
|
+
const subscriptions = importTuiSubscriptions(context, parseErrors);
|
|
314
|
+
const subscriptionImports = subscriptions.importedActive.length + subscriptions.importedPending.length;
|
|
315
|
+
const subscriptionUnchanged = subscriptions.unchangedActive.length + subscriptions.unchangedPending.length;
|
|
235
316
|
|
|
236
|
-
if (values.size === 0) {
|
|
317
|
+
if (values.size === 0 && subscriptionImports === 0 && subscriptionUnchanged === 0 && subscriptions.skipped.length === 0) {
|
|
237
318
|
const detail = parseErrors.length > 0
|
|
238
|
-
? `No importable settings found. ${parseErrors.join('; ')}`
|
|
239
|
-
: 'No GoodVibes TUI settings
|
|
319
|
+
? `No importable settings or subscriptions found. ${parseErrors.join('; ')}`
|
|
320
|
+
: 'No GoodVibes TUI settings or subscription store with importable Agent-owned state was found.';
|
|
240
321
|
return {
|
|
241
322
|
status: 'No GoodVibes TUI settings imported.',
|
|
242
323
|
runtimeSnapshot: null,
|
|
@@ -266,16 +347,21 @@ export async function importAgentWorkspaceTuiSettings(context: CommandContext |
|
|
|
266
347
|
skipped.push(`${setting.key}: ${error instanceof Error ? error.message : String(error)}`);
|
|
267
348
|
}
|
|
268
349
|
}
|
|
350
|
+
skipped.push(...subscriptions.skipped);
|
|
351
|
+
const changedCount = imported.length + subscriptionImports;
|
|
352
|
+
const unchangedCount = unchanged.length + subscriptionUnchanged;
|
|
269
353
|
|
|
270
354
|
return {
|
|
271
|
-
status:
|
|
355
|
+
status: changedCount > 0 ? `Imported ${changedCount} GoodVibes TUI item(s).` : 'No GoodVibes TUI settings changed.',
|
|
272
356
|
runtimeSnapshot: context ? buildAgentWorkspaceRuntimeSnapshot(context) : null,
|
|
273
357
|
result: {
|
|
274
|
-
kind: skipped.length > 0 &&
|
|
275
|
-
title:
|
|
358
|
+
kind: skipped.length > 0 && changedCount === 0 ? 'error' : changedCount > 0 ? 'refreshed' : 'guidance',
|
|
359
|
+
title: changedCount > 0 ? 'GoodVibes TUI settings imported' : 'No settings changed',
|
|
276
360
|
detail: [
|
|
277
361
|
imported.length > 0 ? `Imported: ${imported.slice(0, 10).join(', ')}${imported.length > 10 ? `, +${imported.length - 10} more` : ''}.` : '',
|
|
278
|
-
|
|
362
|
+
subscriptions.importedActive.length > 0 ? `Imported active subscription(s): ${subscriptions.importedActive.join(', ')}.` : '',
|
|
363
|
+
subscriptions.importedPending.length > 0 ? `Imported pending subscription(s): ${subscriptions.importedPending.join(', ')}.` : '',
|
|
364
|
+
unchangedCount > 0 ? `${unchangedCount} item(s) already matched.` : '',
|
|
279
365
|
skipped.length > 0 ? `Skipped: ${skipped.slice(0, 5).join('; ')}${skipped.length > 5 ? `; +${skipped.length - 5} more` : ''}.` : '',
|
|
280
366
|
parseErrors.length > 0 ? `Parse issues: ${parseErrors.join('; ')}.` : '',
|
|
281
367
|
].filter((line) => line.length > 0).join(' '),
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '1.1.
|
|
9
|
+
let _version = '1.1.6';
|
|
10
10
|
try {
|
|
11
11
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|
|
12
12
|
readonly version?: unknown;
|