@vandeepunk/pi-coding-agent 0.0.2 → 0.0.4
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 +105 -0
- package/README.md +6 -6
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +16 -0
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/export-html/template.css +3 -0
- package/dist/core/export-html/template.js +32 -15
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +17 -2
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +53 -9
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +3 -3
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/model-registry.d.ts +3 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +133 -37
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +5 -5
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-manager.d.ts +21 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +134 -33
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +3 -3
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +15 -15
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +6 -6
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +4 -4
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +57 -3
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +172 -177
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +11 -11
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +9 -4
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +6 -6
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +5 -0
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +5 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +49 -34
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +0 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +117 -104
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/git.d.ts +21 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +150 -4
- package/dist/utils/git.js.map +1 -1
- package/docs/extensions.md +5 -0
- package/docs/models.md +40 -1
- package/docs/packages.md +23 -3
- package/docs/prompt-templates.md +6 -6
- package/docs/providers.md +13 -0
- package/docs/rpc.md +1 -1
- package/docs/sdk.md +5 -3
- package/docs/settings.md +2 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/hello.ts +1 -1
- package/examples/extensions/subagent/README.md +4 -4
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/08-prompt-templates.ts +2 -2
- package/package.json +7 -8
- /package/examples/extensions/subagent/{prompts → commands}/implement-and-review.md +0 -0
- /package/examples/extensions/subagent/{prompts → commands}/implement.md +0 -0
- /package/examples/extensions/subagent/{prompts → commands}/scout-and-plan.md +0 -0
|
@@ -6,12 +6,12 @@ import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
|
6
6
|
import ignore from "ignore";
|
|
7
7
|
import { minimatch } from "minimatch";
|
|
8
8
|
import { CONFIG_DIR_NAME } from "../config.js";
|
|
9
|
-
import {
|
|
10
|
-
const RESOURCE_TYPES = ["extensions", "skills", "
|
|
9
|
+
import { parseGitUrl } from "../utils/git.js";
|
|
10
|
+
const RESOURCE_TYPES = ["extensions", "skills", "commands", "themes"];
|
|
11
11
|
const FILE_PATTERNS = {
|
|
12
12
|
extensions: /\.(ts|js)$/,
|
|
13
13
|
skills: /\.md$/,
|
|
14
|
-
|
|
14
|
+
commands: /\.md$/,
|
|
15
15
|
themes: /\.json$/,
|
|
16
16
|
};
|
|
17
17
|
const IGNORE_FILE_NAMES = [".gitignore", ".ignore", ".fdignore"];
|
|
@@ -283,6 +283,12 @@ function collectAutoExtensionEntries(dir) {
|
|
|
283
283
|
const entries = [];
|
|
284
284
|
if (!existsSync(dir))
|
|
285
285
|
return entries;
|
|
286
|
+
// First check if this directory itself has explicit extension entries (package.json or index)
|
|
287
|
+
const rootEntries = resolveExtensionEntries(dir);
|
|
288
|
+
if (rootEntries) {
|
|
289
|
+
return rootEntries;
|
|
290
|
+
}
|
|
291
|
+
// Otherwise, discover extensions from directory contents
|
|
286
292
|
const ig = ignore();
|
|
287
293
|
addIgnoreRules(ig, dir, dir);
|
|
288
294
|
try {
|
|
@@ -465,6 +471,41 @@ export class DefaultPackageManager {
|
|
|
465
471
|
setProgressCallback(callback) {
|
|
466
472
|
this.progressCallback = callback;
|
|
467
473
|
}
|
|
474
|
+
addSourceToSettings(source, options) {
|
|
475
|
+
const scope = options?.local ? "project" : "user";
|
|
476
|
+
const currentSettings = scope === "project" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();
|
|
477
|
+
const currentPackages = currentSettings.packages ?? [];
|
|
478
|
+
const normalizedSource = this.normalizePackageSourceForSettings(source, scope);
|
|
479
|
+
const exists = currentPackages.some((existing) => this.packageSourcesMatch(existing, source, scope));
|
|
480
|
+
if (exists) {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
const nextPackages = [...currentPackages, normalizedSource];
|
|
484
|
+
if (scope === "project") {
|
|
485
|
+
this.settingsManager.setProjectPackages(nextPackages);
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
this.settingsManager.setPackages(nextPackages);
|
|
489
|
+
}
|
|
490
|
+
return true;
|
|
491
|
+
}
|
|
492
|
+
removeSourceFromSettings(source, options) {
|
|
493
|
+
const scope = options?.local ? "project" : "user";
|
|
494
|
+
const currentSettings = scope === "project" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();
|
|
495
|
+
const currentPackages = currentSettings.packages ?? [];
|
|
496
|
+
const nextPackages = currentPackages.filter((existing) => !this.packageSourcesMatch(existing, source, scope));
|
|
497
|
+
const changed = nextPackages.length !== currentPackages.length;
|
|
498
|
+
if (!changed) {
|
|
499
|
+
return false;
|
|
500
|
+
}
|
|
501
|
+
if (scope === "project") {
|
|
502
|
+
this.settingsManager.setProjectPackages(nextPackages);
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
this.settingsManager.setPackages(nextPackages);
|
|
506
|
+
}
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
468
509
|
getInstalledPath(source, scope) {
|
|
469
510
|
const parsed = this.parseSource(source);
|
|
470
511
|
if (parsed.type === "npm") {
|
|
@@ -658,6 +699,9 @@ export class DefaultPackageManager {
|
|
|
658
699
|
if (!installed)
|
|
659
700
|
continue;
|
|
660
701
|
}
|
|
702
|
+
else if (scope === "temporary" && !parsed.pinned) {
|
|
703
|
+
await this.refreshTemporaryGitSource(parsed, sourceStr);
|
|
704
|
+
}
|
|
661
705
|
metadata.baseDir = installedPath;
|
|
662
706
|
this.collectPackageResources(installedPath, accumulator, filter, metadata);
|
|
663
707
|
}
|
|
@@ -697,6 +741,45 @@ export class DefaultPackageManager {
|
|
|
697
741
|
return;
|
|
698
742
|
}
|
|
699
743
|
}
|
|
744
|
+
getPackageSourceString(pkg) {
|
|
745
|
+
return typeof pkg === "string" ? pkg : pkg.source;
|
|
746
|
+
}
|
|
747
|
+
getSourceMatchKeyForInput(source) {
|
|
748
|
+
const parsed = this.parseSource(source);
|
|
749
|
+
if (parsed.type === "npm") {
|
|
750
|
+
return `npm:${parsed.name}`;
|
|
751
|
+
}
|
|
752
|
+
if (parsed.type === "git") {
|
|
753
|
+
return `git:${parsed.host}/${parsed.path}`;
|
|
754
|
+
}
|
|
755
|
+
return `local:${this.resolvePath(parsed.path)}`;
|
|
756
|
+
}
|
|
757
|
+
getSourceMatchKeyForSettings(source, scope) {
|
|
758
|
+
const parsed = this.parseSource(source);
|
|
759
|
+
if (parsed.type === "npm") {
|
|
760
|
+
return `npm:${parsed.name}`;
|
|
761
|
+
}
|
|
762
|
+
if (parsed.type === "git") {
|
|
763
|
+
return `git:${parsed.host}/${parsed.path}`;
|
|
764
|
+
}
|
|
765
|
+
const baseDir = this.getBaseDirForScope(scope);
|
|
766
|
+
return `local:${this.resolvePathFromBase(parsed.path, baseDir)}`;
|
|
767
|
+
}
|
|
768
|
+
packageSourcesMatch(existing, inputSource, scope) {
|
|
769
|
+
const left = this.getSourceMatchKeyForSettings(this.getPackageSourceString(existing), scope);
|
|
770
|
+
const right = this.getSourceMatchKeyForInput(inputSource);
|
|
771
|
+
return left === right;
|
|
772
|
+
}
|
|
773
|
+
normalizePackageSourceForSettings(source, scope) {
|
|
774
|
+
const parsed = this.parseSource(source);
|
|
775
|
+
if (parsed.type !== "local") {
|
|
776
|
+
return source;
|
|
777
|
+
}
|
|
778
|
+
const baseDir = this.getBaseDirForScope(scope);
|
|
779
|
+
const resolved = this.resolvePath(parsed.path);
|
|
780
|
+
const rel = relative(baseDir, resolved);
|
|
781
|
+
return rel || ".";
|
|
782
|
+
}
|
|
700
783
|
parseSource(source) {
|
|
701
784
|
if (source.startsWith("npm:")) {
|
|
702
785
|
const spec = source.slice("npm:".length).trim();
|
|
@@ -708,21 +791,21 @@ export class DefaultPackageManager {
|
|
|
708
791
|
pinned: Boolean(version),
|
|
709
792
|
};
|
|
710
793
|
}
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
794
|
+
const trimmed = source.trim();
|
|
795
|
+
const isWindowsAbsolutePath = /^[A-Za-z]:[\\/]|^\\\\/.test(trimmed);
|
|
796
|
+
const isLocalPathLike = trimmed.startsWith("./") ||
|
|
797
|
+
trimmed.startsWith("../") ||
|
|
798
|
+
trimmed.startsWith("/") ||
|
|
799
|
+
trimmed === "~" ||
|
|
800
|
+
trimmed.startsWith("~/") ||
|
|
801
|
+
isWindowsAbsolutePath;
|
|
802
|
+
if (isLocalPathLike) {
|
|
803
|
+
return { type: "local", path: source };
|
|
804
|
+
}
|
|
805
|
+
// Try parsing as git URL
|
|
806
|
+
const gitParsed = parseGitUrl(source);
|
|
807
|
+
if (gitParsed) {
|
|
808
|
+
return gitParsed;
|
|
726
809
|
}
|
|
727
810
|
return { type: "local", path: source };
|
|
728
811
|
}
|
|
@@ -773,6 +856,8 @@ export class DefaultPackageManager {
|
|
|
773
856
|
/**
|
|
774
857
|
* Get a unique identity for a package, ignoring version/ref.
|
|
775
858
|
* Used to detect when the same package is in both global and project settings.
|
|
859
|
+
* For git packages, uses normalized host/path to ensure SSH and HTTPS URLs
|
|
860
|
+
* for the same repository are treated as identical.
|
|
776
861
|
*/
|
|
777
862
|
getPackageIdentity(source, scope) {
|
|
778
863
|
const parsed = this.parseSource(source);
|
|
@@ -780,7 +865,8 @@ export class DefaultPackageManager {
|
|
|
780
865
|
return `npm:${parsed.name}`;
|
|
781
866
|
}
|
|
782
867
|
if (parsed.type === "git") {
|
|
783
|
-
|
|
868
|
+
// Use host/path for identity to normalize SSH and HTTPS
|
|
869
|
+
return `git:${parsed.host}/${parsed.path}`;
|
|
784
870
|
}
|
|
785
871
|
if (scope) {
|
|
786
872
|
const baseDir = this.getBaseDirForScope(scope);
|
|
@@ -849,8 +935,7 @@ export class DefaultPackageManager {
|
|
|
849
935
|
this.ensureGitIgnore(gitRoot);
|
|
850
936
|
}
|
|
851
937
|
mkdirSync(dirname(targetDir), { recursive: true });
|
|
852
|
-
|
|
853
|
-
await this.runCommand("git", ["clone", cloneUrl, targetDir]);
|
|
938
|
+
await this.runCommand("git", ["clone", source.repo, targetDir]);
|
|
854
939
|
if (source.ref) {
|
|
855
940
|
await this.runCommand("git", ["checkout", source.ref], { cwd: targetDir });
|
|
856
941
|
}
|
|
@@ -867,8 +952,14 @@ export class DefaultPackageManager {
|
|
|
867
952
|
}
|
|
868
953
|
// Fetch latest from remote (handles force-push by getting new history)
|
|
869
954
|
await this.runCommand("git", ["fetch", "--prune", "origin"], { cwd: targetDir });
|
|
870
|
-
// Reset to
|
|
871
|
-
|
|
955
|
+
// Reset to tracking branch. Fall back to origin/HEAD when no upstream is configured.
|
|
956
|
+
try {
|
|
957
|
+
await this.runCommand("git", ["reset", "--hard", "@{upstream}"], { cwd: targetDir });
|
|
958
|
+
}
|
|
959
|
+
catch {
|
|
960
|
+
await this.runCommand("git", ["remote", "set-head", "origin", "-a"], { cwd: targetDir }).catch(() => { });
|
|
961
|
+
await this.runCommand("git", ["reset", "--hard", "origin/HEAD"], { cwd: targetDir });
|
|
962
|
+
}
|
|
872
963
|
// Clean untracked files (extensions should be pristine)
|
|
873
964
|
await this.runCommand("git", ["clean", "-fdx"], { cwd: targetDir });
|
|
874
965
|
const packageJsonPath = join(targetDir, "package.json");
|
|
@@ -876,6 +967,16 @@ export class DefaultPackageManager {
|
|
|
876
967
|
await this.runCommand("npm", ["install"], { cwd: targetDir });
|
|
877
968
|
}
|
|
878
969
|
}
|
|
970
|
+
async refreshTemporaryGitSource(source, sourceStr) {
|
|
971
|
+
try {
|
|
972
|
+
await this.withProgress("pull", sourceStr, `Refreshing ${sourceStr}...`, async () => {
|
|
973
|
+
await this.updateGit(source, "temporary");
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
catch {
|
|
977
|
+
// Keep cached temporary checkout if refresh fails.
|
|
978
|
+
}
|
|
979
|
+
}
|
|
879
980
|
async removeGit(source, scope) {
|
|
880
981
|
const targetDir = this.getGitInstallPath(source, scope);
|
|
881
982
|
if (!existsSync(targetDir))
|
|
@@ -1156,25 +1257,25 @@ export class DefaultPackageManager {
|
|
|
1156
1257
|
const userOverrides = {
|
|
1157
1258
|
extensions: (globalSettings.extensions ?? []),
|
|
1158
1259
|
skills: (globalSettings.skills ?? []),
|
|
1159
|
-
|
|
1260
|
+
commands: (globalSettings.commands ?? []),
|
|
1160
1261
|
themes: (globalSettings.themes ?? []),
|
|
1161
1262
|
};
|
|
1162
1263
|
const projectOverrides = {
|
|
1163
1264
|
extensions: (projectSettings.extensions ?? []),
|
|
1164
1265
|
skills: (projectSettings.skills ?? []),
|
|
1165
|
-
|
|
1266
|
+
commands: (projectSettings.commands ?? []),
|
|
1166
1267
|
themes: (projectSettings.themes ?? []),
|
|
1167
1268
|
};
|
|
1168
1269
|
const userDirs = {
|
|
1169
1270
|
extensions: join(globalBaseDir, "extensions"),
|
|
1170
1271
|
skills: join(globalBaseDir, "skills"),
|
|
1171
|
-
|
|
1272
|
+
commands: join(globalBaseDir, "commands"),
|
|
1172
1273
|
themes: join(globalBaseDir, "themes"),
|
|
1173
1274
|
};
|
|
1174
1275
|
const projectDirs = {
|
|
1175
1276
|
extensions: join(projectBaseDir, "extensions"),
|
|
1176
1277
|
skills: join(projectBaseDir, "skills"),
|
|
1177
|
-
|
|
1278
|
+
commands: join(projectBaseDir, "commands"),
|
|
1178
1279
|
themes: join(projectBaseDir, "themes"),
|
|
1179
1280
|
};
|
|
1180
1281
|
const addResources = (resourceType, paths, metadata, overrides, baseDir) => {
|
|
@@ -1186,11 +1287,11 @@ export class DefaultPackageManager {
|
|
|
1186
1287
|
};
|
|
1187
1288
|
addResources("extensions", collectAutoExtensionEntries(userDirs.extensions), userMetadata, userOverrides.extensions, globalBaseDir);
|
|
1188
1289
|
addResources("skills", collectAutoSkillEntries(userDirs.skills), userMetadata, userOverrides.skills, globalBaseDir);
|
|
1189
|
-
addResources("
|
|
1290
|
+
addResources("commands", collectAutoPromptEntries(userDirs.commands), userMetadata, userOverrides.commands, globalBaseDir);
|
|
1190
1291
|
addResources("themes", collectAutoThemeEntries(userDirs.themes), userMetadata, userOverrides.themes, globalBaseDir);
|
|
1191
1292
|
addResources("extensions", collectAutoExtensionEntries(projectDirs.extensions), projectMetadata, projectOverrides.extensions, projectBaseDir);
|
|
1192
1293
|
addResources("skills", collectAutoSkillEntries(projectDirs.skills), projectMetadata, projectOverrides.skills, projectBaseDir);
|
|
1193
|
-
addResources("
|
|
1294
|
+
addResources("commands", collectAutoPromptEntries(projectDirs.commands), projectMetadata, projectOverrides.commands, projectBaseDir);
|
|
1194
1295
|
addResources("themes", collectAutoThemeEntries(projectDirs.themes), projectMetadata, projectOverrides.themes, projectBaseDir);
|
|
1195
1296
|
}
|
|
1196
1297
|
collectFilesFromPaths(paths, resourceType) {
|
|
@@ -1219,8 +1320,8 @@ export class DefaultPackageManager {
|
|
|
1219
1320
|
return accumulator.extensions;
|
|
1220
1321
|
case "skills":
|
|
1221
1322
|
return accumulator.skills;
|
|
1222
|
-
case "
|
|
1223
|
-
return accumulator.
|
|
1323
|
+
case "commands":
|
|
1324
|
+
return accumulator.commands;
|
|
1224
1325
|
case "themes":
|
|
1225
1326
|
return accumulator.themes;
|
|
1226
1327
|
default:
|
|
@@ -1238,7 +1339,7 @@ export class DefaultPackageManager {
|
|
|
1238
1339
|
return {
|
|
1239
1340
|
extensions: new Map(),
|
|
1240
1341
|
skills: new Map(),
|
|
1241
|
-
|
|
1342
|
+
commands: new Map(),
|
|
1242
1343
|
themes: new Map(),
|
|
1243
1344
|
};
|
|
1244
1345
|
}
|
|
@@ -1253,7 +1354,7 @@ export class DefaultPackageManager {
|
|
|
1253
1354
|
return {
|
|
1254
1355
|
extensions: toResolved(accumulator.extensions),
|
|
1255
1356
|
skills: toResolved(accumulator.skills),
|
|
1256
|
-
|
|
1357
|
+
commands: toResolved(accumulator.commands),
|
|
1257
1358
|
themes: toResolved(accumulator.themes),
|
|
1258
1359
|
};
|
|
1259
1360
|
}
|