@astralyn/pi 1.4.7 → 1.4.8
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 +15 -0
- package/dist/bundle/chunks/{chunk-FYKNSJG6.js → chunk-5VIOGR76.js} +1 -1
- package/dist/bundle/chunks/{chunk-YJTSOLP2.js → chunk-I2COK45I.js} +89 -89
- package/dist/bundle/chunks/{virtual-modules-PKEOKGYI.js → virtual-modules-BBLD7YLS.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/package-manager.d.ts +4 -8
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +11 -72
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resource-loader.d.ts +2 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +21 -24
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/skill-invocation.d.ts +46 -0
- package/dist/core/skill-invocation.d.ts.map +1 -0
- package/dist/core/skill-invocation.js +128 -0
- package/dist/core/skill-invocation.js.map +1 -0
- package/dist/extensions/agent/settings-host.d.ts +33 -0
- package/dist/extensions/agent/settings-host.d.ts.map +1 -0
- package/dist/extensions/agent/settings-host.js +75 -0
- package/dist/extensions/agent/settings-host.js.map +1 -0
- package/dist/extensions/agent/settings.d.ts.map +1 -1
- package/dist/extensions/agent/settings.js +18 -7
- package/dist/extensions/agent/settings.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +10 -8
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +51 -121
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/docs/packages.md +1 -1
- package/docs/settings.md +1 -1
- package/docs/skills.md +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -5,6 +5,8 @@ import { homedir } from "node:os";
|
|
|
5
5
|
import { basename, dirname, join, relative } from "node:path";
|
|
6
6
|
import { Container, getKeybindings, Input, matchesKey, Spacer, truncateToWidth, visibleWidth, } from "@earendil-works/pi-tui";
|
|
7
7
|
import { CONFIG_DIR_NAME } from "../../../config.js";
|
|
8
|
+
import { DefaultPackageManager, } from "../../../core/package-manager.js";
|
|
9
|
+
import { matchInvocation, SkillInvocationPolicy, withInvocation } from "../../../core/skill-invocation.js";
|
|
8
10
|
import { readSkillDisableModelInvocation, resolveSkillEffectiveState, } from "../../../core/skills.js";
|
|
9
11
|
import { BUILTIN_PATH_PREFIX } from "../../../core/source-info.js";
|
|
10
12
|
import { canonicalizePath, isLocalPath, resolvePath } from "../../../utils/paths.js";
|
|
@@ -19,6 +21,10 @@ function hasResourcePattern(patterns, pattern) {
|
|
|
19
21
|
}
|
|
20
22
|
return false;
|
|
21
23
|
}
|
|
24
|
+
/** The invocation override that pins a skill state; Off and inherit leave invocation to the defaults. */
|
|
25
|
+
function stateInvocation(state) {
|
|
26
|
+
return state === "on" ? "model-and-user" : state === "user-only" ? "user-only" : undefined;
|
|
27
|
+
}
|
|
22
28
|
const RESOURCE_TYPES = ["extensions", "skills", "prompts", "themes"];
|
|
23
29
|
const RESOURCE_TYPE_LABELS = {
|
|
24
30
|
extensions: "Extensions",
|
|
@@ -110,7 +116,6 @@ function buildGroups(resolved, agentDir) {
|
|
|
110
116
|
displayName,
|
|
111
117
|
groupKey,
|
|
112
118
|
subgroupKey,
|
|
113
|
-
skillInvocationOverride: res.skillInvocationOverride,
|
|
114
119
|
frontmatterDisableModelInvocation: resourceType === "skills" ? readSkillDisableModelInvocation(path) : undefined,
|
|
115
120
|
});
|
|
116
121
|
}
|
|
@@ -184,7 +189,8 @@ class ResourceList {
|
|
|
184
189
|
this.agentDir = agentDir;
|
|
185
190
|
this.writeScope = writeScope;
|
|
186
191
|
this.inheritedEnabledByKey = this.buildInheritedEnabledMap(groupsByScope.global);
|
|
187
|
-
this.
|
|
192
|
+
this.packageManager = new DefaultPackageManager({ cwd, agentDir, settingsManager });
|
|
193
|
+
this.skillInvocation = new SkillInvocationPolicy(settingsManager, this.packageManager);
|
|
188
194
|
this.searchInput = new Input();
|
|
189
195
|
// 8 lines of chrome: top spacer + top border + spacer + header (2 lines) + spacer + bottom spacer + bottom border
|
|
190
196
|
const chrome = 8;
|
|
@@ -211,19 +217,6 @@ class ResourceList {
|
|
|
211
217
|
}
|
|
212
218
|
return result;
|
|
213
219
|
}
|
|
214
|
-
buildInheritedSkillStateMap(groups) {
|
|
215
|
-
const result = new Map();
|
|
216
|
-
for (const group of groups) {
|
|
217
|
-
for (const subgroup of group.subgroups) {
|
|
218
|
-
if (subgroup.type !== "skills")
|
|
219
|
-
continue;
|
|
220
|
-
for (const item of subgroup.items) {
|
|
221
|
-
result.set(this.getResourceItemKey(item), this.getSkillEffectiveState(item));
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return result;
|
|
226
|
-
}
|
|
227
220
|
buildFlatList() {
|
|
228
221
|
this.flatItems = [];
|
|
229
222
|
for (const group of this.groups) {
|
|
@@ -301,12 +294,8 @@ class ResourceList {
|
|
|
301
294
|
}
|
|
302
295
|
updateItem(item, enabled) {
|
|
303
296
|
item.enabled = enabled;
|
|
304
|
-
if (this.writeScope === "global")
|
|
297
|
+
if (this.writeScope === "global")
|
|
305
298
|
this.inheritedEnabledByKey.set(this.getResourceItemKey(item), enabled);
|
|
306
|
-
if (item.resourceType === "skills") {
|
|
307
|
-
this.inheritedSkillStateByKey.set(this.getResourceItemKey(item), this.getSkillEffectiveState(item));
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
299
|
// Update in groups too
|
|
311
300
|
for (const group of this.groups) {
|
|
312
301
|
for (const subgroup of group.subgroups) {
|
|
@@ -434,15 +423,11 @@ class ResourceList {
|
|
|
434
423
|
const state = this.getNextProjectSkillOverrideState(item);
|
|
435
424
|
if (!this.setProjectSkillOverride(item, state))
|
|
436
425
|
return undefined;
|
|
437
|
-
item.skillInvocationOverride =
|
|
438
|
-
state === "on" ? "model-and-user" : state === "user-only" ? "user-only" : undefined;
|
|
439
426
|
return state === "inherit" ? this.getInheritedSkillEffectiveState(item) !== "off" : state !== "off";
|
|
440
427
|
}
|
|
441
428
|
const currentState = this.getSkillEffectiveState(item);
|
|
442
429
|
const nextState = currentState === "on" ? "user-only" : currentState === "user-only" ? "off" : "on";
|
|
443
430
|
this.setGlobalSkillEffectiveState(item, nextState);
|
|
444
|
-
item.skillInvocationOverride =
|
|
445
|
-
nextState === "on" ? "model-and-user" : nextState === "user-only" ? "user-only" : undefined;
|
|
446
431
|
return nextState !== "off";
|
|
447
432
|
}
|
|
448
433
|
if (this.writeScope === "project") {
|
|
@@ -562,65 +547,42 @@ class ResourceList {
|
|
|
562
547
|
this.toggleTopLevelResource(item, enabled);
|
|
563
548
|
else
|
|
564
549
|
this.togglePackageResource(item, enabled);
|
|
565
|
-
this.setSkillInvocationOverride(item, "user", state
|
|
550
|
+
this.setSkillInvocationOverride(item, "user", stateInvocation(state));
|
|
566
551
|
}
|
|
567
552
|
setProjectSkillOverride(item, state) {
|
|
568
553
|
const loadState = state === "inherit" ? "inherit" : state === "off" ? "unload" : "load";
|
|
569
554
|
if (!this.setProjectResourceOverride(item, loadState))
|
|
570
555
|
return false;
|
|
571
|
-
this.setSkillInvocationOverride(item, "project", state
|
|
556
|
+
this.setSkillInvocationOverride(item, "project", stateInvocation(state));
|
|
572
557
|
return true;
|
|
573
558
|
}
|
|
559
|
+
/** Runs after the load write, which creates the package entry a project override needs. */
|
|
574
560
|
setSkillInvocationOverride(item, scope, override) {
|
|
561
|
+
const layer = this.skillInvocation.layer(scope, item.metadata);
|
|
562
|
+
if (!layer)
|
|
563
|
+
return;
|
|
564
|
+
const overrides = withInvocation(layer, item.path, override);
|
|
575
565
|
if (item.metadata.origin === "top-level") {
|
|
576
|
-
const settings = scope === "project" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();
|
|
577
|
-
const updated = { ...settings.skillInvocationOverrides };
|
|
578
|
-
const patterns = this.getTopLevelOverridePatterns(item, scope);
|
|
579
|
-
for (const pattern of Object.keys(updated)) {
|
|
580
|
-
if (hasResourcePattern(patterns, pattern))
|
|
581
|
-
delete updated[pattern];
|
|
582
|
-
}
|
|
583
|
-
if (override) {
|
|
584
|
-
const pattern = scope === "project" && this.isInheritedGlobalItem(item)
|
|
585
|
-
? item.path
|
|
586
|
-
: this.getResourcePatternForScope(item, scope);
|
|
587
|
-
updated[pattern] = override;
|
|
588
|
-
}
|
|
589
566
|
if (scope === "project")
|
|
590
|
-
this.settingsManager.setProjectSkillInvocationOverrides(
|
|
567
|
+
this.settingsManager.setProjectSkillInvocationOverrides(overrides);
|
|
591
568
|
else
|
|
592
|
-
this.settingsManager.setSkillInvocationOverrides(
|
|
569
|
+
this.settingsManager.setSkillInvocationOverrides(overrides);
|
|
593
570
|
return;
|
|
594
571
|
}
|
|
595
572
|
const settings = scope === "project" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();
|
|
596
573
|
const packages = [...(settings.packages ?? [])];
|
|
597
|
-
const pkgIndex =
|
|
598
|
-
|
|
574
|
+
const pkgIndex = this.skillInvocation.findPackage(scope, item.metadata);
|
|
575
|
+
const current = packages[pkgIndex];
|
|
576
|
+
if (current === undefined || (typeof current === "string" && !overrides))
|
|
599
577
|
return;
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
return;
|
|
604
|
-
pkg = { source: pkg };
|
|
578
|
+
const pkg = typeof current === "string" ? { source: current } : { ...current };
|
|
579
|
+
pkg.skillInvocationOverrides = overrides;
|
|
580
|
+
if (overrides || RESOURCE_TYPES.some((key) => pkg[key] !== undefined))
|
|
605
581
|
packages[pkgIndex] = pkg;
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if (hasResourcePattern(patterns, pattern))
|
|
611
|
-
delete updated[pattern];
|
|
612
|
-
}
|
|
613
|
-
const pattern = this.getPackageResourcePattern(item);
|
|
614
|
-
if (override)
|
|
615
|
-
updated[pattern] = override;
|
|
616
|
-
pkg.skillInvocationOverrides = Object.keys(updated).length > 0 ? updated : undefined;
|
|
617
|
-
const hasConfiguration = RESOURCE_TYPES.some((key) => pkg[key] !== undefined) || pkg.skillInvocationOverrides !== undefined;
|
|
618
|
-
if (!hasConfiguration) {
|
|
619
|
-
if (scope === "project" && pkg.autoload === false)
|
|
620
|
-
packages.splice(pkgIndex, 1);
|
|
621
|
-
else
|
|
622
|
-
packages[pkgIndex] = pkg.source;
|
|
623
|
-
}
|
|
582
|
+
else if (scope === "project" && pkg.autoload === false)
|
|
583
|
+
packages.splice(pkgIndex, 1);
|
|
584
|
+
else
|
|
585
|
+
packages[pkgIndex] = pkg.source;
|
|
624
586
|
if (scope === "project")
|
|
625
587
|
this.settingsManager.setProjectPackages(packages);
|
|
626
588
|
else
|
|
@@ -696,21 +658,19 @@ class ResourceList {
|
|
|
696
658
|
? this.getProjectSkillOverrideState(item) === "inherit"
|
|
697
659
|
: this.getProjectOverrideState(item) === "inherit";
|
|
698
660
|
}
|
|
661
|
+
/** The state settings give a skill in the current mode; global mode ignores project settings. */
|
|
699
662
|
getSkillEffectiveState(item) {
|
|
663
|
+
const scopes = this.writeScope === "project" ? ["project", "user"] : ["user"];
|
|
700
664
|
return resolveSkillEffectiveState({
|
|
701
665
|
enabled: item.enabled,
|
|
702
|
-
invocationOverride: item.
|
|
666
|
+
invocationOverride: this.skillInvocation.resolve(item.path, item.metadata, scopes),
|
|
703
667
|
frontmatterDisableModelInvocation: item.frontmatterDisableModelInvocation,
|
|
704
668
|
});
|
|
705
669
|
}
|
|
706
670
|
getInheritedSkillEffectiveState(item) {
|
|
707
|
-
const inherited = this.inheritedSkillStateByKey.get(this.getResourceItemKey(item));
|
|
708
|
-
if (inherited)
|
|
709
|
-
return inherited;
|
|
710
|
-
const userScoped = this.getItemScope(item) === "user";
|
|
711
671
|
return resolveSkillEffectiveState({
|
|
712
|
-
enabled:
|
|
713
|
-
invocationOverride:
|
|
672
|
+
enabled: this.getInheritedEnabled(item),
|
|
673
|
+
invocationOverride: this.skillInvocation.resolve(item.path, item.metadata, ["user"]),
|
|
714
674
|
frontmatterDisableModelInvocation: item.frontmatterDisableModelInvocation,
|
|
715
675
|
});
|
|
716
676
|
}
|
|
@@ -729,42 +689,15 @@ class ResourceList {
|
|
|
729
689
|
getProjectSkillOverrideState(item) {
|
|
730
690
|
if (this.writeScope !== "project")
|
|
731
691
|
return "inherit";
|
|
732
|
-
|
|
733
|
-
let invocationOverrides;
|
|
734
|
-
let patterns;
|
|
735
|
-
if (item.metadata.origin === "top-level") {
|
|
736
|
-
const settings = this.settingsManager.getProjectSettings();
|
|
737
|
-
loadState = this.getOverrideStateFromEntries((settings.skills ?? []), this.getTopLevelOverridePatterns(item, "project"), false);
|
|
738
|
-
invocationOverrides = settings.skillInvocationOverrides;
|
|
739
|
-
patterns = this.getTopLevelOverridePatterns(item, "project");
|
|
740
|
-
}
|
|
741
|
-
else {
|
|
742
|
-
const pkg = this.findMatchingPackageSource(item, "project");
|
|
743
|
-
if (typeof pkg !== "object")
|
|
744
|
-
return "inherit";
|
|
745
|
-
loadState =
|
|
746
|
-
pkg.skills === undefined
|
|
747
|
-
? "inherit"
|
|
748
|
-
: this.getOverrideStateFromEntries(pkg.skills, this.getPackageSkillInvocationOverridePatterns(item), pkg.autoload !== false);
|
|
749
|
-
invocationOverrides = pkg.skillInvocationOverrides;
|
|
750
|
-
patterns = this.getPackageSkillInvocationOverridePatterns(item);
|
|
751
|
-
}
|
|
692
|
+
const loadState = this.getProjectOverrideState(item);
|
|
752
693
|
if (loadState === "unload")
|
|
753
694
|
return "off";
|
|
754
|
-
const
|
|
695
|
+
const layer = this.skillInvocation.layer("project", item.metadata);
|
|
696
|
+
const invocation = layer ? matchInvocation(layer, item.path).override : undefined;
|
|
755
697
|
if (invocation)
|
|
756
698
|
return invocation === "user-only" ? "user-only" : "on";
|
|
757
699
|
return loadState;
|
|
758
700
|
}
|
|
759
|
-
getSkillInvocationOverrideFromMap(overrides, patterns) {
|
|
760
|
-
for (const [pattern, override] of Object.entries(overrides ?? {})) {
|
|
761
|
-
if (!hasResourcePattern(patterns, pattern))
|
|
762
|
-
continue;
|
|
763
|
-
if (override === "model-and-user" || override === "user-only")
|
|
764
|
-
return override;
|
|
765
|
-
}
|
|
766
|
-
return undefined;
|
|
767
|
-
}
|
|
768
701
|
setProjectResourceOverride(item, state) {
|
|
769
702
|
return item.metadata.origin === "top-level"
|
|
770
703
|
? this.setProjectTopLevelOverride(item, state)
|
|
@@ -801,7 +734,7 @@ class ResourceList {
|
|
|
801
734
|
}
|
|
802
735
|
setProjectPackageOverride(item, state) {
|
|
803
736
|
const packages = [...(this.settingsManager.getProjectSettings().packages ?? [])];
|
|
804
|
-
let pkgIndex = packages.findIndex((pkg) => this.
|
|
737
|
+
let pkgIndex = packages.findIndex((pkg) => this.isSamePackage(item.metadata.source, this.getItemScope(item), typeof pkg === "string" ? pkg : pkg.source, "project"));
|
|
805
738
|
if (pkgIndex === -1) {
|
|
806
739
|
if (state === "inherit")
|
|
807
740
|
return false;
|
|
@@ -851,7 +784,7 @@ class ResourceList {
|
|
|
851
784
|
const entries = pkg[item.resourceType];
|
|
852
785
|
if (entries === undefined)
|
|
853
786
|
return "inherit";
|
|
854
|
-
return this.getOverrideStateFromEntries(entries,
|
|
787
|
+
return this.getOverrideStateFromEntries(entries, this.getPackageOverridePatterns(item), pkg.autoload !== false);
|
|
855
788
|
}
|
|
856
789
|
getOverrideStateFromEntries(entries, patterns, emptyArrayIsUnload) {
|
|
857
790
|
if (entries.length === 0 && emptyArrayIsUnload)
|
|
@@ -906,20 +839,16 @@ class ResourceList {
|
|
|
906
839
|
const sourcePath = resolvePath(source, this.getTopLevelBaseDir(this.getItemScope(item)), { trim: true });
|
|
907
840
|
return { source: relative(this.getTopLevelBaseDir("project"), sourcePath) || ".", autoload: false };
|
|
908
841
|
}
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
return false;
|
|
914
|
-
const left = resolvePath(leftSource, this.getTopLevelBaseDir(leftScope), { trim: true });
|
|
915
|
-
const right = resolvePath(rightSource, this.getTopLevelBaseDir(rightScope), { trim: true });
|
|
916
|
-
return left === right;
|
|
842
|
+
/** Package entries match by the identity package loading dedupes on, so `npm:pkg@1` and `npm:pkg` are one package. */
|
|
843
|
+
isSamePackage(leftSource, leftScope, rightSource, rightScope) {
|
|
844
|
+
return (this.packageManager.getPackageIdentity(leftSource, leftScope) ===
|
|
845
|
+
this.packageManager.getPackageIdentity(rightSource, rightScope));
|
|
917
846
|
}
|
|
918
847
|
findMatchingPackageSource(item, targetScope) {
|
|
919
848
|
const settings = targetScope === "project"
|
|
920
849
|
? this.settingsManager.getProjectSettings()
|
|
921
850
|
: this.settingsManager.getGlobalSettings();
|
|
922
|
-
return (settings.packages ?? []).find((pkg) => this.
|
|
851
|
+
return (settings.packages ?? []).find((pkg) => this.isSamePackage(item.metadata.source, this.getItemScope(item), typeof pkg === "string" ? pkg : pkg.source, targetScope));
|
|
923
852
|
}
|
|
924
853
|
getPatternEntryTarget(entry) {
|
|
925
854
|
return entry.startsWith("!") || entry.startsWith("+") || entry.startsWith("-") ? entry.slice(1) : entry;
|
|
@@ -944,13 +873,14 @@ class ResourceList {
|
|
|
944
873
|
const baseDir = item.metadata.baseDir ?? dirname(item.path);
|
|
945
874
|
return relative(baseDir, item.path);
|
|
946
875
|
}
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
const
|
|
950
|
-
if (
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
876
|
+
/** Package filter entries that name an item; a skill can also be named by its absolute path or directory. */
|
|
877
|
+
getPackageOverridePatterns(item) {
|
|
878
|
+
const pattern = this.getPackageResourcePattern(item);
|
|
879
|
+
if (item.resourceType !== "skills")
|
|
880
|
+
return new Set([pattern]);
|
|
881
|
+
const patterns = new Set([pattern, item.path]);
|
|
882
|
+
if (basename(item.path) === "SKILL.md")
|
|
883
|
+
patterns.add(dirname(pattern)).add(dirname(item.path));
|
|
954
884
|
return patterns;
|
|
955
885
|
}
|
|
956
886
|
}
|