@promptscript/cli 1.12.1 → 1.13.1
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/README.md +64 -35
- package/index.js +874 -378
- package/package.json +3 -2
- package/skills/promptscript/SKILL.md +6 -2
- package/src/cli.d.ts.map +1 -1
- package/src/commands/compile.d.ts.map +1 -1
- package/src/commands/skills.d.ts.map +1 -1
- package/src/prettier/index.d.ts +1 -0
- package/src/prettier/index.d.ts.map +1 -1
- package/src/prettier/post-format.d.ts +23 -0
- package/src/prettier/post-format.d.ts.map +1 -0
- package/src/types.d.ts +8 -0
- package/src/types.d.ts.map +1 -1
package/index.js
CHANGED
|
@@ -4,11 +4,20 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __getProtoOf = Object.getPrototypeOf;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __esm = (fn, res) => function __init() {
|
|
8
|
-
|
|
7
|
+
var __esm = (fn, res, err) => function __init() {
|
|
8
|
+
if (err) throw err[0];
|
|
9
|
+
try {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
} catch (e) {
|
|
12
|
+
throw err = [e], e;
|
|
13
|
+
}
|
|
9
14
|
};
|
|
10
15
|
var __commonJS = (cb, mod) => function __require() {
|
|
11
|
-
|
|
16
|
+
try {
|
|
17
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
+
} catch (e) {
|
|
19
|
+
throw mod = 0, e;
|
|
20
|
+
}
|
|
12
21
|
};
|
|
13
22
|
var __export = (target, all) => {
|
|
14
23
|
for (var name in all)
|
|
@@ -11760,6 +11769,14 @@ var init_base_formatter = __esm({
|
|
|
11760
11769
|
referencesMode() {
|
|
11761
11770
|
return "none";
|
|
11762
11771
|
}
|
|
11772
|
+
/**
|
|
11773
|
+
* Default pass-through for injected skill content. Formatters whose target
|
|
11774
|
+
* tools restrict skill frontmatter (e.g. Factory AI) override this hook to
|
|
11775
|
+
* filter unsupported fields before the compiler writes the file.
|
|
11776
|
+
*/
|
|
11777
|
+
transformInjectedSkillContent(content) {
|
|
11778
|
+
return content;
|
|
11779
|
+
}
|
|
11763
11780
|
/**
|
|
11764
11781
|
* Generate a provenance comment for a reference file.
|
|
11765
11782
|
*/
|
|
@@ -16365,6 +16382,24 @@ ${lines.join("\n")}
|
|
|
16365
16382
|
}
|
|
16366
16383
|
return filtered;
|
|
16367
16384
|
}
|
|
16385
|
+
/**
|
|
16386
|
+
* Filter the frontmatter of an externally-supplied SKILL.md file (such as
|
|
16387
|
+
* the bundled PromptScript skill injected by the compiler) so it only
|
|
16388
|
+
* contains fields Factory AI recognises. The body is preserved verbatim.
|
|
16389
|
+
* Files without a YAML frontmatter block are returned unchanged.
|
|
16390
|
+
*/
|
|
16391
|
+
transformInjectedSkillContent(content) {
|
|
16392
|
+
if (!content.startsWith("---")) return content;
|
|
16393
|
+
const closing = content.indexOf("\n---", 3);
|
|
16394
|
+
if (closing === -1) return content;
|
|
16395
|
+
const rawFrontmatter = content.slice(4, closing);
|
|
16396
|
+
const body = content.slice(closing + 4);
|
|
16397
|
+
const filteredLines = this.filterFactoryFrontmatter(rawFrontmatter);
|
|
16398
|
+
const filteredFrontmatter = filteredLines.join("\n");
|
|
16399
|
+
return `---
|
|
16400
|
+
${filteredFrontmatter}
|
|
16401
|
+
---${body}`;
|
|
16402
|
+
}
|
|
16368
16403
|
};
|
|
16369
16404
|
}
|
|
16370
16405
|
});
|
|
@@ -19863,9 +19898,9 @@ var require_dist = __commonJS({
|
|
|
19863
19898
|
}
|
|
19864
19899
|
});
|
|
19865
19900
|
|
|
19866
|
-
// node_modules/.pnpm/toad-cache@3.7.
|
|
19901
|
+
// node_modules/.pnpm/toad-cache@3.7.1/node_modules/toad-cache/dist/toad-cache.cjs
|
|
19867
19902
|
var require_toad_cache = __commonJS({
|
|
19868
|
-
"node_modules/.pnpm/toad-cache@3.7.
|
|
19903
|
+
"node_modules/.pnpm/toad-cache@3.7.1/node_modules/toad-cache/dist/toad-cache.cjs"(exports) {
|
|
19869
19904
|
"use strict";
|
|
19870
19905
|
var FifoMap = class {
|
|
19871
19906
|
constructor(max = 1e3, ttlInMsecs = 0) {
|
|
@@ -19976,6 +20011,155 @@ var require_toad_cache = __commonJS({
|
|
|
19976
20011
|
this.last = item;
|
|
19977
20012
|
}
|
|
19978
20013
|
};
|
|
20014
|
+
var FifoObject = class {
|
|
20015
|
+
constructor(max = 1e3, ttlInMsecs = 0) {
|
|
20016
|
+
if (isNaN(max) || max < 0) {
|
|
20017
|
+
throw new Error("Invalid max value");
|
|
20018
|
+
}
|
|
20019
|
+
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
|
|
20020
|
+
throw new Error("Invalid ttl value");
|
|
20021
|
+
}
|
|
20022
|
+
this.first = null;
|
|
20023
|
+
this.items = /* @__PURE__ */ Object.create(null);
|
|
20024
|
+
this.last = null;
|
|
20025
|
+
this.size = 0;
|
|
20026
|
+
this.max = max;
|
|
20027
|
+
this.ttl = ttlInMsecs;
|
|
20028
|
+
}
|
|
20029
|
+
clear() {
|
|
20030
|
+
this.items = /* @__PURE__ */ Object.create(null);
|
|
20031
|
+
this.first = null;
|
|
20032
|
+
this.last = null;
|
|
20033
|
+
this.size = 0;
|
|
20034
|
+
}
|
|
20035
|
+
delete(key) {
|
|
20036
|
+
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
|
|
20037
|
+
const deletedItem = this.items[key];
|
|
20038
|
+
delete this.items[key];
|
|
20039
|
+
this.size--;
|
|
20040
|
+
if (deletedItem.prev !== null) {
|
|
20041
|
+
deletedItem.prev.next = deletedItem.next;
|
|
20042
|
+
}
|
|
20043
|
+
if (deletedItem.next !== null) {
|
|
20044
|
+
deletedItem.next.prev = deletedItem.prev;
|
|
20045
|
+
}
|
|
20046
|
+
if (this.first === deletedItem) {
|
|
20047
|
+
this.first = deletedItem.next;
|
|
20048
|
+
}
|
|
20049
|
+
if (this.last === deletedItem) {
|
|
20050
|
+
this.last = deletedItem.prev;
|
|
20051
|
+
}
|
|
20052
|
+
}
|
|
20053
|
+
}
|
|
20054
|
+
deleteMany(keys) {
|
|
20055
|
+
for (var i = 0; i < keys.length; i++) {
|
|
20056
|
+
this.delete(keys[i]);
|
|
20057
|
+
}
|
|
20058
|
+
}
|
|
20059
|
+
evict() {
|
|
20060
|
+
if (this.size > 0) {
|
|
20061
|
+
const item = this.first;
|
|
20062
|
+
delete this.items[item.key];
|
|
20063
|
+
if (--this.size === 0) {
|
|
20064
|
+
this.first = null;
|
|
20065
|
+
this.last = null;
|
|
20066
|
+
} else {
|
|
20067
|
+
this.first = item.next;
|
|
20068
|
+
this.first.prev = null;
|
|
20069
|
+
}
|
|
20070
|
+
}
|
|
20071
|
+
}
|
|
20072
|
+
expiresAt(key) {
|
|
20073
|
+
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
|
|
20074
|
+
return this.items[key].expiry;
|
|
20075
|
+
}
|
|
20076
|
+
}
|
|
20077
|
+
get(key) {
|
|
20078
|
+
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
|
|
20079
|
+
const item = this.items[key];
|
|
20080
|
+
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
20081
|
+
this.delete(key);
|
|
20082
|
+
return;
|
|
20083
|
+
}
|
|
20084
|
+
return item.value;
|
|
20085
|
+
}
|
|
20086
|
+
}
|
|
20087
|
+
getMany(keys) {
|
|
20088
|
+
const result = [];
|
|
20089
|
+
for (var i = 0; i < keys.length; i++) {
|
|
20090
|
+
result.push(this.get(keys[i]));
|
|
20091
|
+
}
|
|
20092
|
+
return result;
|
|
20093
|
+
}
|
|
20094
|
+
keys() {
|
|
20095
|
+
return Object.keys(this.items);
|
|
20096
|
+
}
|
|
20097
|
+
set(key, value) {
|
|
20098
|
+
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
|
|
20099
|
+
const item2 = this.items[key];
|
|
20100
|
+
item2.value = value;
|
|
20101
|
+
item2.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
20102
|
+
return;
|
|
20103
|
+
}
|
|
20104
|
+
if (this.max > 0 && this.size === this.max) {
|
|
20105
|
+
this.evict();
|
|
20106
|
+
}
|
|
20107
|
+
const item = {
|
|
20108
|
+
expiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,
|
|
20109
|
+
key,
|
|
20110
|
+
prev: this.last,
|
|
20111
|
+
next: null,
|
|
20112
|
+
value
|
|
20113
|
+
};
|
|
20114
|
+
this.items[key] = item;
|
|
20115
|
+
if (++this.size === 1) {
|
|
20116
|
+
this.first = item;
|
|
20117
|
+
} else {
|
|
20118
|
+
this.last.next = item;
|
|
20119
|
+
}
|
|
20120
|
+
this.last = item;
|
|
20121
|
+
}
|
|
20122
|
+
};
|
|
20123
|
+
var HitStatisticsRecord = class {
|
|
20124
|
+
constructor() {
|
|
20125
|
+
this.records = {};
|
|
20126
|
+
}
|
|
20127
|
+
initForCache(cacheId, currentTimeStamp) {
|
|
20128
|
+
this.records[cacheId] = {
|
|
20129
|
+
[currentTimeStamp]: {
|
|
20130
|
+
cacheSize: 0,
|
|
20131
|
+
hits: 0,
|
|
20132
|
+
falsyHits: 0,
|
|
20133
|
+
emptyHits: 0,
|
|
20134
|
+
misses: 0,
|
|
20135
|
+
expirations: 0,
|
|
20136
|
+
evictions: 0,
|
|
20137
|
+
invalidateOne: 0,
|
|
20138
|
+
invalidateAll: 0,
|
|
20139
|
+
sets: 0
|
|
20140
|
+
}
|
|
20141
|
+
};
|
|
20142
|
+
}
|
|
20143
|
+
resetForCache(cacheId) {
|
|
20144
|
+
for (let key of Object.keys(this.records[cacheId])) {
|
|
20145
|
+
this.records[cacheId][key] = {
|
|
20146
|
+
cacheSize: 0,
|
|
20147
|
+
hits: 0,
|
|
20148
|
+
falsyHits: 0,
|
|
20149
|
+
emptyHits: 0,
|
|
20150
|
+
misses: 0,
|
|
20151
|
+
expirations: 0,
|
|
20152
|
+
evictions: 0,
|
|
20153
|
+
invalidateOne: 0,
|
|
20154
|
+
invalidateAll: 0,
|
|
20155
|
+
sets: 0
|
|
20156
|
+
};
|
|
20157
|
+
}
|
|
20158
|
+
}
|
|
20159
|
+
getStatistics() {
|
|
20160
|
+
return this.records;
|
|
20161
|
+
}
|
|
20162
|
+
};
|
|
19979
20163
|
var LruMap = class {
|
|
19980
20164
|
constructor(max = 1e3, ttlInMsecs = 0) {
|
|
19981
20165
|
if (isNaN(max) || max < 0) {
|
|
@@ -20244,46 +20428,6 @@ var require_toad_cache = __commonJS({
|
|
|
20244
20428
|
this.last = item;
|
|
20245
20429
|
}
|
|
20246
20430
|
};
|
|
20247
|
-
var HitStatisticsRecord = class {
|
|
20248
|
-
constructor() {
|
|
20249
|
-
this.records = {};
|
|
20250
|
-
}
|
|
20251
|
-
initForCache(cacheId, currentTimeStamp) {
|
|
20252
|
-
this.records[cacheId] = {
|
|
20253
|
-
[currentTimeStamp]: {
|
|
20254
|
-
cacheSize: 0,
|
|
20255
|
-
hits: 0,
|
|
20256
|
-
falsyHits: 0,
|
|
20257
|
-
emptyHits: 0,
|
|
20258
|
-
misses: 0,
|
|
20259
|
-
expirations: 0,
|
|
20260
|
-
evictions: 0,
|
|
20261
|
-
invalidateOne: 0,
|
|
20262
|
-
invalidateAll: 0,
|
|
20263
|
-
sets: 0
|
|
20264
|
-
}
|
|
20265
|
-
};
|
|
20266
|
-
}
|
|
20267
|
-
resetForCache(cacheId) {
|
|
20268
|
-
for (let key of Object.keys(this.records[cacheId])) {
|
|
20269
|
-
this.records[cacheId][key] = {
|
|
20270
|
-
cacheSize: 0,
|
|
20271
|
-
hits: 0,
|
|
20272
|
-
falsyHits: 0,
|
|
20273
|
-
emptyHits: 0,
|
|
20274
|
-
misses: 0,
|
|
20275
|
-
expirations: 0,
|
|
20276
|
-
evictions: 0,
|
|
20277
|
-
invalidateOne: 0,
|
|
20278
|
-
invalidateAll: 0,
|
|
20279
|
-
sets: 0
|
|
20280
|
-
};
|
|
20281
|
-
}
|
|
20282
|
-
}
|
|
20283
|
-
getStatistics() {
|
|
20284
|
-
return this.records;
|
|
20285
|
-
}
|
|
20286
|
-
};
|
|
20287
20431
|
function getTimestamp(date) {
|
|
20288
20432
|
return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`;
|
|
20289
20433
|
}
|
|
@@ -20425,115 +20569,6 @@ var require_toad_cache = __commonJS({
|
|
|
20425
20569
|
this.hitStatistics.addMiss();
|
|
20426
20570
|
}
|
|
20427
20571
|
};
|
|
20428
|
-
var FifoObject = class {
|
|
20429
|
-
constructor(max = 1e3, ttlInMsecs = 0) {
|
|
20430
|
-
if (isNaN(max) || max < 0) {
|
|
20431
|
-
throw new Error("Invalid max value");
|
|
20432
|
-
}
|
|
20433
|
-
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
|
|
20434
|
-
throw new Error("Invalid ttl value");
|
|
20435
|
-
}
|
|
20436
|
-
this.first = null;
|
|
20437
|
-
this.items = /* @__PURE__ */ Object.create(null);
|
|
20438
|
-
this.last = null;
|
|
20439
|
-
this.size = 0;
|
|
20440
|
-
this.max = max;
|
|
20441
|
-
this.ttl = ttlInMsecs;
|
|
20442
|
-
}
|
|
20443
|
-
clear() {
|
|
20444
|
-
this.items = /* @__PURE__ */ Object.create(null);
|
|
20445
|
-
this.first = null;
|
|
20446
|
-
this.last = null;
|
|
20447
|
-
this.size = 0;
|
|
20448
|
-
}
|
|
20449
|
-
delete(key) {
|
|
20450
|
-
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
|
|
20451
|
-
const deletedItem = this.items[key];
|
|
20452
|
-
delete this.items[key];
|
|
20453
|
-
this.size--;
|
|
20454
|
-
if (deletedItem.prev !== null) {
|
|
20455
|
-
deletedItem.prev.next = deletedItem.next;
|
|
20456
|
-
}
|
|
20457
|
-
if (deletedItem.next !== null) {
|
|
20458
|
-
deletedItem.next.prev = deletedItem.prev;
|
|
20459
|
-
}
|
|
20460
|
-
if (this.first === deletedItem) {
|
|
20461
|
-
this.first = deletedItem.next;
|
|
20462
|
-
}
|
|
20463
|
-
if (this.last === deletedItem) {
|
|
20464
|
-
this.last = deletedItem.prev;
|
|
20465
|
-
}
|
|
20466
|
-
}
|
|
20467
|
-
}
|
|
20468
|
-
deleteMany(keys) {
|
|
20469
|
-
for (var i = 0; i < keys.length; i++) {
|
|
20470
|
-
this.delete(keys[i]);
|
|
20471
|
-
}
|
|
20472
|
-
}
|
|
20473
|
-
evict() {
|
|
20474
|
-
if (this.size > 0) {
|
|
20475
|
-
const item = this.first;
|
|
20476
|
-
delete this.items[item.key];
|
|
20477
|
-
if (--this.size === 0) {
|
|
20478
|
-
this.first = null;
|
|
20479
|
-
this.last = null;
|
|
20480
|
-
} else {
|
|
20481
|
-
this.first = item.next;
|
|
20482
|
-
this.first.prev = null;
|
|
20483
|
-
}
|
|
20484
|
-
}
|
|
20485
|
-
}
|
|
20486
|
-
expiresAt(key) {
|
|
20487
|
-
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
|
|
20488
|
-
return this.items[key].expiry;
|
|
20489
|
-
}
|
|
20490
|
-
}
|
|
20491
|
-
get(key) {
|
|
20492
|
-
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
|
|
20493
|
-
const item = this.items[key];
|
|
20494
|
-
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
20495
|
-
this.delete(key);
|
|
20496
|
-
return;
|
|
20497
|
-
}
|
|
20498
|
-
return item.value;
|
|
20499
|
-
}
|
|
20500
|
-
}
|
|
20501
|
-
getMany(keys) {
|
|
20502
|
-
const result = [];
|
|
20503
|
-
for (var i = 0; i < keys.length; i++) {
|
|
20504
|
-
result.push(this.get(keys[i]));
|
|
20505
|
-
}
|
|
20506
|
-
return result;
|
|
20507
|
-
}
|
|
20508
|
-
keys() {
|
|
20509
|
-
return Object.keys(this.items);
|
|
20510
|
-
}
|
|
20511
|
-
set(key, value) {
|
|
20512
|
-
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
|
|
20513
|
-
const item2 = this.items[key];
|
|
20514
|
-
item2.value = value;
|
|
20515
|
-
item2.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
20516
|
-
return;
|
|
20517
|
-
}
|
|
20518
|
-
if (this.max > 0 && this.size === this.max) {
|
|
20519
|
-
this.evict();
|
|
20520
|
-
}
|
|
20521
|
-
const item = {
|
|
20522
|
-
expiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,
|
|
20523
|
-
key,
|
|
20524
|
-
prev: this.last,
|
|
20525
|
-
next: null,
|
|
20526
|
-
value
|
|
20527
|
-
};
|
|
20528
|
-
this.items[key] = item;
|
|
20529
|
-
if (++this.size === 1) {
|
|
20530
|
-
this.first = item;
|
|
20531
|
-
} else {
|
|
20532
|
-
this.last.next = item;
|
|
20533
|
-
}
|
|
20534
|
-
this.last = item;
|
|
20535
|
-
}
|
|
20536
|
-
};
|
|
20537
20572
|
exports.Fifo = FifoObject;
|
|
20538
20573
|
exports.FifoMap = FifoMap;
|
|
20539
20574
|
exports.FifoObject = FifoObject;
|
|
@@ -20546,9 +20581,9 @@ var require_toad_cache = __commonJS({
|
|
|
20546
20581
|
}
|
|
20547
20582
|
});
|
|
20548
20583
|
|
|
20549
|
-
// node_modules/.pnpm/@fastify+rate-limit@
|
|
20584
|
+
// node_modules/.pnpm/@fastify+rate-limit@11.0.0/node_modules/@fastify/rate-limit/store/LocalStore.js
|
|
20550
20585
|
var require_LocalStore = __commonJS({
|
|
20551
|
-
"node_modules/.pnpm/@fastify+rate-limit@
|
|
20586
|
+
"node_modules/.pnpm/@fastify+rate-limit@11.0.0/node_modules/@fastify/rate-limit/store/LocalStore.js"(exports, module) {
|
|
20552
20587
|
"use strict";
|
|
20553
20588
|
var { LruMap: Lru } = require_toad_cache();
|
|
20554
20589
|
function LocalStore(continueExceeding, exponentialBackoff, cache = 5e3) {
|
|
@@ -20589,9 +20624,9 @@ var require_LocalStore = __commonJS({
|
|
|
20589
20624
|
}
|
|
20590
20625
|
});
|
|
20591
20626
|
|
|
20592
|
-
// node_modules/.pnpm/@fastify+rate-limit@
|
|
20627
|
+
// node_modules/.pnpm/@fastify+rate-limit@11.0.0/node_modules/@fastify/rate-limit/store/RedisStore.js
|
|
20593
20628
|
var require_RedisStore = __commonJS({
|
|
20594
|
-
"node_modules/.pnpm/@fastify+rate-limit@
|
|
20629
|
+
"node_modules/.pnpm/@fastify+rate-limit@11.0.0/node_modules/@fastify/rate-limit/store/RedisStore.js"(exports, module) {
|
|
20595
20630
|
"use strict";
|
|
20596
20631
|
var lua = `
|
|
20597
20632
|
-- Key to operate on
|
|
@@ -20647,9 +20682,9 @@ var require_RedisStore = __commonJS({
|
|
|
20647
20682
|
}
|
|
20648
20683
|
});
|
|
20649
20684
|
|
|
20650
|
-
// node_modules/.pnpm/@fastify+rate-limit@
|
|
20685
|
+
// node_modules/.pnpm/@fastify+rate-limit@11.0.0/node_modules/@fastify/rate-limit/index.js
|
|
20651
20686
|
var require_rate_limit = __commonJS({
|
|
20652
|
-
"node_modules/.pnpm/@fastify+rate-limit@
|
|
20687
|
+
"node_modules/.pnpm/@fastify+rate-limit@11.0.0/node_modules/@fastify/rate-limit/index.js"(exports, module) {
|
|
20653
20688
|
"use strict";
|
|
20654
20689
|
var fp = require_plugin();
|
|
20655
20690
|
var { parse: parse2, format: format2 } = require_dist();
|
|
@@ -20717,7 +20752,7 @@ var require_rate_limit = __commonJS({
|
|
|
20717
20752
|
globalParams.timeWindow = defaultTimeWindow;
|
|
20718
20753
|
}
|
|
20719
20754
|
globalParams.hook = settings.hook || defaultHook;
|
|
20720
|
-
globalParams.allowList = settings.allowList ||
|
|
20755
|
+
globalParams.allowList = settings.allowList || null;
|
|
20721
20756
|
globalParams.ban = Number.isFinite(settings.ban) && settings.ban >= 0 ? Math.trunc(settings.ban) : -1;
|
|
20722
20757
|
globalParams.onBanReach = typeof settings.onBanReach === "function" ? settings.onBanReach : defaultOnFn;
|
|
20723
20758
|
globalParams.onExceeding = typeof settings.onExceeding === "function" ? settings.onExceeding : defaultOnFn;
|
|
@@ -20847,9 +20882,9 @@ var require_rate_limit = __commonJS({
|
|
|
20847
20882
|
let ttl = 0;
|
|
20848
20883
|
let ttlInSeconds = 0;
|
|
20849
20884
|
try {
|
|
20850
|
-
const res = await new Promise((
|
|
20885
|
+
const res = await new Promise((resolve22, reject) => {
|
|
20851
20886
|
store.incr(key, (err, res2) => {
|
|
20852
|
-
err ? reject(err) :
|
|
20887
|
+
err ? reject(err) : resolve22(res2);
|
|
20853
20888
|
}, timeWindow, max);
|
|
20854
20889
|
});
|
|
20855
20890
|
current = res.current;
|
|
@@ -20956,12 +20991,12 @@ var init_health = __esm({
|
|
|
20956
20991
|
|
|
20957
20992
|
// packages/server/src/source-dirs.ts
|
|
20958
20993
|
import { readFile as readFile24 } from "fs/promises";
|
|
20959
|
-
import { join as
|
|
20994
|
+
import { join as join23, dirname as dirname14 } from "path";
|
|
20960
20995
|
import { parse as parseYaml13 } from "yaml";
|
|
20961
20996
|
async function readProjectConfig(workspace) {
|
|
20962
20997
|
for (const filename of CONFIG_FILENAMES) {
|
|
20963
20998
|
try {
|
|
20964
|
-
const raw = await readFile24(
|
|
20999
|
+
const raw = await readFile24(join23(workspace, filename), "utf-8");
|
|
20965
21000
|
const config = parseYaml13(raw);
|
|
20966
21001
|
if (config) return config;
|
|
20967
21002
|
} catch {
|
|
@@ -20972,10 +21007,10 @@ async function readProjectConfig(workspace) {
|
|
|
20972
21007
|
async function resolveSourceDir(workspace) {
|
|
20973
21008
|
for (const filename of CONFIG_FILENAMES) {
|
|
20974
21009
|
try {
|
|
20975
|
-
const raw = await readFile24(
|
|
21010
|
+
const raw = await readFile24(join23(workspace, filename), "utf-8");
|
|
20976
21011
|
const config = parseYaml13(raw);
|
|
20977
21012
|
if (config?.input?.entry) {
|
|
20978
|
-
return
|
|
21013
|
+
return dirname14(config.input.entry);
|
|
20979
21014
|
}
|
|
20980
21015
|
} catch {
|
|
20981
21016
|
}
|
|
@@ -20989,9 +21024,9 @@ async function resolveFileGlobs(workspace) {
|
|
|
20989
21024
|
async function resolveWatchPaths(workspace) {
|
|
20990
21025
|
const sourceDir = await resolveSourceDir(workspace);
|
|
20991
21026
|
return [
|
|
20992
|
-
|
|
20993
|
-
|
|
20994
|
-
|
|
21027
|
+
join23(workspace, sourceDir),
|
|
21028
|
+
join23(workspace, "promptscript.yaml"),
|
|
21029
|
+
join23(workspace, "promptscript.yml")
|
|
20995
21030
|
];
|
|
20996
21031
|
}
|
|
20997
21032
|
var DEFAULT_SOURCE_DIR, CONFIG_FILENAMES;
|
|
@@ -21018,13 +21053,13 @@ var init_config2 = __esm({
|
|
|
21018
21053
|
});
|
|
21019
21054
|
|
|
21020
21055
|
// packages/server/src/path-guard.ts
|
|
21021
|
-
import { resolve as
|
|
21056
|
+
import { resolve as resolve21, relative as relative4, isAbsolute as isAbsolute6 } from "path";
|
|
21022
21057
|
function resolveSafePath(workspace, requestedPath) {
|
|
21023
21058
|
const decoded = decodeURIComponent(requestedPath);
|
|
21024
21059
|
if (isAbsolute6(decoded)) {
|
|
21025
21060
|
throw new PathTraversalError(requestedPath);
|
|
21026
21061
|
}
|
|
21027
|
-
const resolved =
|
|
21062
|
+
const resolved = resolve21(workspace, decoded);
|
|
21028
21063
|
const rel = relative4(workspace, resolved);
|
|
21029
21064
|
if (rel.startsWith("..") || isAbsolute6(rel)) {
|
|
21030
21065
|
throw new PathTraversalError(requestedPath);
|
|
@@ -21046,7 +21081,7 @@ var init_path_guard = __esm({
|
|
|
21046
21081
|
|
|
21047
21082
|
// packages/server/src/routes/files.ts
|
|
21048
21083
|
import { readFile as readFile25, writeFile as writeFile13, unlink as unlink2, stat as stat3, mkdir as mkdir10 } from "fs/promises";
|
|
21049
|
-
import { dirname as
|
|
21084
|
+
import { dirname as dirname15 } from "path";
|
|
21050
21085
|
import fg from "fast-glob";
|
|
21051
21086
|
function registerRoutes(app, workspace, readOnly) {
|
|
21052
21087
|
app.get("/api/files", async () => {
|
|
@@ -21106,7 +21141,7 @@ function registerRoutes(app, workspace, readOnly) {
|
|
|
21106
21141
|
return reply.status(409).send({ error: "File already exists" });
|
|
21107
21142
|
} catch {
|
|
21108
21143
|
}
|
|
21109
|
-
await mkdir10(
|
|
21144
|
+
await mkdir10(dirname15(resolved), { recursive: true });
|
|
21110
21145
|
await writeFile13(resolved, request.body.content, "utf-8");
|
|
21111
21146
|
return reply.status(201).send({ path: filePath, status: "created" });
|
|
21112
21147
|
} catch (err) {
|
|
@@ -21332,14 +21367,14 @@ init_src();
|
|
|
21332
21367
|
init_init();
|
|
21333
21368
|
import { Command } from "commander";
|
|
21334
21369
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
21335
|
-
import { dirname as
|
|
21370
|
+
import { dirname as dirname16 } from "path";
|
|
21336
21371
|
|
|
21337
21372
|
// packages/cli/src/commands/compile.ts
|
|
21338
21373
|
init_src();
|
|
21339
|
-
import { resolve as
|
|
21374
|
+
import { resolve as resolve8, dirname as dirname9, isAbsolute as isAbsolute5 } from "path";
|
|
21340
21375
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
21341
21376
|
import { writeFile as writeFile4, mkdir as mkdir4, readFile as readFile12 } from "fs/promises";
|
|
21342
|
-
import { existsSync as
|
|
21377
|
+
import { existsSync as existsSync12 } from "fs";
|
|
21343
21378
|
import chokidar from "chokidar";
|
|
21344
21379
|
|
|
21345
21380
|
// packages/cli/src/config/loader.ts
|
|
@@ -21403,6 +21438,56 @@ async function loadConfig(customPath) {
|
|
|
21403
21438
|
|
|
21404
21439
|
// packages/cli/src/commands/compile.ts
|
|
21405
21440
|
init_loader();
|
|
21441
|
+
|
|
21442
|
+
// packages/cli/src/prettier/post-format.ts
|
|
21443
|
+
import { resolve as resolve4 } from "path";
|
|
21444
|
+
var MARKDOWN_RE = /\.(md|mdx|markdown)$/i;
|
|
21445
|
+
async function postFormatWithPrettier(outputs, projectRoot, logger) {
|
|
21446
|
+
let prettier;
|
|
21447
|
+
try {
|
|
21448
|
+
prettier = await import("prettier");
|
|
21449
|
+
} catch {
|
|
21450
|
+
logger.verbose("Prettier not available; skipping markdown post-format.");
|
|
21451
|
+
return;
|
|
21452
|
+
}
|
|
21453
|
+
const queue = [];
|
|
21454
|
+
for (const output of outputs.values()) {
|
|
21455
|
+
collectOutputs(output, queue);
|
|
21456
|
+
}
|
|
21457
|
+
for (const output of queue) {
|
|
21458
|
+
if (!MARKDOWN_RE.test(output.path)) continue;
|
|
21459
|
+
const absPath = resolve4(projectRoot, output.path);
|
|
21460
|
+
let config = null;
|
|
21461
|
+
try {
|
|
21462
|
+
config = await prettier.resolveConfig(absPath);
|
|
21463
|
+
} catch (err) {
|
|
21464
|
+
logger.verbose(
|
|
21465
|
+
`Could not resolve Prettier config for ${output.path}: ${err instanceof Error ? err.message : String(err)}`
|
|
21466
|
+
);
|
|
21467
|
+
}
|
|
21468
|
+
try {
|
|
21469
|
+
output.content = await prettier.format(output.content, {
|
|
21470
|
+
...config ?? {},
|
|
21471
|
+
filepath: absPath,
|
|
21472
|
+
parser: "markdown"
|
|
21473
|
+
});
|
|
21474
|
+
} catch (err) {
|
|
21475
|
+
logger.verbose(
|
|
21476
|
+
`Prettier rejected ${output.path}: ${err instanceof Error ? err.message : String(err)}`
|
|
21477
|
+
);
|
|
21478
|
+
}
|
|
21479
|
+
}
|
|
21480
|
+
}
|
|
21481
|
+
function collectOutputs(output, into) {
|
|
21482
|
+
into.push(output);
|
|
21483
|
+
if (output.additionalFiles) {
|
|
21484
|
+
for (const child of output.additionalFiles) {
|
|
21485
|
+
collectOutputs(child, into);
|
|
21486
|
+
}
|
|
21487
|
+
}
|
|
21488
|
+
}
|
|
21489
|
+
|
|
21490
|
+
// packages/cli/src/commands/compile.ts
|
|
21406
21491
|
init_console();
|
|
21407
21492
|
|
|
21408
21493
|
// packages/compiler/src/compiler.ts
|
|
@@ -21419,7 +21504,7 @@ import { basename as basename11, dirname as dirname7, join as join8 } from "path
|
|
|
21419
21504
|
// packages/resolver/src/loader.ts
|
|
21420
21505
|
init_src();
|
|
21421
21506
|
import { readFile as readFile7 } from "fs/promises";
|
|
21422
|
-
import { resolve as
|
|
21507
|
+
import { resolve as resolve5, dirname as dirname5, basename as basename7, isAbsolute as isAbsolute2, relative } from "path";
|
|
21423
21508
|
|
|
21424
21509
|
// packages/resolver/src/alias-resolver.ts
|
|
21425
21510
|
init_src();
|
|
@@ -21509,8 +21594,8 @@ var FileLoader = class {
|
|
|
21509
21594
|
options;
|
|
21510
21595
|
constructor(options) {
|
|
21511
21596
|
this.registryPath = options.registryPath;
|
|
21512
|
-
this.localPath =
|
|
21513
|
-
this.projectRoot =
|
|
21597
|
+
this.localPath = resolve5(options.localPath ?? process.cwd());
|
|
21598
|
+
this.projectRoot = resolve5(
|
|
21514
21599
|
options.projectRoot ?? (basename7(this.localPath) === ".promptscript" ? dirname5(this.localPath) : this.localPath)
|
|
21515
21600
|
);
|
|
21516
21601
|
this.options = options;
|
|
@@ -21553,11 +21638,11 @@ var FileLoader = class {
|
|
|
21553
21638
|
const namespace = match[1];
|
|
21554
21639
|
const segments = match[2];
|
|
21555
21640
|
const fileName2 = segments.endsWith(".prs") || segments.endsWith(".md") ? segments : `${segments}.prs`;
|
|
21556
|
-
return
|
|
21641
|
+
return resolve5(this.registryPath, `@${namespace}`, fileName2);
|
|
21557
21642
|
}
|
|
21558
21643
|
}
|
|
21559
21644
|
const fileName = path.endsWith(".prs") || path.endsWith(".md") ? path : `${path}.prs`;
|
|
21560
|
-
return
|
|
21645
|
+
return resolve5(this.localPath, fileName);
|
|
21561
21646
|
}
|
|
21562
21647
|
/**
|
|
21563
21648
|
* Resolve a PathReference to an absolute path.
|
|
@@ -21570,7 +21655,7 @@ var FileLoader = class {
|
|
|
21570
21655
|
if (ref.isRelative) {
|
|
21571
21656
|
const dir = dirname5(fromFile);
|
|
21572
21657
|
const rawPath = ref.raw.endsWith(".prs") || ref.raw.endsWith(".md") ? ref.raw : `${ref.raw}.prs`;
|
|
21573
|
-
const resolved =
|
|
21658
|
+
const resolved = resolve5(dir, rawPath);
|
|
21574
21659
|
const rel = relative(this.projectRoot, resolved);
|
|
21575
21660
|
if (rel.startsWith("..") || isAbsolute2(rel)) {
|
|
21576
21661
|
throw new Error(`Path traversal outside project root is not allowed: ${ref.raw}`);
|
|
@@ -22511,7 +22596,7 @@ function uniqueConcat3(parent, child) {
|
|
|
22511
22596
|
// packages/resolver/src/skills.ts
|
|
22512
22597
|
init_src();
|
|
22513
22598
|
import { readFile as readFile8, readdir as readdir2, access, lstat, realpath } from "fs/promises";
|
|
22514
|
-
import { basename as basename8, resolve as
|
|
22599
|
+
import { basename as basename8, resolve as resolve6, dirname as dirname6, relative as relative2, normalize as normalize2, isAbsolute as isAbsolute3, sep as sep2 } from "path";
|
|
22515
22600
|
function parseSkillMd(content) {
|
|
22516
22601
|
const lines = content.split("\n");
|
|
22517
22602
|
let inFrontmatter = false;
|
|
@@ -22957,10 +23042,10 @@ function parseSkillIgnore(content) {
|
|
|
22957
23042
|
return { patterns };
|
|
22958
23043
|
}
|
|
22959
23044
|
function isIgnoredByRules(relPath, rules) {
|
|
22960
|
-
const
|
|
23045
|
+
const basename16 = relPath.split("/").pop() ?? relPath;
|
|
22961
23046
|
let ignored = false;
|
|
22962
23047
|
for (const { regex, matchPath, negated } of rules.patterns) {
|
|
22963
|
-
const target = matchPath ? relPath :
|
|
23048
|
+
const target = matchPath ? relPath : basename16;
|
|
22964
23049
|
if (regex.test(target)) {
|
|
22965
23050
|
ignored = !negated;
|
|
22966
23051
|
}
|
|
@@ -22968,7 +23053,7 @@ function isIgnoredByRules(relPath, rules) {
|
|
|
22968
23053
|
return ignored;
|
|
22969
23054
|
}
|
|
22970
23055
|
async function loadSkillIgnore(skillDir) {
|
|
22971
|
-
const ignorePath =
|
|
23056
|
+
const ignorePath = resolve6(skillDir, ".skillignore");
|
|
22972
23057
|
try {
|
|
22973
23058
|
const content = await readFile8(ignorePath, "utf-8");
|
|
22974
23059
|
return parseSkillIgnore(content);
|
|
@@ -23014,7 +23099,7 @@ async function discoverSkillResources(skillDir, logger = noopLogger2) {
|
|
|
23014
23099
|
}
|
|
23015
23100
|
if (entry.isSymbolicLink()) continue;
|
|
23016
23101
|
if (SKIP_FILES.has(entry.name)) continue;
|
|
23017
|
-
const fullPath =
|
|
23102
|
+
const fullPath = resolve6(entry.parentPath, entry.name);
|
|
23018
23103
|
const relPath = relative2(skillDir, fullPath);
|
|
23019
23104
|
const relPathNormalized = relPath.split(sep2).join("/");
|
|
23020
23105
|
const pathSegments = relPath.split(sep2);
|
|
@@ -23073,7 +23158,7 @@ async function resolveSkillReferences(references, basePath, logger) {
|
|
|
23073
23158
|
column: 0
|
|
23074
23159
|
});
|
|
23075
23160
|
}
|
|
23076
|
-
const fullPath =
|
|
23161
|
+
const fullPath = resolve6(basePath, ref);
|
|
23077
23162
|
let content;
|
|
23078
23163
|
try {
|
|
23079
23164
|
content = await readFile8(fullPath, "utf-8");
|
|
@@ -23145,8 +23230,8 @@ async function discoverSkillDirs(basePath) {
|
|
|
23145
23230
|
if (!entry.isDirectory()) continue;
|
|
23146
23231
|
if (SKIP_DIRS.has(entry.name)) continue;
|
|
23147
23232
|
if (!isSafeSkillName(entry.name)) continue;
|
|
23148
|
-
const subDir =
|
|
23149
|
-
const skillMd =
|
|
23233
|
+
const subDir = resolve6(dir, entry.name);
|
|
23234
|
+
const skillMd = resolve6(subDir, "SKILL.md");
|
|
23150
23235
|
if (await fileExists(skillMd)) {
|
|
23151
23236
|
if (!result.has(entry.name)) {
|
|
23152
23237
|
result.set(entry.name, subDir);
|
|
@@ -23173,9 +23258,9 @@ async function resolveNativeSkills(ast, registryPath, sourceFile, localPath, opt
|
|
|
23173
23258
|
const isSkillsDir = sourceDir.includes("@skills") || sourceDir.endsWith("/skills");
|
|
23174
23259
|
const discoveredSkillPaths = /* @__PURE__ */ new Map();
|
|
23175
23260
|
if (!isSkillsDir && localPath) {
|
|
23176
|
-
const discoveryDirs = [
|
|
23261
|
+
const discoveryDirs = [resolve6(localPath, "skills")];
|
|
23177
23262
|
if (options?.universalDir && localPath) {
|
|
23178
|
-
discoveryDirs.push(
|
|
23263
|
+
discoveryDirs.push(resolve6(localPath, "..", options.universalDir, "skills"));
|
|
23179
23264
|
}
|
|
23180
23265
|
for (const dir of discoveryDirs) {
|
|
23181
23266
|
const discovered = await discoverSkillDirs(dir);
|
|
@@ -23196,7 +23281,7 @@ async function resolveNativeSkills(ast, registryPath, sourceFile, localPath, opt
|
|
|
23196
23281
|
}
|
|
23197
23282
|
let sharedResources = [];
|
|
23198
23283
|
if (localPath) {
|
|
23199
|
-
const sharedDir =
|
|
23284
|
+
const sharedDir = resolve6(localPath, "shared");
|
|
23200
23285
|
if (await fileExists(sharedDir)) {
|
|
23201
23286
|
try {
|
|
23202
23287
|
sharedResources = await discoverSkillResources(sharedDir, logger);
|
|
@@ -23217,12 +23302,12 @@ async function resolveNativeSkills(ast, registryPath, sourceFile, localPath, opt
|
|
|
23217
23302
|
continue;
|
|
23218
23303
|
}
|
|
23219
23304
|
const skillObj = skillValue;
|
|
23220
|
-
const skillMdPath = isSkillsDir ?
|
|
23305
|
+
const skillMdPath = isSkillsDir ? resolve6(sourceDir, skillName, "SKILL.md") : await (async () => {
|
|
23221
23306
|
const discoveredDir = discoveredSkillPaths.get(skillName);
|
|
23222
|
-
if (discoveredDir) return
|
|
23223
|
-
const localCandidate = localPath ?
|
|
23224
|
-
const universalCandidate = options?.universalDir && localPath ?
|
|
23225
|
-
const registryCandidate =
|
|
23307
|
+
if (discoveredDir) return resolve6(discoveredDir, "SKILL.md");
|
|
23308
|
+
const localCandidate = localPath ? resolve6(localPath, "skills", skillName, "SKILL.md") : null;
|
|
23309
|
+
const universalCandidate = options?.universalDir && localPath ? resolve6(localPath, "..", options.universalDir, "skills", skillName, "SKILL.md") : null;
|
|
23310
|
+
const registryCandidate = resolve6(registryPath, "@skills", skillName, "SKILL.md");
|
|
23226
23311
|
if (localCandidate && await fileExists(localCandidate)) return localCandidate;
|
|
23227
23312
|
if (universalCandidate && await fileExists(universalCandidate))
|
|
23228
23313
|
return universalCandidate;
|
|
@@ -23312,7 +23397,7 @@ async function discoverCommandFiles(dir, logger = noopLogger2) {
|
|
|
23312
23397
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
23313
23398
|
if (entry.isSymbolicLink()) continue;
|
|
23314
23399
|
const cmdName = "/" + entry.name.replace(/\.md$/, "");
|
|
23315
|
-
const fullPath =
|
|
23400
|
+
const fullPath = resolve6(dir, entry.name);
|
|
23316
23401
|
try {
|
|
23317
23402
|
const fileStat = await lstat(fullPath);
|
|
23318
23403
|
if (fileStat.isSymbolicLink()) continue;
|
|
@@ -23343,11 +23428,11 @@ async function resolveNativeCommands(ast, sourceFile, localPath, options) {
|
|
|
23343
23428
|
if (!localPath) return ast;
|
|
23344
23429
|
const logger = options?.logger ?? noopLogger2;
|
|
23345
23430
|
const allCommands = {};
|
|
23346
|
-
const localCommands = await discoverCommandFiles(
|
|
23431
|
+
const localCommands = await discoverCommandFiles(resolve6(localPath, "commands"), logger);
|
|
23347
23432
|
Object.assign(allCommands, localCommands);
|
|
23348
23433
|
if (options?.universalDir) {
|
|
23349
23434
|
const universalCommands = await discoverCommandFiles(
|
|
23350
|
-
|
|
23435
|
+
resolve6(localPath, "..", options.universalDir, "commands"),
|
|
23351
23436
|
logger
|
|
23352
23437
|
);
|
|
23353
23438
|
for (const [name, value] of Object.entries(universalCommands)) {
|
|
@@ -23428,7 +23513,7 @@ async function discoverAgentFiles(dir, logger = noopLogger2) {
|
|
|
23428
23513
|
for (const entry of entries) {
|
|
23429
23514
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
23430
23515
|
if (entry.isSymbolicLink()) continue;
|
|
23431
|
-
const fullPath =
|
|
23516
|
+
const fullPath = resolve6(dir, entry.name);
|
|
23432
23517
|
try {
|
|
23433
23518
|
const fileStat = await lstat(fullPath);
|
|
23434
23519
|
if (fileStat.isSymbolicLink()) continue;
|
|
@@ -23492,11 +23577,11 @@ async function resolveNativeAgents(ast, sourceFile, localPath, options) {
|
|
|
23492
23577
|
if (!localPath) return ast;
|
|
23493
23578
|
const logger = options?.logger ?? noopLogger2;
|
|
23494
23579
|
const allAgents = {};
|
|
23495
|
-
const localAgents = await discoverAgentFiles(
|
|
23580
|
+
const localAgents = await discoverAgentFiles(resolve6(localPath, "agents"), logger);
|
|
23496
23581
|
Object.assign(allAgents, localAgents);
|
|
23497
23582
|
if (options?.universalDir) {
|
|
23498
23583
|
const universalAgents = await discoverAgentFiles(
|
|
23499
|
-
|
|
23584
|
+
resolve6(localPath, "..", options.universalDir, "agents"),
|
|
23500
23585
|
logger
|
|
23501
23586
|
);
|
|
23502
23587
|
for (const [name, value] of Object.entries(universalAgents)) {
|
|
@@ -25124,7 +25209,7 @@ var RegistryCache = class {
|
|
|
25124
25209
|
|
|
25125
25210
|
// packages/resolver/src/auto-discovery.ts
|
|
25126
25211
|
import { readFile as readFile10, readdir as readdir3, access as access2, lstat as lstat2 } from "fs/promises";
|
|
25127
|
-
import { resolve as
|
|
25212
|
+
import { resolve as resolve7, basename as basename10 } from "path";
|
|
25128
25213
|
var CONTEXT_FILES = ["CLAUDE.md", ".clinerules", ".cursorrules"];
|
|
25129
25214
|
async function fileExists2(path) {
|
|
25130
25215
|
try {
|
|
@@ -25160,9 +25245,9 @@ async function discoverSkills(dir) {
|
|
|
25160
25245
|
const properties = {};
|
|
25161
25246
|
for (const entry of entries) {
|
|
25162
25247
|
if (!entry.isDirectory()) continue;
|
|
25163
|
-
let skillMdPath =
|
|
25248
|
+
let skillMdPath = resolve7(dir, entry.name, "SKILL.md");
|
|
25164
25249
|
if (!await fileExists2(skillMdPath)) {
|
|
25165
|
-
const dirnameMdPath =
|
|
25250
|
+
const dirnameMdPath = resolve7(dir, entry.name, `${entry.name}.md`);
|
|
25166
25251
|
if (await fileExists2(dirnameMdPath)) {
|
|
25167
25252
|
skillMdPath = dirnameMdPath;
|
|
25168
25253
|
} else {
|
|
@@ -25189,7 +25274,7 @@ async function discoverSkills(dir) {
|
|
|
25189
25274
|
return Object.keys(properties).length > 0 ? properties : null;
|
|
25190
25275
|
}
|
|
25191
25276
|
async function discoverRootSkill(dir) {
|
|
25192
|
-
const skillMdPath =
|
|
25277
|
+
const skillMdPath = resolve7(dir, "SKILL.md");
|
|
25193
25278
|
if (!await fileExists2(skillMdPath)) return null;
|
|
25194
25279
|
try {
|
|
25195
25280
|
const raw = await readFile10(skillMdPath, "utf-8");
|
|
@@ -25220,7 +25305,7 @@ async function discoverAgents(dir) {
|
|
|
25220
25305
|
const properties = {};
|
|
25221
25306
|
for (const entry of entries) {
|
|
25222
25307
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
25223
|
-
const fullPath =
|
|
25308
|
+
const fullPath = resolve7(dir, entry.name);
|
|
25224
25309
|
try {
|
|
25225
25310
|
const stat4 = await lstat2(fullPath);
|
|
25226
25311
|
if (stat4.isSymbolicLink()) continue;
|
|
@@ -25256,7 +25341,7 @@ async function discoverCommands(dir) {
|
|
|
25256
25341
|
for (const entry of entries) {
|
|
25257
25342
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
25258
25343
|
if (entry.name === "SKILL.md") continue;
|
|
25259
|
-
const fullPath =
|
|
25344
|
+
const fullPath = resolve7(dir, entry.name);
|
|
25260
25345
|
try {
|
|
25261
25346
|
const stat4 = await lstat2(fullPath);
|
|
25262
25347
|
if (stat4.isSymbolicLink()) continue;
|
|
@@ -25273,7 +25358,7 @@ async function discoverCommands(dir) {
|
|
|
25273
25358
|
}
|
|
25274
25359
|
async function discoverContext(dir) {
|
|
25275
25360
|
for (const fileName of CONTEXT_FILES) {
|
|
25276
|
-
const fullPath =
|
|
25361
|
+
const fullPath = resolve7(dir, fileName);
|
|
25277
25362
|
if (!await fileExists2(fullPath)) continue;
|
|
25278
25363
|
try {
|
|
25279
25364
|
const content = await readFile10(fullPath, "utf-8");
|
|
@@ -25303,7 +25388,7 @@ async function discoverNativeContent(dir) {
|
|
|
25303
25388
|
const subSkills = await discoverSkills(dir);
|
|
25304
25389
|
const wrappedSkillResults = await Promise.all(
|
|
25305
25390
|
SKILL_WRAPPER_DIRS.map(async (name) => {
|
|
25306
|
-
const candidate =
|
|
25391
|
+
const candidate = resolve7(dir, name);
|
|
25307
25392
|
if (!await safeIsDirectory(candidate)) return null;
|
|
25308
25393
|
return discoverSkills(candidate);
|
|
25309
25394
|
})
|
|
@@ -25324,7 +25409,7 @@ async function discoverNativeContent(dir) {
|
|
|
25324
25409
|
const rootAgents = await discoverAgents(dir) ?? {};
|
|
25325
25410
|
const wrappedAgents = {};
|
|
25326
25411
|
for (const name of AGENT_WRAPPER_DIRS) {
|
|
25327
|
-
const candidate =
|
|
25412
|
+
const candidate = resolve7(dir, name);
|
|
25328
25413
|
if (await safeIsDirectory(candidate)) {
|
|
25329
25414
|
const found = await discoverAgents(candidate);
|
|
25330
25415
|
if (found) Object.assign(wrappedAgents, found);
|
|
@@ -25337,7 +25422,7 @@ async function discoverNativeContent(dir) {
|
|
|
25337
25422
|
const rootCommands = await discoverCommands(dir) ?? {};
|
|
25338
25423
|
const wrappedCommands = {};
|
|
25339
25424
|
for (const name of COMMAND_WRAPPER_DIRS) {
|
|
25340
|
-
const candidate =
|
|
25425
|
+
const candidate = resolve7(dir, name);
|
|
25341
25426
|
if (await safeIsDirectory(candidate)) {
|
|
25342
25427
|
const found = await discoverCommands(candidate);
|
|
25343
25428
|
if (found) Object.assign(wrappedCommands, found);
|
|
@@ -25838,18 +25923,39 @@ var Resolver = class {
|
|
|
25838
25923
|
errors.push(new ResolveError(e.message, e.location));
|
|
25839
25924
|
}
|
|
25840
25925
|
}
|
|
25926
|
+
} else if (isMdPath) {
|
|
25927
|
+
errors.push(
|
|
25928
|
+
new ResolveError(
|
|
25929
|
+
`Cannot resolve registry import: file '${subPath}' not found in ${repoUrl} (looked for ${resolvedFullPath}). Verify the path inside the repository.`
|
|
25930
|
+
)
|
|
25931
|
+
);
|
|
25841
25932
|
} else {
|
|
25842
25933
|
const discoverDir = isRoot ? cachePath : join8(cachePath, subPath);
|
|
25843
|
-
|
|
25844
|
-
resolvedAST = await discoverNativeContent(discoverDir);
|
|
25845
|
-
if (!resolvedAST) {
|
|
25846
|
-
const where = isRoot ? "<repository root>" : `'${subPath}'`;
|
|
25847
|
-
const hint = isRoot ? ` Specify a sub-path (e.g. ${repoUrl}/skills/<name>).` : "";
|
|
25934
|
+
if (!isRoot && !existsSync9(discoverDir)) {
|
|
25848
25935
|
errors.push(
|
|
25849
25936
|
new ResolveError(
|
|
25850
|
-
`Cannot resolve registry import:
|
|
25937
|
+
`Cannot resolve registry import: path '${subPath}' does not exist in repository ${repoUrl}.`
|
|
25851
25938
|
)
|
|
25852
25939
|
);
|
|
25940
|
+
} else {
|
|
25941
|
+
this.logger.debug(
|
|
25942
|
+
`No .prs found, trying directory scan and auto-discovery: ${discoverDir}`
|
|
25943
|
+
);
|
|
25944
|
+
const dirResult = await this.tryDirectoryScan(discoverDir, [marker], []);
|
|
25945
|
+
if (dirResult?.ast) {
|
|
25946
|
+
resolvedAST = dirResult.ast;
|
|
25947
|
+
} else {
|
|
25948
|
+
resolvedAST = await discoverNativeContent(discoverDir);
|
|
25949
|
+
if (!resolvedAST) {
|
|
25950
|
+
const where = isRoot ? "<repository root>" : `'${subPath}'`;
|
|
25951
|
+
const hint = isRoot ? ` Specify a sub-path (e.g. ${repoUrl}/skills/<name>).` : "";
|
|
25952
|
+
errors.push(
|
|
25953
|
+
new ResolveError(
|
|
25954
|
+
`Cannot resolve registry import: no .prs file, .md file, or native content at ${where} in ${repoUrl}.${hint}`
|
|
25955
|
+
)
|
|
25956
|
+
);
|
|
25957
|
+
}
|
|
25958
|
+
}
|
|
25853
25959
|
}
|
|
25854
25960
|
}
|
|
25855
25961
|
const result = {
|
|
@@ -26080,7 +26186,7 @@ var HttpRegistry = class {
|
|
|
26080
26186
|
* Sleep for specified milliseconds.
|
|
26081
26187
|
*/
|
|
26082
26188
|
sleep(ms) {
|
|
26083
|
-
return new Promise((
|
|
26189
|
+
return new Promise((resolve22) => setTimeout(resolve22, ms));
|
|
26084
26190
|
}
|
|
26085
26191
|
/**
|
|
26086
26192
|
* Fetch with timeout.
|
|
@@ -26224,9 +26330,251 @@ function createHttpRegistry(options) {
|
|
|
26224
26330
|
// packages/resolver/src/vendor-registry.ts
|
|
26225
26331
|
init_src();
|
|
26226
26332
|
|
|
26333
|
+
// packages/resolver/src/skill-validation.ts
|
|
26334
|
+
import { basename as basename12, dirname as dirname8, join as join10 } from "path";
|
|
26335
|
+
import { existsSync as existsSync11 } from "fs";
|
|
26336
|
+
function validateSkillFrontmatter(rawContent, options = {}) {
|
|
26337
|
+
const issues = [];
|
|
26338
|
+
if (!hasFrontmatterDelimiters(rawContent)) {
|
|
26339
|
+
issues.push({
|
|
26340
|
+
severity: "error",
|
|
26341
|
+
code: "SK001",
|
|
26342
|
+
message: "SKILL.md must start with a YAML frontmatter block delimited by `---` lines."
|
|
26343
|
+
});
|
|
26344
|
+
return { valid: false, issues };
|
|
26345
|
+
}
|
|
26346
|
+
const parsed = parseSkillMd(rawContent);
|
|
26347
|
+
validateName(parsed, options, issues);
|
|
26348
|
+
validateDescription(parsed, issues);
|
|
26349
|
+
validateCompatibility(parsed.rawFrontmatter, issues);
|
|
26350
|
+
validateLicense(parsed.rawFrontmatter, issues);
|
|
26351
|
+
validateBody(parsed.content, issues);
|
|
26352
|
+
validateReferences(parsed.references, options.filePath, issues);
|
|
26353
|
+
validateAllowedTools(parsed.rawFrontmatter, issues);
|
|
26354
|
+
const hasErrors = issues.some((i) => i.severity === "error");
|
|
26355
|
+
return { valid: !hasErrors, issues };
|
|
26356
|
+
}
|
|
26357
|
+
var NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
26358
|
+
var MAX_NAME_LEN = 64;
|
|
26359
|
+
var MIN_DESC_LEN = 1;
|
|
26360
|
+
var MAX_DESC_LEN = 1024;
|
|
26361
|
+
var MAX_COMPATIBILITY_LEN = 500;
|
|
26362
|
+
var SHORT_DESC_WARN_LEN = 40;
|
|
26363
|
+
var MAX_BODY_LINES = 500;
|
|
26364
|
+
function validateName(parsed, options, issues) {
|
|
26365
|
+
const name = parsed.name;
|
|
26366
|
+
if (!name || name.length === 0) {
|
|
26367
|
+
issues.push({
|
|
26368
|
+
severity: "error",
|
|
26369
|
+
code: "SK002",
|
|
26370
|
+
field: "name",
|
|
26371
|
+
message: "`name` is required in SKILL.md frontmatter."
|
|
26372
|
+
});
|
|
26373
|
+
return;
|
|
26374
|
+
}
|
|
26375
|
+
if (name.length > MAX_NAME_LEN) {
|
|
26376
|
+
issues.push({
|
|
26377
|
+
severity: "error",
|
|
26378
|
+
code: "SK003",
|
|
26379
|
+
field: "name",
|
|
26380
|
+
message: `\`name\` must be at most ${MAX_NAME_LEN} characters (got ${name.length}).`
|
|
26381
|
+
});
|
|
26382
|
+
}
|
|
26383
|
+
if (!NAME_PATTERN.test(name)) {
|
|
26384
|
+
issues.push({
|
|
26385
|
+
severity: "error",
|
|
26386
|
+
code: "SK004",
|
|
26387
|
+
field: "name",
|
|
26388
|
+
message: `\`name\` "${name}" is invalid. Use lowercase letters, digits, and single hyphens only. Cannot start or end with a hyphen or contain consecutive hyphens.`
|
|
26389
|
+
});
|
|
26390
|
+
}
|
|
26391
|
+
if (options.filePath) {
|
|
26392
|
+
const parentDir = basename12(dirname8(options.filePath));
|
|
26393
|
+
if (parentDir && parentDir !== name) {
|
|
26394
|
+
issues.push({
|
|
26395
|
+
severity: "error",
|
|
26396
|
+
code: "SK005",
|
|
26397
|
+
field: "name",
|
|
26398
|
+
message: `\`name\` "${name}" must match the parent directory name "${parentDir}".`
|
|
26399
|
+
});
|
|
26400
|
+
}
|
|
26401
|
+
}
|
|
26402
|
+
if (options.existingNames?.has(name)) {
|
|
26403
|
+
issues.push({
|
|
26404
|
+
severity: "error",
|
|
26405
|
+
code: "SK006",
|
|
26406
|
+
field: "name",
|
|
26407
|
+
message: `Skill name "${name}" collides with an already-installed skill. Two skills cannot share the same name (they would be written to the same output folder).`
|
|
26408
|
+
});
|
|
26409
|
+
}
|
|
26410
|
+
}
|
|
26411
|
+
function validateDescription(parsed, issues) {
|
|
26412
|
+
const fromRaw = parsed.rawFrontmatter ? extractScalarField(parsed.rawFrontmatter, "description") : void 0;
|
|
26413
|
+
const description = fromRaw !== void 0 ? fromRaw : parsed.description;
|
|
26414
|
+
if (!description || description.trim().length < MIN_DESC_LEN) {
|
|
26415
|
+
issues.push({
|
|
26416
|
+
severity: "error",
|
|
26417
|
+
code: "SK010",
|
|
26418
|
+
field: "description",
|
|
26419
|
+
message: "`description` is required and must be non-empty."
|
|
26420
|
+
});
|
|
26421
|
+
return;
|
|
26422
|
+
}
|
|
26423
|
+
if (description.length > MAX_DESC_LEN) {
|
|
26424
|
+
issues.push({
|
|
26425
|
+
severity: "error",
|
|
26426
|
+
code: "SK011",
|
|
26427
|
+
field: "description",
|
|
26428
|
+
message: `\`description\` must be at most ${MAX_DESC_LEN} characters (got ${description.length}).`
|
|
26429
|
+
});
|
|
26430
|
+
}
|
|
26431
|
+
if (description.length < SHORT_DESC_WARN_LEN) {
|
|
26432
|
+
issues.push({
|
|
26433
|
+
severity: "warning",
|
|
26434
|
+
code: "SK012",
|
|
26435
|
+
field: "description",
|
|
26436
|
+
message: `\`description\` is very short (${description.length} chars). The spec recommends describing both what the skill does AND when to use it so agents can match it to tasks.`
|
|
26437
|
+
});
|
|
26438
|
+
} else if (!/\bwhen\b|\buse\b/i.test(description)) {
|
|
26439
|
+
issues.push({
|
|
26440
|
+
severity: "warning",
|
|
26441
|
+
code: "SK013",
|
|
26442
|
+
field: "description",
|
|
26443
|
+
message: '`description` should mention WHEN to use the skill (e.g. "Use when \u2026"). This improves agent trigger accuracy.'
|
|
26444
|
+
});
|
|
26445
|
+
}
|
|
26446
|
+
}
|
|
26447
|
+
function validateCompatibility(rawFrontmatter, issues) {
|
|
26448
|
+
if (!rawFrontmatter) return;
|
|
26449
|
+
const value = extractScalarField(rawFrontmatter, "compatibility");
|
|
26450
|
+
if (value === void 0) return;
|
|
26451
|
+
if (value.length > MAX_COMPATIBILITY_LEN) {
|
|
26452
|
+
issues.push({
|
|
26453
|
+
severity: "error",
|
|
26454
|
+
code: "SK020",
|
|
26455
|
+
field: "compatibility",
|
|
26456
|
+
message: `\`compatibility\` must be at most ${MAX_COMPATIBILITY_LEN} characters (got ${value.length}).`
|
|
26457
|
+
});
|
|
26458
|
+
}
|
|
26459
|
+
}
|
|
26460
|
+
function validateLicense(rawFrontmatter, issues) {
|
|
26461
|
+
if (!rawFrontmatter) {
|
|
26462
|
+
issues.push({
|
|
26463
|
+
severity: "warning",
|
|
26464
|
+
code: "SK030",
|
|
26465
|
+
field: "license",
|
|
26466
|
+
message: "`license` is missing. Enterprises typically require an explicit license declaration before adopting a third-party skill."
|
|
26467
|
+
});
|
|
26468
|
+
return;
|
|
26469
|
+
}
|
|
26470
|
+
const value = extractScalarField(rawFrontmatter, "license");
|
|
26471
|
+
if (value === void 0 || value.length === 0) {
|
|
26472
|
+
issues.push({
|
|
26473
|
+
severity: "warning",
|
|
26474
|
+
code: "SK030",
|
|
26475
|
+
field: "license",
|
|
26476
|
+
message: "`license` is missing. Enterprises typically require an explicit license declaration before adopting a third-party skill."
|
|
26477
|
+
});
|
|
26478
|
+
}
|
|
26479
|
+
}
|
|
26480
|
+
function validateBody(body, issues) {
|
|
26481
|
+
const lines = body.split("\n").length;
|
|
26482
|
+
if (lines > MAX_BODY_LINES) {
|
|
26483
|
+
issues.push({
|
|
26484
|
+
severity: "warning",
|
|
26485
|
+
code: "SK040",
|
|
26486
|
+
message: `SKILL.md body has ${lines} lines (>${MAX_BODY_LINES}). The spec recommends splitting long content into separate files under references/ for progressive disclosure.`
|
|
26487
|
+
});
|
|
26488
|
+
}
|
|
26489
|
+
}
|
|
26490
|
+
function validateReferences(references, filePath, issues) {
|
|
26491
|
+
if (!references || references.length === 0) return;
|
|
26492
|
+
if (!filePath) return;
|
|
26493
|
+
const skillDir = dirname8(filePath);
|
|
26494
|
+
for (const ref of references) {
|
|
26495
|
+
if (ref.startsWith("/") || ref.startsWith("..")) {
|
|
26496
|
+
issues.push({
|
|
26497
|
+
severity: "error",
|
|
26498
|
+
code: "SK050",
|
|
26499
|
+
field: "references",
|
|
26500
|
+
message: `Reference "${ref}" must be a relative path inside the skill directory (no leading "/" or "..").`
|
|
26501
|
+
});
|
|
26502
|
+
continue;
|
|
26503
|
+
}
|
|
26504
|
+
const target = join10(skillDir, ref);
|
|
26505
|
+
if (!existsSync11(target)) {
|
|
26506
|
+
issues.push({
|
|
26507
|
+
severity: "error",
|
|
26508
|
+
code: "SK051",
|
|
26509
|
+
field: "references",
|
|
26510
|
+
message: `Reference "${ref}" listed in frontmatter does not exist (looked for ${target}).`
|
|
26511
|
+
});
|
|
26512
|
+
}
|
|
26513
|
+
}
|
|
26514
|
+
}
|
|
26515
|
+
function validateAllowedTools(rawFrontmatter, issues) {
|
|
26516
|
+
if (!rawFrontmatter) return;
|
|
26517
|
+
const value = extractScalarField(rawFrontmatter, "allowed-tools");
|
|
26518
|
+
if (value === void 0) return;
|
|
26519
|
+
const tokens = value.split(/\s+/).filter((t) => t.length > 0);
|
|
26520
|
+
for (const token of tokens) {
|
|
26521
|
+
if (!/^[A-Za-z][A-Za-z0-9_-]*(\([^)]*\))?$/.test(token)) {
|
|
26522
|
+
issues.push({
|
|
26523
|
+
severity: "warning",
|
|
26524
|
+
code: "SK060",
|
|
26525
|
+
field: "allowed-tools",
|
|
26526
|
+
message: `\`allowed-tools\` entry "${token}" does not match the expected \`Tool\` or \`Tool(scope:pattern)\` shape.`
|
|
26527
|
+
});
|
|
26528
|
+
}
|
|
26529
|
+
}
|
|
26530
|
+
}
|
|
26531
|
+
function hasFrontmatterDelimiters(content) {
|
|
26532
|
+
const lines = content.split("\n");
|
|
26533
|
+
let first2 = -1;
|
|
26534
|
+
for (let i = 0; i < lines.length; i++) {
|
|
26535
|
+
if ((lines[i] ?? "").trim() === "---") {
|
|
26536
|
+
first2 = i;
|
|
26537
|
+
break;
|
|
26538
|
+
}
|
|
26539
|
+
}
|
|
26540
|
+
if (first2 === -1) return false;
|
|
26541
|
+
for (let i = first2 + 1; i < lines.length; i++) {
|
|
26542
|
+
if ((lines[i] ?? "").trim() === "---") return true;
|
|
26543
|
+
}
|
|
26544
|
+
return false;
|
|
26545
|
+
}
|
|
26546
|
+
function extractScalarField(rawFrontmatter, field) {
|
|
26547
|
+
const lines = rawFrontmatter.split("\n");
|
|
26548
|
+
const pattern = new RegExp(`^${escapeRegex(field)}:\\s*(?:"([^"]*)"|'([^']*)'|(.*))\\s*$`);
|
|
26549
|
+
for (const line of lines) {
|
|
26550
|
+
const match = line.match(pattern);
|
|
26551
|
+
if (match) {
|
|
26552
|
+
return (match[1] ?? match[2] ?? match[3] ?? "").trim();
|
|
26553
|
+
}
|
|
26554
|
+
}
|
|
26555
|
+
return void 0;
|
|
26556
|
+
}
|
|
26557
|
+
function escapeRegex(input2) {
|
|
26558
|
+
return input2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
26559
|
+
}
|
|
26560
|
+
function formatSkillValidationIssues(issues) {
|
|
26561
|
+
return issues.map((i) => {
|
|
26562
|
+
const tag = i.severity === "error" ? "\u2717" : "\u26A0";
|
|
26563
|
+
const field = i.field ? ` [${i.field}]` : "";
|
|
26564
|
+
return ` ${tag} ${i.code}${field}: ${i.message}`;
|
|
26565
|
+
}).join("\n");
|
|
26566
|
+
}
|
|
26567
|
+
|
|
26227
26568
|
// packages/resolver/src/index.ts
|
|
26228
26569
|
init_src();
|
|
26229
26570
|
|
|
26571
|
+
// packages/resolver/src/reference-hasher.ts
|
|
26572
|
+
import { createHash as createHash2 } from "crypto";
|
|
26573
|
+
function hashContent(content) {
|
|
26574
|
+
const hex = createHash2("sha256").update(content).digest("hex");
|
|
26575
|
+
return `sha256-${hex}`;
|
|
26576
|
+
}
|
|
26577
|
+
|
|
26230
26578
|
// packages/validator/src/validator.ts
|
|
26231
26579
|
init_src();
|
|
26232
26580
|
|
|
@@ -27391,7 +27739,8 @@ var AUTHORITY_PATTERNS = [
|
|
|
27391
27739
|
/\[?\s{0,10}PRIORITY\s{0,10}(?:OVERRIDE|ONE|ALPHA)\s{0,10}\]?/i,
|
|
27392
27740
|
/\[?\s{0,10}EMERGENCY\s{0,10}(?:PROTOCOL|OVERRIDE|MODE)\s{0,10}\]?/i,
|
|
27393
27741
|
// Warning suppression patterns
|
|
27394
|
-
|
|
27742
|
+
// Removed because it triggers false positives on valid agent instructions (e.g., "do not notify user")
|
|
27743
|
+
// /(?:DO\s{1,10}NOT|NEVER|DON'?T)\s{1,10}(?:WARN|ALERT|NOTIFY|FLAG|REPORT)/i,
|
|
27395
27744
|
/(?:DO\s{1,10}NOT|NEVER|DON'?T)\s{1,10}(?:PROVIDE|SHOW|DISPLAY|INCLUDE)\s{1,10}(?:SECURITY\s{1,10})?WARNINGS?/i,
|
|
27396
27745
|
/(?:SUPPRESS|HIDE|DISABLE|REMOVE|SILENCE)\s{1,10}(?:ALL\s{1,10})?WARNINGS?/i,
|
|
27397
27746
|
/(?:SUPPRESS|HIDE|DISABLE|REMOVE|SILENCE)\s{1,10}(?:ALL\s{1,10})?(?:SECURITY\s{1,10})?(?:ALERTS?|NOTIFICATIONS?)/i,
|
|
@@ -29679,7 +30028,7 @@ var Compiler = class _Compiler {
|
|
|
29679
30028
|
outputPathOwners.set(skillPath, `${formatter.name}:promptscript-skill`);
|
|
29680
30029
|
const skillOutput = {
|
|
29681
30030
|
path: skillPath,
|
|
29682
|
-
content: this.options.skillContent
|
|
30031
|
+
content: formatter.transformInjectedSkillContent ? formatter.transformInjectedSkillContent(this.options.skillContent) : this.options.skillContent
|
|
29683
30032
|
};
|
|
29684
30033
|
outputs.set(skillPath, addMarkerToOutput(skillOutput, sourceLabel, "promptscript"));
|
|
29685
30034
|
this.logger.verbose(` \u2192 ${skillPath} (auto-injected promptscript skill)`);
|
|
@@ -29760,12 +30109,12 @@ var Compiler = class _Compiler {
|
|
|
29760
30109
|
*/
|
|
29761
30110
|
async watch(entryPath, options = {}) {
|
|
29762
30111
|
const { default: chokidar2 } = await import("chokidar");
|
|
29763
|
-
const { dirname:
|
|
29764
|
-
const baseDir =
|
|
30112
|
+
const { dirname: dirname17, resolve: resolve22 } = await import("path");
|
|
30113
|
+
const baseDir = dirname17(resolve22(entryPath));
|
|
29765
30114
|
const includePatterns = options.include ?? ["**/*.prs"];
|
|
29766
30115
|
const excludePatterns = options.exclude ?? ["**/node_modules/**"];
|
|
29767
30116
|
const debounceMs = options.debounce ?? 300;
|
|
29768
|
-
const watchPatterns = includePatterns.map((p) =>
|
|
30117
|
+
const watchPatterns = includePatterns.map((p) => resolve22(baseDir, p));
|
|
29769
30118
|
let debounceTimer = null;
|
|
29770
30119
|
let pendingChanges = [];
|
|
29771
30120
|
const handleChange = async (changedFiles) => {
|
|
@@ -29940,7 +30289,7 @@ var Pager = class {
|
|
|
29940
30289
|
}
|
|
29941
30290
|
return;
|
|
29942
30291
|
}
|
|
29943
|
-
return new Promise((
|
|
30292
|
+
return new Promise((resolve22) => {
|
|
29944
30293
|
const pagerCmd = getPagerCommand();
|
|
29945
30294
|
const [cmd, ...args] = pagerCmd.split(" ");
|
|
29946
30295
|
if (cmd === "less" && !args.includes("-R")) {
|
|
@@ -29948,7 +30297,7 @@ var Pager = class {
|
|
|
29948
30297
|
}
|
|
29949
30298
|
if (!cmd) {
|
|
29950
30299
|
console.log(content);
|
|
29951
|
-
|
|
30300
|
+
resolve22();
|
|
29952
30301
|
return;
|
|
29953
30302
|
}
|
|
29954
30303
|
const pager = spawn(cmd, args, {
|
|
@@ -29961,17 +30310,17 @@ var Pager = class {
|
|
|
29961
30310
|
});
|
|
29962
30311
|
pager.on("error", (_err) => {
|
|
29963
30312
|
console.log(content);
|
|
29964
|
-
|
|
30313
|
+
resolve22();
|
|
29965
30314
|
});
|
|
29966
30315
|
pager.on("close", () => {
|
|
29967
|
-
|
|
30316
|
+
resolve22();
|
|
29968
30317
|
});
|
|
29969
30318
|
if (pager.stdin) {
|
|
29970
30319
|
pager.stdin.write(content);
|
|
29971
30320
|
pager.stdin.end();
|
|
29972
30321
|
} else {
|
|
29973
30322
|
console.log(content);
|
|
29974
|
-
|
|
30323
|
+
resolve22();
|
|
29975
30324
|
}
|
|
29976
30325
|
});
|
|
29977
30326
|
}
|
|
@@ -29984,7 +30333,7 @@ function createPager(enabled = true) {
|
|
|
29984
30333
|
init_services();
|
|
29985
30334
|
|
|
29986
30335
|
// packages/cli/src/utils/registry-resolver.ts
|
|
29987
|
-
import { join as
|
|
30336
|
+
import { join as join11 } from "path";
|
|
29988
30337
|
async function resolveRegistryPath(config) {
|
|
29989
30338
|
if (config.registry?.git) {
|
|
29990
30339
|
const gitConfig = config.registry.git;
|
|
@@ -29998,7 +30347,7 @@ async function resolveRegistryPath(config) {
|
|
|
29998
30347
|
if (isValid) {
|
|
29999
30348
|
const subPath2 = gitConfig.path ?? "";
|
|
30000
30349
|
return {
|
|
30001
|
-
path: subPath2 ?
|
|
30350
|
+
path: subPath2 ? join11(cachePath, subPath2) : cachePath,
|
|
30002
30351
|
isRemote: true,
|
|
30003
30352
|
source: "git"
|
|
30004
30353
|
};
|
|
@@ -30027,7 +30376,7 @@ async function resolveRegistryPath(config) {
|
|
|
30027
30376
|
}
|
|
30028
30377
|
const subPath = gitConfig.path ?? "";
|
|
30029
30378
|
return {
|
|
30030
|
-
path: subPath ?
|
|
30379
|
+
path: subPath ? join11(cachePath, subPath) : cachePath,
|
|
30031
30380
|
isRemote: true,
|
|
30032
30381
|
source: "git"
|
|
30033
30382
|
};
|
|
@@ -30077,17 +30426,17 @@ function detectOutputConflicts(targets) {
|
|
|
30077
30426
|
|
|
30078
30427
|
// packages/cli/src/commands/compile.ts
|
|
30079
30428
|
var __filename2 = fileURLToPath2(import.meta.url);
|
|
30080
|
-
var __dirname2 =
|
|
30429
|
+
var __dirname2 = dirname9(__filename2);
|
|
30081
30430
|
async function loadBundledSkillContent(logger) {
|
|
30082
30431
|
const skillRelPath = "skills/promptscript/SKILL.md";
|
|
30083
30432
|
const candidates = [
|
|
30084
|
-
|
|
30433
|
+
resolve8(__dirname2, skillRelPath),
|
|
30085
30434
|
// bundled: dist/packages/cli/skills/...
|
|
30086
|
-
|
|
30435
|
+
resolve8(__dirname2, "..", "..", skillRelPath)
|
|
30087
30436
|
// dev: packages/cli/skills/...
|
|
30088
30437
|
];
|
|
30089
30438
|
for (const candidate of candidates) {
|
|
30090
|
-
if (
|
|
30439
|
+
if (existsSync12(candidate)) {
|
|
30091
30440
|
try {
|
|
30092
30441
|
const content = await readFile12(candidate, "utf-8");
|
|
30093
30442
|
logger.debug(
|
|
@@ -30104,8 +30453,8 @@ async function loadBundledSkillContent(logger) {
|
|
|
30104
30453
|
}
|
|
30105
30454
|
function findConfigInDir(dir) {
|
|
30106
30455
|
for (const file of CONFIG_FILES) {
|
|
30107
|
-
const fullPath =
|
|
30108
|
-
if (
|
|
30456
|
+
const fullPath = resolve8(dir, file);
|
|
30457
|
+
if (existsSync12(fullPath)) {
|
|
30109
30458
|
return fullPath;
|
|
30110
30459
|
}
|
|
30111
30460
|
}
|
|
@@ -30161,7 +30510,7 @@ function getBuildProfile(config, buildName) {
|
|
|
30161
30510
|
}
|
|
30162
30511
|
function resolveOutputBase(projectRoot, output) {
|
|
30163
30512
|
if (!output) return projectRoot;
|
|
30164
|
-
return isAbsolute5(output) ? output :
|
|
30513
|
+
return isAbsolute5(output) ? output : resolve8(projectRoot, output);
|
|
30165
30514
|
}
|
|
30166
30515
|
async function isPromptScriptGenerated2(filePath) {
|
|
30167
30516
|
try {
|
|
@@ -30205,13 +30554,13 @@ async function writeOutputs(outputs, options, _config, services) {
|
|
|
30205
30554
|
const targetErrors = [];
|
|
30206
30555
|
async function safeWrite(path, content) {
|
|
30207
30556
|
try {
|
|
30208
|
-
await mkdir4(
|
|
30557
|
+
await mkdir4(dirname9(path), { recursive: true });
|
|
30209
30558
|
await writeFile4(path, content, "utf-8");
|
|
30210
30559
|
return true;
|
|
30211
30560
|
} catch (err) {
|
|
30212
30561
|
const nodeErr = err;
|
|
30213
30562
|
if (nodeErr.code === "ENOTDIR") {
|
|
30214
|
-
const conflictPath = nodeErr.path ??
|
|
30563
|
+
const conflictPath = nodeErr.path ?? dirname9(path);
|
|
30215
30564
|
const msg = `Cannot create directory because '${conflictPath}' already exists as a file. Remove it or disable this target.`;
|
|
30216
30565
|
targetErrors.push(msg);
|
|
30217
30566
|
ConsoleOutput.error(msg);
|
|
@@ -30227,8 +30576,8 @@ async function writeOutputs(outputs, options, _config, services) {
|
|
|
30227
30576
|
}
|
|
30228
30577
|
}
|
|
30229
30578
|
for (const output of outputs.values()) {
|
|
30230
|
-
const outputPath = options.output ?
|
|
30231
|
-
const fileExists3 =
|
|
30579
|
+
const outputPath = options.output ? resolve8(options.output, output.path) : resolve8(output.path);
|
|
30580
|
+
const fileExists3 = existsSync12(outputPath);
|
|
30232
30581
|
if (options.dryRun) {
|
|
30233
30582
|
if (fileExists3) {
|
|
30234
30583
|
const isGenerated2 = await isPromptScriptGenerated2(outputPath);
|
|
@@ -30361,7 +30710,7 @@ async function compileCommand(options, services = createDefaultServices()) {
|
|
|
30361
30710
|
const spinner = createSpinner("Loading configuration...").start();
|
|
30362
30711
|
const logger = createCliLogger();
|
|
30363
30712
|
try {
|
|
30364
|
-
const projectRoot = options.cwd ?
|
|
30713
|
+
const projectRoot = options.cwd ? resolve8(options.cwd) : process.cwd();
|
|
30365
30714
|
logger.verbose("Loading configuration...");
|
|
30366
30715
|
const configPath = options.config ? options.config : options.cwd ? findConfigInDir(projectRoot) : void 0;
|
|
30367
30716
|
const config = await loadConfig(configPath);
|
|
@@ -30401,7 +30750,7 @@ Disable one of the conflicting targets or assign a custom output path.`
|
|
|
30401
30750
|
}
|
|
30402
30751
|
}
|
|
30403
30752
|
let lockfile;
|
|
30404
|
-
const lockfilePath =
|
|
30753
|
+
const lockfilePath = resolve8(projectRoot, "promptscript.lock");
|
|
30405
30754
|
try {
|
|
30406
30755
|
const lockfileContent = await readFile12(lockfilePath, "utf-8");
|
|
30407
30756
|
const parsed = parseYaml5(lockfileContent, { maxAliasCount: 100 });
|
|
@@ -30421,7 +30770,7 @@ Disable one of the conflicting targets or assign a custom output path.`
|
|
|
30421
30770
|
if (config.includePromptScriptSkill !== false) {
|
|
30422
30771
|
skillContent = await loadBundledSkillContent(logger);
|
|
30423
30772
|
}
|
|
30424
|
-
const localPath =
|
|
30773
|
+
const localPath = resolve8(projectRoot, ".promptscript");
|
|
30425
30774
|
const compiler = new Compiler({
|
|
30426
30775
|
resolver: {
|
|
30427
30776
|
registryPath,
|
|
@@ -30441,8 +30790,8 @@ Disable one of the conflicting targets or assign a custom output path.`
|
|
|
30441
30790
|
ignoreHashes: options.ignoreHashes
|
|
30442
30791
|
});
|
|
30443
30792
|
const entry = buildProfile?.entry ?? config.input?.entry;
|
|
30444
|
-
const entryPath = entry ?
|
|
30445
|
-
if (!
|
|
30793
|
+
const entryPath = entry ? resolve8(projectRoot, entry) : resolve8(localPath, "project.prs");
|
|
30794
|
+
if (!existsSync12(entryPath)) {
|
|
30446
30795
|
spinner.fail("Entry file not found");
|
|
30447
30796
|
ConsoleOutput.error(`File not found: ${entryPath}`);
|
|
30448
30797
|
ConsoleOutput.muted("Run: prs init");
|
|
@@ -30467,6 +30816,7 @@ Disable one of the conflicting targets or assign a custom output path.`
|
|
|
30467
30816
|
...options,
|
|
30468
30817
|
output: resolveOutputBase(projectRoot, configuredOutput)
|
|
30469
30818
|
};
|
|
30819
|
+
await postFormatWithPrettier(result.outputs, projectRoot, logger);
|
|
30470
30820
|
const writeResult = await writeOutputs(result.outputs, effectiveOptions, config, services);
|
|
30471
30821
|
if (writeResult.unchanged.length > 0) {
|
|
30472
30822
|
ConsoleOutput.muted(`Unchanged ${writeResult.unchanged.length} file(s)`);
|
|
@@ -30480,7 +30830,7 @@ Disable one of the conflicting targets or assign a custom output path.`
|
|
|
30480
30830
|
ConsoleOutput.newline();
|
|
30481
30831
|
ConsoleOutput.info("Watching for changes... (Ctrl+C to stop)");
|
|
30482
30832
|
watchForChanges(
|
|
30483
|
-
|
|
30833
|
+
resolve8(projectRoot, ".promptscript"),
|
|
30484
30834
|
() => compileCommand({ ...options, watch: false }, services)
|
|
30485
30835
|
);
|
|
30486
30836
|
}
|
|
@@ -30531,8 +30881,8 @@ function watchForChanges(dir, callback) {
|
|
|
30531
30881
|
}
|
|
30532
30882
|
|
|
30533
30883
|
// packages/cli/src/commands/validate.ts
|
|
30534
|
-
import { resolve as
|
|
30535
|
-
import { existsSync as
|
|
30884
|
+
import { resolve as resolve9, join as join12 } from "path";
|
|
30885
|
+
import { existsSync as existsSync13, readFileSync as readFileSync4, writeFileSync, readdirSync } from "fs";
|
|
30536
30886
|
init_console();
|
|
30537
30887
|
init_src();
|
|
30538
30888
|
init_src2();
|
|
@@ -30641,7 +30991,7 @@ function discoverPrsFiles(dir) {
|
|
|
30641
30991
|
try {
|
|
30642
30992
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
30643
30993
|
for (const entry of entries) {
|
|
30644
|
-
const fullPath =
|
|
30994
|
+
const fullPath = join12(dir, entry.name);
|
|
30645
30995
|
if (entry.isDirectory()) {
|
|
30646
30996
|
results.push(...discoverPrsFiles(fullPath));
|
|
30647
30997
|
} else if (entry.name.endsWith(".prs")) {
|
|
@@ -30681,8 +31031,8 @@ async function validateCommand(options) {
|
|
|
30681
31031
|
formatters: []
|
|
30682
31032
|
// No formatters needed for validation only
|
|
30683
31033
|
});
|
|
30684
|
-
const entryPath =
|
|
30685
|
-
if (!
|
|
31034
|
+
const entryPath = resolve9("./.promptscript/project.prs");
|
|
31035
|
+
if (!existsSync13(entryPath)) {
|
|
30686
31036
|
handleEntryNotFound(entryPath, isJsonFormat, spinner);
|
|
30687
31037
|
return;
|
|
30688
31038
|
}
|
|
@@ -30764,8 +31114,8 @@ ${fixedCount} file(s) fixed.`);
|
|
|
30764
31114
|
|
|
30765
31115
|
// packages/cli/src/commands/pull.ts
|
|
30766
31116
|
import { mkdir as mkdir5, writeFile as writeFile5 } from "fs/promises";
|
|
30767
|
-
import { existsSync as
|
|
30768
|
-
import { resolve as
|
|
31117
|
+
import { existsSync as existsSync14 } from "fs";
|
|
31118
|
+
import { resolve as resolve10, dirname as dirname10 } from "path";
|
|
30769
31119
|
init_console();
|
|
30770
31120
|
async function pullCommand(options) {
|
|
30771
31121
|
const spinner = createSpinner("Loading configuration...").start();
|
|
@@ -30790,8 +31140,8 @@ async function pullCommand(options) {
|
|
|
30790
31140
|
}
|
|
30791
31141
|
spinner.text = `Fetching ${inheritPath}...`;
|
|
30792
31142
|
const content = await registry2.fetch(inheritPath);
|
|
30793
|
-
const destPath =
|
|
30794
|
-
if (
|
|
31143
|
+
const destPath = resolve10("./.promptscript/.inherited", inheritPath);
|
|
31144
|
+
if (existsSync14(destPath) && !options.force && !options.dryRun) {
|
|
30795
31145
|
spinner.warn("File already exists (use --force to overwrite)");
|
|
30796
31146
|
ConsoleOutput.muted(destPath);
|
|
30797
31147
|
return;
|
|
@@ -30801,12 +31151,12 @@ async function pullCommand(options) {
|
|
|
30801
31151
|
ConsoleOutput.newline();
|
|
30802
31152
|
ConsoleOutput.dryRun(`Would fetch: ${config.inherit}`);
|
|
30803
31153
|
ConsoleOutput.dryRun(` to: ${destPath}`);
|
|
30804
|
-
if (
|
|
31154
|
+
if (existsSync14(destPath)) {
|
|
30805
31155
|
ConsoleOutput.dryRun("(would overwrite existing file)");
|
|
30806
31156
|
}
|
|
30807
31157
|
return;
|
|
30808
31158
|
}
|
|
30809
|
-
await mkdir5(
|
|
31159
|
+
await mkdir5(dirname10(destPath), { recursive: true });
|
|
30810
31160
|
await writeFile5(destPath, content, "utf-8");
|
|
30811
31161
|
spinner.succeed("Pulled from registry");
|
|
30812
31162
|
ConsoleOutput.success(destPath);
|
|
@@ -30849,10 +31199,10 @@ async function createRegistry(config, options, spinner) {
|
|
|
30849
31199
|
}
|
|
30850
31200
|
const registryPath = config.registry?.path ?? "./registry";
|
|
30851
31201
|
spinner.text = `Using local registry: ${registryPath}...`;
|
|
30852
|
-
if (!
|
|
31202
|
+
if (!existsSync14(registryPath)) {
|
|
30853
31203
|
throw new Error(`Local registry path not found: ${registryPath}`);
|
|
30854
31204
|
}
|
|
30855
|
-
return createFileSystemRegistry(
|
|
31205
|
+
return createFileSystemRegistry(resolve10(registryPath));
|
|
30856
31206
|
}
|
|
30857
31207
|
function parseInheritPath(inheritPath) {
|
|
30858
31208
|
const versionIndex = inheritPath.lastIndexOf("@");
|
|
@@ -30899,9 +31249,9 @@ function handlePullError(error, spinner) {
|
|
|
30899
31249
|
}
|
|
30900
31250
|
|
|
30901
31251
|
// packages/cli/src/commands/diff.ts
|
|
30902
|
-
import { resolve as
|
|
31252
|
+
import { resolve as resolve11 } from "path";
|
|
30903
31253
|
import { readFile as readFile13 } from "fs/promises";
|
|
30904
|
-
import { existsSync as
|
|
31254
|
+
import { existsSync as existsSync15 } from "fs";
|
|
30905
31255
|
init_console();
|
|
30906
31256
|
import chalk2 from "chalk";
|
|
30907
31257
|
function configureColors(options) {
|
|
@@ -30936,9 +31286,9 @@ function printNewFilePreview(content, showFull, pager) {
|
|
|
30936
31286
|
}
|
|
30937
31287
|
}
|
|
30938
31288
|
async function compareOutput(_name, output, _config, showFull, pager) {
|
|
30939
|
-
const outputPath =
|
|
31289
|
+
const outputPath = resolve11(output.path);
|
|
30940
31290
|
const newContent = output.content;
|
|
30941
|
-
if (!
|
|
31291
|
+
if (!existsSync15(outputPath)) {
|
|
30942
31292
|
pager.write(chalk2.green(`+ ${outputPath} (new file)`));
|
|
30943
31293
|
pager.write("");
|
|
30944
31294
|
printNewFilePreview(newContent, showFull, pager);
|
|
@@ -30978,8 +31328,8 @@ async function diffCommand(options) {
|
|
|
30978
31328
|
formatters: targets,
|
|
30979
31329
|
customConventions: config.customConventions
|
|
30980
31330
|
});
|
|
30981
|
-
const entryPath =
|
|
30982
|
-
if (!
|
|
31331
|
+
const entryPath = resolve11("./.promptscript/project.prs");
|
|
31332
|
+
if (!existsSync15(entryPath)) {
|
|
30983
31333
|
spinner.fail("Entry file not found");
|
|
30984
31334
|
ConsoleOutput.error(`File not found: ${entryPath}`);
|
|
30985
31335
|
ConsoleOutput.muted("Run: prs init");
|
|
@@ -31047,8 +31397,8 @@ function printSimpleDiff(existingLines, newLines, showFull, pager) {
|
|
|
31047
31397
|
}
|
|
31048
31398
|
|
|
31049
31399
|
// packages/cli/src/commands/check.ts
|
|
31050
|
-
import { existsSync as
|
|
31051
|
-
import { resolve as
|
|
31400
|
+
import { existsSync as existsSync16 } from "fs";
|
|
31401
|
+
import { resolve as resolve12 } from "path";
|
|
31052
31402
|
init_console();
|
|
31053
31403
|
async function checkCommand(_options) {
|
|
31054
31404
|
const spinner = createSpinner("Checking project health...").start();
|
|
@@ -31111,7 +31461,7 @@ async function checkCommand(_options) {
|
|
|
31111
31461
|
});
|
|
31112
31462
|
}
|
|
31113
31463
|
const entryPath = config.input?.entry ?? ".promptscript/project.prs";
|
|
31114
|
-
if (
|
|
31464
|
+
if (existsSync16(entryPath)) {
|
|
31115
31465
|
results.push({
|
|
31116
31466
|
name: "Entry file",
|
|
31117
31467
|
status: "ok",
|
|
@@ -31126,8 +31476,8 @@ async function checkCommand(_options) {
|
|
|
31126
31476
|
hasErrors = true;
|
|
31127
31477
|
}
|
|
31128
31478
|
if (config.registry?.path) {
|
|
31129
|
-
const registryPath =
|
|
31130
|
-
if (
|
|
31479
|
+
const registryPath = resolve12(config.registry.path);
|
|
31480
|
+
if (existsSync16(registryPath)) {
|
|
31131
31481
|
results.push({
|
|
31132
31482
|
name: "Registry path",
|
|
31133
31483
|
status: "ok",
|
|
@@ -31212,21 +31562,21 @@ function printResults(results) {
|
|
|
31212
31562
|
init_src();
|
|
31213
31563
|
init_console();
|
|
31214
31564
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
31215
|
-
import { dirname as
|
|
31565
|
+
import { dirname as dirname11 } from "path";
|
|
31216
31566
|
|
|
31217
31567
|
// packages/cli/src/utils/version-check.ts
|
|
31218
31568
|
init_console();
|
|
31219
31569
|
import { homedir as homedir3 } from "os";
|
|
31220
|
-
import { join as
|
|
31570
|
+
import { join as join13 } from "path";
|
|
31221
31571
|
import { readFile as readFile14, writeFile as writeFile6, mkdir as mkdir6 } from "fs/promises";
|
|
31222
31572
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org/@promptscript/cli/latest";
|
|
31223
31573
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
31224
31574
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
31225
31575
|
function getCacheDir() {
|
|
31226
|
-
return
|
|
31576
|
+
return join13(homedir3(), ".promptscript", ".cache");
|
|
31227
31577
|
}
|
|
31228
31578
|
function getCachePath() {
|
|
31229
|
-
return
|
|
31579
|
+
return join13(getCacheDir(), "version.json");
|
|
31230
31580
|
}
|
|
31231
31581
|
async function readCache() {
|
|
31232
31582
|
try {
|
|
@@ -31365,7 +31715,7 @@ function printUpdateNotification(info) {
|
|
|
31365
31715
|
|
|
31366
31716
|
// packages/cli/src/commands/update-check.ts
|
|
31367
31717
|
var __filename3 = fileURLToPath3(import.meta.url);
|
|
31368
|
-
var __dirname3 =
|
|
31718
|
+
var __dirname3 = dirname11(__filename3);
|
|
31369
31719
|
async function updateCheckCommand() {
|
|
31370
31720
|
const currentVersion = getPackageVersion(__dirname3, "./package.json");
|
|
31371
31721
|
console.log(`@promptscript/cli v${currentVersion}`);
|
|
@@ -31393,7 +31743,7 @@ init_services();
|
|
|
31393
31743
|
init_console();
|
|
31394
31744
|
|
|
31395
31745
|
// packages/cli/src/utils/registry-scaffolder.ts
|
|
31396
|
-
import { join as
|
|
31746
|
+
import { join as join14 } from "path";
|
|
31397
31747
|
var SEED_BASE = `@meta {
|
|
31398
31748
|
id: "@core/base"
|
|
31399
31749
|
syntax: "1.0.0"
|
|
@@ -31494,14 +31844,14 @@ async function scaffoldRegistry(options, services) {
|
|
|
31494
31844
|
const createdFiles = [];
|
|
31495
31845
|
await fs4.mkdir(directory, { recursive: true });
|
|
31496
31846
|
const manifest = generateManifest(name, description, namespaces, seed);
|
|
31497
|
-
const manifestPath =
|
|
31847
|
+
const manifestPath = join14(directory, "registry-manifest.yaml");
|
|
31498
31848
|
await fs4.writeFile(manifestPath, manifest, "utf-8");
|
|
31499
31849
|
createdFiles.push(manifestPath);
|
|
31500
31850
|
const readme = generateReadme(name, description, namespaces);
|
|
31501
|
-
const readmePath =
|
|
31851
|
+
const readmePath = join14(directory, "README.md");
|
|
31502
31852
|
await fs4.writeFile(readmePath, readme, "utf-8");
|
|
31503
31853
|
createdFiles.push(readmePath);
|
|
31504
|
-
const gitignorePath =
|
|
31854
|
+
const gitignorePath = join14(directory, ".gitignore");
|
|
31505
31855
|
await fs4.writeFile(
|
|
31506
31856
|
gitignorePath,
|
|
31507
31857
|
".DS_Store\nnode_modules/\n*.log\n*.swp\n*.bak\n.env*\n",
|
|
@@ -31509,20 +31859,20 @@ async function scaffoldRegistry(options, services) {
|
|
|
31509
31859
|
);
|
|
31510
31860
|
createdFiles.push(gitignorePath);
|
|
31511
31861
|
for (const ns of namespaces) {
|
|
31512
|
-
const nsDir =
|
|
31862
|
+
const nsDir = join14(directory, ns);
|
|
31513
31863
|
await fs4.mkdir(nsDir, { recursive: true });
|
|
31514
31864
|
if (seed && ns === "@core") {
|
|
31515
|
-
const basePath =
|
|
31865
|
+
const basePath = join14(nsDir, "base.prs");
|
|
31516
31866
|
await fs4.writeFile(basePath, SEED_BASE, "utf-8");
|
|
31517
31867
|
createdFiles.push(basePath);
|
|
31518
|
-
const qualityPath =
|
|
31868
|
+
const qualityPath = join14(nsDir, "quality.prs");
|
|
31519
31869
|
await fs4.writeFile(qualityPath, SEED_QUALITY, "utf-8");
|
|
31520
31870
|
createdFiles.push(qualityPath);
|
|
31521
|
-
const securityPath =
|
|
31871
|
+
const securityPath = join14(nsDir, "security.prs");
|
|
31522
31872
|
await fs4.writeFile(securityPath, SEED_SECURITY, "utf-8");
|
|
31523
31873
|
createdFiles.push(securityPath);
|
|
31524
31874
|
} else {
|
|
31525
|
-
const gitkeepPath =
|
|
31875
|
+
const gitkeepPath = join14(nsDir, ".gitkeep");
|
|
31526
31876
|
await fs4.writeFile(gitkeepPath, "", "utf-8");
|
|
31527
31877
|
createdFiles.push(gitkeepPath);
|
|
31528
31878
|
}
|
|
@@ -31631,7 +31981,7 @@ Then reference configs with \`@inherit\` or \`@use\`:
|
|
|
31631
31981
|
}
|
|
31632
31982
|
|
|
31633
31983
|
// packages/cli/src/utils/resolve-target-directory.ts
|
|
31634
|
-
import { join as
|
|
31984
|
+
import { join as join15, resolve as resolve13 } from "path";
|
|
31635
31985
|
|
|
31636
31986
|
// packages/cli/src/utils/slugify.ts
|
|
31637
31987
|
function slugify(name) {
|
|
@@ -31642,7 +31992,7 @@ function slugify(name) {
|
|
|
31642
31992
|
async function resolveTargetDirectory(options, services) {
|
|
31643
31993
|
const { cwd, directoryArg, registryName, nonInteractive } = options;
|
|
31644
31994
|
if (directoryArg) {
|
|
31645
|
-
return
|
|
31995
|
+
return resolve13(directoryArg);
|
|
31646
31996
|
}
|
|
31647
31997
|
const empty = await isDirectoryEmpty(cwd, services.fs);
|
|
31648
31998
|
if (empty && nonInteractive) {
|
|
@@ -31656,9 +32006,9 @@ async function resolveTargetDirectory(options, services) {
|
|
|
31656
32006
|
{ name: `Subdirectory (./${slugify(registryName)})`, value: "subdirectory" }
|
|
31657
32007
|
]
|
|
31658
32008
|
});
|
|
31659
|
-
return choice === "here" ? cwd :
|
|
32009
|
+
return choice === "here" ? cwd : join15(cwd, slugify(registryName));
|
|
31660
32010
|
}
|
|
31661
|
-
return
|
|
32011
|
+
return join15(cwd, slugify(registryName));
|
|
31662
32012
|
}
|
|
31663
32013
|
async function isDirectoryEmpty(dir, fs4) {
|
|
31664
32014
|
const entries = await fs4.readdir(dir);
|
|
@@ -31749,15 +32099,15 @@ async function registryInitCommand(directory, options, services = createDefaultS
|
|
|
31749
32099
|
// packages/cli/src/commands/registry/validate.ts
|
|
31750
32100
|
init_services();
|
|
31751
32101
|
init_console();
|
|
31752
|
-
import { resolve as
|
|
32102
|
+
import { resolve as resolve14 } from "path";
|
|
31753
32103
|
|
|
31754
32104
|
// packages/cli/src/utils/registry-validator.ts
|
|
31755
|
-
import { join as
|
|
32105
|
+
import { join as join16 } from "path";
|
|
31756
32106
|
import { parse as parseYaml6 } from "yaml";
|
|
31757
32107
|
async function validateRegistry(registryPath, services) {
|
|
31758
32108
|
const { fs: fs4 } = services;
|
|
31759
32109
|
const issues = [];
|
|
31760
|
-
const manifestPath =
|
|
32110
|
+
const manifestPath = join16(registryPath, "registry-manifest.yaml");
|
|
31761
32111
|
if (!fs4.existsSync(manifestPath)) {
|
|
31762
32112
|
return {
|
|
31763
32113
|
valid: false,
|
|
@@ -31849,7 +32199,7 @@ async function validateRegistry(registryPath, services) {
|
|
|
31849
32199
|
});
|
|
31850
32200
|
}
|
|
31851
32201
|
if (entry.path) {
|
|
31852
|
-
const prsPath =
|
|
32202
|
+
const prsPath = join16(registryPath, entry.path);
|
|
31853
32203
|
if (!fs4.existsSync(prsPath)) {
|
|
31854
32204
|
issues.push({
|
|
31855
32205
|
severity: "error",
|
|
@@ -31884,7 +32234,7 @@ async function validateRegistry(registryPath, services) {
|
|
|
31884
32234
|
});
|
|
31885
32235
|
}
|
|
31886
32236
|
for (const ns of namespaceNames) {
|
|
31887
|
-
const nsDir =
|
|
32237
|
+
const nsDir = join16(registryPath, ns);
|
|
31888
32238
|
if (fs4.existsSync(nsDir)) {
|
|
31889
32239
|
try {
|
|
31890
32240
|
const files = await fs4.readdir(nsDir);
|
|
@@ -31898,7 +32248,7 @@ async function validateRegistry(registryPath, services) {
|
|
|
31898
32248
|
issues.push({
|
|
31899
32249
|
severity: "warning",
|
|
31900
32250
|
message: `Orphaned .prs file not in catalog: ${relativePath}`,
|
|
31901
|
-
path:
|
|
32251
|
+
path: join16(nsDir, file)
|
|
31902
32252
|
});
|
|
31903
32253
|
}
|
|
31904
32254
|
}
|
|
@@ -31949,7 +32299,7 @@ function detectCircularDependencies(catalog) {
|
|
|
31949
32299
|
|
|
31950
32300
|
// packages/cli/src/commands/registry/validate.ts
|
|
31951
32301
|
async function registryValidateCommand(path, options, services = createDefaultServices()) {
|
|
31952
|
-
const registryPath =
|
|
32302
|
+
const registryPath = resolve14(path ?? ".");
|
|
31953
32303
|
const spinner = createSpinner("Validating registry...").start();
|
|
31954
32304
|
try {
|
|
31955
32305
|
const result = await validateRegistry(registryPath, services);
|
|
@@ -32001,10 +32351,10 @@ async function registryValidateCommand(path, options, services = createDefaultSe
|
|
|
32001
32351
|
// packages/cli/src/commands/registry/publish.ts
|
|
32002
32352
|
init_services();
|
|
32003
32353
|
init_console();
|
|
32004
|
-
import { resolve as
|
|
32354
|
+
import { resolve as resolve15, join as join17 } from "path";
|
|
32005
32355
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
32006
32356
|
async function registryPublishCommand(path, options, services = createDefaultServices()) {
|
|
32007
|
-
const registryPath =
|
|
32357
|
+
const registryPath = resolve15(path ?? ".");
|
|
32008
32358
|
try {
|
|
32009
32359
|
if (!options.force) {
|
|
32010
32360
|
const spinner2 = createSpinner("Validating registry...").start();
|
|
@@ -32024,7 +32374,7 @@ async function registryPublishCommand(path, options, services = createDefaultSer
|
|
|
32024
32374
|
`Registry valid (${result.stats.catalogEntries} entries, ${result.stats.prsFiles} files)`
|
|
32025
32375
|
);
|
|
32026
32376
|
}
|
|
32027
|
-
const manifestPath =
|
|
32377
|
+
const manifestPath = join17(registryPath, "registry-manifest.yaml");
|
|
32028
32378
|
if (services.fs.existsSync(manifestPath)) {
|
|
32029
32379
|
const content = await services.fs.readFile(manifestPath, "utf-8");
|
|
32030
32380
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -32152,8 +32502,8 @@ async function registryListCommand() {
|
|
|
32152
32502
|
// packages/cli/src/commands/registry/add.ts
|
|
32153
32503
|
init_console();
|
|
32154
32504
|
import { readFile as readFile16, writeFile as writeFile7, mkdir as mkdir7 } from "fs/promises";
|
|
32155
|
-
import { existsSync as
|
|
32156
|
-
import { dirname as
|
|
32505
|
+
import { existsSync as existsSync17 } from "fs";
|
|
32506
|
+
import { dirname as dirname12 } from "path";
|
|
32157
32507
|
import { parse as parseYaml8, stringify as stringifyYaml } from "yaml";
|
|
32158
32508
|
init_user_config();
|
|
32159
32509
|
async function registryAddCommand(alias, url, options) {
|
|
@@ -32183,12 +32533,12 @@ async function registryAddCommand(alias, url, options) {
|
|
|
32183
32533
|
}
|
|
32184
32534
|
}
|
|
32185
32535
|
async function addToGlobalConfig(alias, url) {
|
|
32186
|
-
const configDir =
|
|
32187
|
-
if (!
|
|
32536
|
+
const configDir = dirname12(USER_CONFIG_PATH);
|
|
32537
|
+
if (!existsSync17(configDir)) {
|
|
32188
32538
|
await mkdir7(configDir, { recursive: true });
|
|
32189
32539
|
}
|
|
32190
32540
|
let config = { version: "1" };
|
|
32191
|
-
if (
|
|
32541
|
+
if (existsSync17(USER_CONFIG_PATH)) {
|
|
32192
32542
|
const content = await readFile16(USER_CONFIG_PATH, "utf-8");
|
|
32193
32543
|
const parsed = parseYaml8(content);
|
|
32194
32544
|
if (parsed && typeof parsed === "object") {
|
|
@@ -32238,8 +32588,8 @@ function registerRegistryCommands(registry2) {
|
|
|
32238
32588
|
|
|
32239
32589
|
// packages/cli/src/commands/lock.ts
|
|
32240
32590
|
import { writeFile as writeFile8, readFile as readFile18 } from "fs/promises";
|
|
32241
|
-
import { existsSync as
|
|
32242
|
-
import { resolve as
|
|
32591
|
+
import { existsSync as existsSync19 } from "fs";
|
|
32592
|
+
import { resolve as resolve16 } from "path";
|
|
32243
32593
|
import { parse as parseYaml9, stringify as stringifyYaml2 } from "yaml";
|
|
32244
32594
|
init_console();
|
|
32245
32595
|
init_src();
|
|
@@ -32247,9 +32597,9 @@ init_src();
|
|
|
32247
32597
|
// packages/cli/src/commands/lock-scanner.ts
|
|
32248
32598
|
init_src2();
|
|
32249
32599
|
import { readFile as readFile17 } from "fs/promises";
|
|
32250
|
-
import { existsSync as
|
|
32600
|
+
import { existsSync as existsSync18 } from "fs";
|
|
32251
32601
|
async function collectRemoteImports(entryPath, options) {
|
|
32252
|
-
if (!
|
|
32602
|
+
if (!existsSync18(entryPath)) {
|
|
32253
32603
|
return [];
|
|
32254
32604
|
}
|
|
32255
32605
|
const loader = new FileLoader({
|
|
@@ -32286,7 +32636,7 @@ async function collectRemoteImports(entryPath, options) {
|
|
|
32286
32636
|
results.push(marker);
|
|
32287
32637
|
}
|
|
32288
32638
|
} else {
|
|
32289
|
-
if (
|
|
32639
|
+
if (existsSync18(resolved)) {
|
|
32290
32640
|
await scan(resolved);
|
|
32291
32641
|
}
|
|
32292
32642
|
}
|
|
@@ -32312,8 +32662,8 @@ async function lockCommand(options) {
|
|
|
32312
32662
|
const aliases = config.registries ?? {};
|
|
32313
32663
|
const aliasEntries = Object.entries(aliases);
|
|
32314
32664
|
const projectRoot = process.cwd();
|
|
32315
|
-
const localPath =
|
|
32316
|
-
const entryPath = config.input?.entry ?
|
|
32665
|
+
const localPath = resolve16(projectRoot, ".promptscript");
|
|
32666
|
+
const entryPath = config.input?.entry ? resolve16(projectRoot, config.input.entry) : resolve16(localPath, "project.prs");
|
|
32317
32667
|
const scannedImports = await collectRemoteImports(entryPath, {
|
|
32318
32668
|
localPath,
|
|
32319
32669
|
registries: config.registries
|
|
@@ -32324,7 +32674,7 @@ async function lockCommand(options) {
|
|
|
32324
32674
|
return;
|
|
32325
32675
|
}
|
|
32326
32676
|
let existing = { version: LOCKFILE_VERSION, dependencies: {} };
|
|
32327
|
-
if (
|
|
32677
|
+
if (existsSync19(LOCKFILE_PATH)) {
|
|
32328
32678
|
try {
|
|
32329
32679
|
const raw = await readFile18(LOCKFILE_PATH, "utf-8");
|
|
32330
32680
|
const parsed = parseYaml9(raw, { maxAliasCount: 100 });
|
|
@@ -32393,7 +32743,7 @@ async function lockCommand(options) {
|
|
|
32393
32743
|
|
|
32394
32744
|
// packages/cli/src/commands/update.ts
|
|
32395
32745
|
import { writeFile as writeFile9, readFile as readFile19 } from "fs/promises";
|
|
32396
|
-
import { existsSync as
|
|
32746
|
+
import { existsSync as existsSync20 } from "fs";
|
|
32397
32747
|
import { parse as parseYaml10, stringify as stringifyYaml3 } from "yaml";
|
|
32398
32748
|
init_console();
|
|
32399
32749
|
init_src();
|
|
@@ -32416,7 +32766,7 @@ async function updateCommand(packageArg, options) {
|
|
|
32416
32766
|
return;
|
|
32417
32767
|
}
|
|
32418
32768
|
let existing = { version: LOCKFILE_VERSION, dependencies: {} };
|
|
32419
|
-
if (
|
|
32769
|
+
if (existsSync20(LOCKFILE_PATH)) {
|
|
32420
32770
|
try {
|
|
32421
32771
|
const raw = await readFile19(LOCKFILE_PATH, "utf-8");
|
|
32422
32772
|
const parsed = parseYaml10(raw, { maxAliasCount: 100 });
|
|
@@ -32480,12 +32830,12 @@ async function updateCommand(packageArg, options) {
|
|
|
32480
32830
|
init_console();
|
|
32481
32831
|
init_src();
|
|
32482
32832
|
import { readFile as readFile20, writeFile as writeFile10, mkdir as mkdir8, readdir as readdir5 } from "fs/promises";
|
|
32483
|
-
import { existsSync as
|
|
32484
|
-
import { join as
|
|
32833
|
+
import { existsSync as existsSync21 } from "fs";
|
|
32834
|
+
import { join as join18, resolve as resolve17 } from "path";
|
|
32485
32835
|
import { homedir as homedir4 } from "os";
|
|
32486
32836
|
import { parse as parseYaml11 } from "yaml";
|
|
32487
32837
|
var VENDOR_DIR = ".promptscript/vendor";
|
|
32488
|
-
var CACHE_BASE =
|
|
32838
|
+
var CACHE_BASE = join18(homedir4(), ".promptscript", "cache", "registries");
|
|
32489
32839
|
async function vendorSyncCommand(options) {
|
|
32490
32840
|
const spinner = createSpinner("Syncing vendor directory...").start();
|
|
32491
32841
|
try {
|
|
@@ -32503,13 +32853,13 @@ async function vendorSyncCommand(options) {
|
|
|
32503
32853
|
}
|
|
32504
32854
|
const results = [];
|
|
32505
32855
|
for (const [repoUrl, dep] of deps) {
|
|
32506
|
-
const cacheDir =
|
|
32507
|
-
if (!
|
|
32856
|
+
const cacheDir = join18(CACHE_BASE, repoUrl.replace(/[/:]/g, "_"), dep.version);
|
|
32857
|
+
if (!existsSync21(cacheDir)) {
|
|
32508
32858
|
results.push({ repoUrl, status: "missing" });
|
|
32509
32859
|
continue;
|
|
32510
32860
|
}
|
|
32511
32861
|
if (!options.dryRun) {
|
|
32512
|
-
const vendorTarget =
|
|
32862
|
+
const vendorTarget = resolve17(VENDOR_DIR, repoUrl.replace(/[/:]/g, "_"));
|
|
32513
32863
|
await mkdir8(vendorTarget, { recursive: true });
|
|
32514
32864
|
await copyDirectory(cacheDir, vendorTarget);
|
|
32515
32865
|
}
|
|
@@ -32555,7 +32905,7 @@ async function vendorCheckCommand(_options) {
|
|
|
32555
32905
|
spinner.warn("No dependencies in lockfile");
|
|
32556
32906
|
return;
|
|
32557
32907
|
}
|
|
32558
|
-
if (!
|
|
32908
|
+
if (!existsSync21(VENDOR_DIR)) {
|
|
32559
32909
|
spinner.fail("Vendor directory does not exist");
|
|
32560
32910
|
ConsoleOutput.muted("Run: prs vendor sync");
|
|
32561
32911
|
process.exitCode = 1;
|
|
@@ -32563,8 +32913,8 @@ async function vendorCheckCommand(_options) {
|
|
|
32563
32913
|
}
|
|
32564
32914
|
const issues = [];
|
|
32565
32915
|
for (const [repoUrl] of deps) {
|
|
32566
|
-
const vendorTarget =
|
|
32567
|
-
if (!
|
|
32916
|
+
const vendorTarget = resolve17(VENDOR_DIR, repoUrl.replace(/[/:]/g, "_"));
|
|
32917
|
+
if (!existsSync21(vendorTarget)) {
|
|
32568
32918
|
issues.push({ repoUrl, issue: "missing from vendor directory" });
|
|
32569
32919
|
}
|
|
32570
32920
|
}
|
|
@@ -32587,7 +32937,7 @@ async function vendorCheckCommand(_options) {
|
|
|
32587
32937
|
}
|
|
32588
32938
|
}
|
|
32589
32939
|
async function loadLockfile() {
|
|
32590
|
-
if (!
|
|
32940
|
+
if (!existsSync21(LOCKFILE_PATH)) {
|
|
32591
32941
|
return null;
|
|
32592
32942
|
}
|
|
32593
32943
|
try {
|
|
@@ -32601,8 +32951,8 @@ async function loadLockfile() {
|
|
|
32601
32951
|
async function copyDirectory(src, dest) {
|
|
32602
32952
|
const entries = await readdir5(src, { withFileTypes: true });
|
|
32603
32953
|
for (const entry of entries) {
|
|
32604
|
-
const srcPath =
|
|
32605
|
-
const destPath =
|
|
32954
|
+
const srcPath = join18(src, entry.name);
|
|
32955
|
+
const destPath = join18(dest, entry.name);
|
|
32606
32956
|
if (entry.isDirectory()) {
|
|
32607
32957
|
await mkdir8(destPath, { recursive: true });
|
|
32608
32958
|
await copyDirectory(srcPath, destPath);
|
|
@@ -32614,12 +32964,12 @@ async function copyDirectory(src, dest) {
|
|
|
32614
32964
|
}
|
|
32615
32965
|
|
|
32616
32966
|
// packages/cli/src/commands/resolve-cmd.ts
|
|
32617
|
-
import { existsSync as
|
|
32618
|
-
import { join as
|
|
32967
|
+
import { existsSync as existsSync22 } from "fs";
|
|
32968
|
+
import { join as join19 } from "path";
|
|
32619
32969
|
import { homedir as homedir5 } from "os";
|
|
32620
32970
|
init_user_config();
|
|
32621
32971
|
init_console();
|
|
32622
|
-
var CACHE_BASE2 =
|
|
32972
|
+
var CACHE_BASE2 = join19(homedir5(), ".promptscript", "cache", "registries");
|
|
32623
32973
|
async function resolveCommand(importPath, _options) {
|
|
32624
32974
|
try {
|
|
32625
32975
|
const configFile = findConfigFile();
|
|
@@ -32661,11 +33011,11 @@ async function resolveCommand(importPath, _options) {
|
|
|
32661
33011
|
}
|
|
32662
33012
|
const { repoUrl, path, version } = expanded;
|
|
32663
33013
|
const cacheVersion = version ?? "latest";
|
|
32664
|
-
const cacheDir =
|
|
32665
|
-
const cacheExists =
|
|
33014
|
+
const cacheDir = join19(CACHE_BASE2, repoUrl.replace(/[/:]/g, "_"), cacheVersion);
|
|
33015
|
+
const cacheExists = existsSync22(cacheDir);
|
|
32666
33016
|
const filePath = path.endsWith(".prs") ? path : `${path}.prs`;
|
|
32667
|
-
const cachedFile =
|
|
32668
|
-
const fileExists3 = cacheExists &&
|
|
33017
|
+
const cachedFile = join19(cacheDir, filePath);
|
|
33018
|
+
const fileExists3 = cacheExists && existsSync22(cachedFile);
|
|
32669
33019
|
ConsoleOutput.newline();
|
|
32670
33020
|
console.log(` Alias: ${aliasName} \u2192 ${repoUrl}`);
|
|
32671
33021
|
console.log(` Repo: ${repoUrl}`);
|
|
@@ -32682,7 +33032,7 @@ async function resolveCommand(importPath, _options) {
|
|
|
32682
33032
|
ConsoleOutput.newline();
|
|
32683
33033
|
} else {
|
|
32684
33034
|
const resolvedPath = importPath.endsWith(".prs") ? importPath : `${importPath}.prs`;
|
|
32685
|
-
const exists =
|
|
33035
|
+
const exists = existsSync22(resolvedPath);
|
|
32686
33036
|
ConsoleOutput.newline();
|
|
32687
33037
|
console.log(` Import: ${importPath}`);
|
|
32688
33038
|
console.log(` Type: local file`);
|
|
@@ -32699,8 +33049,8 @@ async function resolveCommand(importPath, _options) {
|
|
|
32699
33049
|
}
|
|
32700
33050
|
|
|
32701
33051
|
// packages/cli/src/commands/inspect.ts
|
|
32702
|
-
import { existsSync as
|
|
32703
|
-
import { resolve as
|
|
33052
|
+
import { existsSync as existsSync23 } from "fs";
|
|
33053
|
+
import { resolve as resolve18, basename as basename13 } from "path";
|
|
32704
33054
|
init_console();
|
|
32705
33055
|
async function inspectCommand(skillName, options) {
|
|
32706
33056
|
const isJson = options.format === "json";
|
|
@@ -32713,8 +33063,8 @@ async function inspectCommand(skillName, options) {
|
|
|
32713
33063
|
localPath: "./.promptscript",
|
|
32714
33064
|
registries: config.registries
|
|
32715
33065
|
});
|
|
32716
|
-
const entryPath =
|
|
32717
|
-
if (!
|
|
33066
|
+
const entryPath = resolve18("./.promptscript/project.prs");
|
|
33067
|
+
if (!existsSync23(entryPath)) {
|
|
32718
33068
|
spinner.stop();
|
|
32719
33069
|
ConsoleOutput.error(`Entry file not found: ${entryPath}`);
|
|
32720
33070
|
process.exitCode = 1;
|
|
@@ -32786,7 +33136,7 @@ function summarizeValue(val) {
|
|
|
32786
33136
|
return String(val);
|
|
32787
33137
|
}
|
|
32788
33138
|
function shortPath(source) {
|
|
32789
|
-
return
|
|
33139
|
+
return basename13(source);
|
|
32790
33140
|
}
|
|
32791
33141
|
function getPropertySource(propName, trace, baseSource) {
|
|
32792
33142
|
for (let i = trace.length - 1; i >= 0; i--) {
|
|
@@ -32894,8 +33244,8 @@ init_console();
|
|
|
32894
33244
|
// packages/cli/src/commands/import.ts
|
|
32895
33245
|
init_src3();
|
|
32896
33246
|
init_console();
|
|
32897
|
-
import { resolve as
|
|
32898
|
-
import { writeFileSync as writeFileSync2, mkdirSync, existsSync as
|
|
33247
|
+
import { resolve as resolve19, join as join20, basename as basename14 } from "path";
|
|
33248
|
+
import { writeFileSync as writeFileSync2, mkdirSync, existsSync as existsSync24 } from "fs";
|
|
32899
33249
|
import { stat as stat2, readdir as readdir6, readFile as readFile21, writeFile as writeFile11, mkdir as mkdir9 } from "fs/promises";
|
|
32900
33250
|
function parseInstructionFrontmatter(content) {
|
|
32901
33251
|
const match = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/.exec(content);
|
|
@@ -32923,10 +33273,10 @@ async function importDirectory(dirPath) {
|
|
|
32923
33273
|
}
|
|
32924
33274
|
const lines = ["@meta {", ' version: "1.0"', "}", "", "@guards {"];
|
|
32925
33275
|
for (const filename of instructionFiles) {
|
|
32926
|
-
const filePath =
|
|
33276
|
+
const filePath = join20(dirPath, filename);
|
|
32927
33277
|
const content = await readFile21(filePath, "utf-8");
|
|
32928
33278
|
const frontmatter = parseInstructionFrontmatter(content);
|
|
32929
|
-
const entryName =
|
|
33279
|
+
const entryName = basename14(filename).replace(/\.instructions\.md$/i, "");
|
|
32930
33280
|
if (frontmatter) {
|
|
32931
33281
|
const globPatterns = frontmatter.applyTo.map((p) => `"${p}"`).join(", ");
|
|
32932
33282
|
lines.push(` ${entryName}(${globPatterns}) {`);
|
|
@@ -32949,7 +33299,7 @@ async function importDirectory(dirPath) {
|
|
|
32949
33299
|
return lines.join("\n");
|
|
32950
33300
|
}
|
|
32951
33301
|
async function importCommand(file, options) {
|
|
32952
|
-
const filepath =
|
|
33302
|
+
const filepath = resolve19(file);
|
|
32953
33303
|
const inputStat = await stat2(filepath).catch(() => null);
|
|
32954
33304
|
if (inputStat?.isDirectory()) {
|
|
32955
33305
|
const prsContent = await importDirectory(filepath);
|
|
@@ -32959,7 +33309,7 @@ async function importCommand(file, options) {
|
|
|
32959
33309
|
}
|
|
32960
33310
|
const outputDir = options.output ?? ".promptscript";
|
|
32961
33311
|
await mkdir9(outputDir, { recursive: true });
|
|
32962
|
-
const outputPath =
|
|
33312
|
+
const outputPath = join20(outputDir, "imported.prs");
|
|
32963
33313
|
await writeFile11(outputPath, prsContent);
|
|
32964
33314
|
console.log(`\u2714 Imported directory to ${outputPath}`);
|
|
32965
33315
|
return;
|
|
@@ -32981,11 +33331,11 @@ async function importCommand(file, options) {
|
|
|
32981
33331
|
console.log(result.prsContent);
|
|
32982
33332
|
return;
|
|
32983
33333
|
}
|
|
32984
|
-
const outputDir =
|
|
32985
|
-
if (!
|
|
33334
|
+
const outputDir = resolve19(options.output ?? ".promptscript");
|
|
33335
|
+
if (!existsSync24(outputDir)) {
|
|
32986
33336
|
mkdirSync(outputDir, { recursive: true });
|
|
32987
33337
|
}
|
|
32988
|
-
const outputPath =
|
|
33338
|
+
const outputPath = resolve19(outputDir, "imported.prs");
|
|
32989
33339
|
writeFileSync2(outputPath, result.prsContent, "utf-8");
|
|
32990
33340
|
ConsoleOutput.success(`Written to ${outputPath}`);
|
|
32991
33341
|
if (options.validate) {
|
|
@@ -33100,18 +33450,18 @@ async function detectMarker(filePath) {
|
|
|
33100
33450
|
}
|
|
33101
33451
|
|
|
33102
33452
|
// packages/cli/src/hooks/debounce-lock.ts
|
|
33103
|
-
import { createHash as
|
|
33104
|
-
import { existsSync as
|
|
33453
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
33454
|
+
import { existsSync as existsSync25, writeFileSync as writeFileSync4, unlinkSync, statSync } from "node:fs";
|
|
33105
33455
|
import { tmpdir } from "node:os";
|
|
33106
|
-
import { join as
|
|
33456
|
+
import { join as join21 } from "node:path";
|
|
33107
33457
|
var STALE_THRESHOLD_MS = 3e4;
|
|
33108
33458
|
function getLockPath(projectDir) {
|
|
33109
|
-
const hash =
|
|
33110
|
-
return
|
|
33459
|
+
const hash = createHash3("md5").update(projectDir).digest("hex").slice(0, 12);
|
|
33460
|
+
return join21(tmpdir(), `prs-compile-${hash}.lock`);
|
|
33111
33461
|
}
|
|
33112
33462
|
function acquireLock(projectDir) {
|
|
33113
33463
|
const lockPath = getLockPath(projectDir);
|
|
33114
|
-
if (
|
|
33464
|
+
if (existsSync25(lockPath)) {
|
|
33115
33465
|
try {
|
|
33116
33466
|
const stat4 = statSync(lockPath);
|
|
33117
33467
|
const age = Date.now() - stat4.mtimeMs;
|
|
@@ -33219,9 +33569,10 @@ Usage: echo '{"file_path":"..."}' | prs hook ${action}
|
|
|
33219
33569
|
init_hooks();
|
|
33220
33570
|
|
|
33221
33571
|
// packages/cli/src/commands/skills.ts
|
|
33222
|
-
import { writeFile as writeFile12, readFile as readFile23, readdir as readdir7 } from "fs/promises";
|
|
33223
|
-
import { resolve as
|
|
33224
|
-
import { existsSync as
|
|
33572
|
+
import { writeFile as writeFile12, readFile as readFile23, readdir as readdir7, mkdtemp, rm } from "fs/promises";
|
|
33573
|
+
import { resolve as resolve20, join as join22, basename as basename15, dirname as dirname13 } from "path";
|
|
33574
|
+
import { existsSync as existsSync26 } from "fs";
|
|
33575
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
33225
33576
|
import { parse as parseYaml12, stringify as stringifyYaml4 } from "yaml";
|
|
33226
33577
|
init_console();
|
|
33227
33578
|
init_src();
|
|
@@ -33241,6 +33592,77 @@ function normalizeSkillSource(input2) {
|
|
|
33241
33592
|
}
|
|
33242
33593
|
return source;
|
|
33243
33594
|
}
|
|
33595
|
+
function extractSubPath(source) {
|
|
33596
|
+
const parts = source.replace(/^https?:\/\//, "").split("/");
|
|
33597
|
+
return parts.length > 3 ? parts.slice(3).join("/") : "";
|
|
33598
|
+
}
|
|
33599
|
+
function deriveSkillFolderName(source) {
|
|
33600
|
+
const subPath = extractSubPath(source);
|
|
33601
|
+
if (!subPath) return void 0;
|
|
33602
|
+
if (!subPath.toLowerCase().endsWith(".md")) return void 0;
|
|
33603
|
+
const parent = dirname13(subPath);
|
|
33604
|
+
if (parent === "." || parent === "") return void 0;
|
|
33605
|
+
return basename15(parent);
|
|
33606
|
+
}
|
|
33607
|
+
function collectExistingSkillNames(lockfile, exclude) {
|
|
33608
|
+
const names = /* @__PURE__ */ new Set();
|
|
33609
|
+
for (const [key, dep] of Object.entries(lockfile.dependencies)) {
|
|
33610
|
+
if (dep.source !== "md") continue;
|
|
33611
|
+
if (exclude && key === exclude) continue;
|
|
33612
|
+
const name = deriveSkillFolderName(key);
|
|
33613
|
+
if (name) names.add(name);
|
|
33614
|
+
}
|
|
33615
|
+
return names;
|
|
33616
|
+
}
|
|
33617
|
+
async function fetchAndValidateRemoteSkill(source, options) {
|
|
33618
|
+
const subPath = extractSubPath(source);
|
|
33619
|
+
if (!subPath || !subPath.toLowerCase().endsWith(".md")) {
|
|
33620
|
+
return void 0;
|
|
33621
|
+
}
|
|
33622
|
+
const repoUrl = extractRepoUrl(source);
|
|
33623
|
+
const tmp = await mkdtemp(join22(tmpdir2(), "prs-skill-validate-"));
|
|
33624
|
+
try {
|
|
33625
|
+
const gitRegistry = createGitRegistry({ url: repoUrl });
|
|
33626
|
+
await gitRegistry.cloneAtTag(repoUrl, options.version, tmp);
|
|
33627
|
+
const filePath = join22(tmp, subPath);
|
|
33628
|
+
if (!existsSync26(filePath)) {
|
|
33629
|
+
return {
|
|
33630
|
+
content: "",
|
|
33631
|
+
integrity: "",
|
|
33632
|
+
valid: false,
|
|
33633
|
+
issues: [
|
|
33634
|
+
{
|
|
33635
|
+
severity: "error",
|
|
33636
|
+
code: "SK000",
|
|
33637
|
+
message: `File '${subPath}' does not exist in ${repoUrl} at ${options.version}.`
|
|
33638
|
+
}
|
|
33639
|
+
]
|
|
33640
|
+
};
|
|
33641
|
+
}
|
|
33642
|
+
const content = await readFile23(filePath, "utf-8");
|
|
33643
|
+
const integrity = hashContent(Buffer.from(content, "utf-8"));
|
|
33644
|
+
const result = validateSkillFrontmatter(content, {
|
|
33645
|
+
filePath,
|
|
33646
|
+
existingNames: options.existingNames
|
|
33647
|
+
});
|
|
33648
|
+
return { content, integrity, valid: result.valid, issues: result.issues };
|
|
33649
|
+
} finally {
|
|
33650
|
+
await rm(tmp, { recursive: true, force: true }).catch(() => {
|
|
33651
|
+
});
|
|
33652
|
+
}
|
|
33653
|
+
}
|
|
33654
|
+
function printValidationIssues(issues) {
|
|
33655
|
+
if (issues.length === 0) return;
|
|
33656
|
+
ConsoleOutput.newline();
|
|
33657
|
+
const formatted = formatSkillValidationIssues(issues);
|
|
33658
|
+
for (const line of formatted.split("\n")) {
|
|
33659
|
+
if (line.includes("\u2717")) {
|
|
33660
|
+
ConsoleOutput.error(line);
|
|
33661
|
+
} else {
|
|
33662
|
+
ConsoleOutput.warn(line);
|
|
33663
|
+
}
|
|
33664
|
+
}
|
|
33665
|
+
}
|
|
33244
33666
|
var HEADER_DIRECTIVES = ["@use ", "@inherit ", "@meta "];
|
|
33245
33667
|
function extractRepoUrl(source) {
|
|
33246
33668
|
const parts = source.replace(/^https?:\/\//, "").split("/");
|
|
@@ -33268,8 +33690,8 @@ function validateRemoteSource(source) {
|
|
|
33268
33690
|
}
|
|
33269
33691
|
async function resolveEntryFile(fileFlag) {
|
|
33270
33692
|
if (fileFlag) {
|
|
33271
|
-
const resolved =
|
|
33272
|
-
if (!
|
|
33693
|
+
const resolved = resolve20(fileFlag);
|
|
33694
|
+
if (!existsSync26(resolved)) {
|
|
33273
33695
|
throw new Error(`File not found: ${resolved}`);
|
|
33274
33696
|
}
|
|
33275
33697
|
return resolved;
|
|
@@ -33279,24 +33701,24 @@ async function resolveEntryFile(fileFlag) {
|
|
|
33279
33701
|
try {
|
|
33280
33702
|
const config = await loadConfig();
|
|
33281
33703
|
if (config.input?.entry) {
|
|
33282
|
-
const entryPath =
|
|
33283
|
-
if (
|
|
33704
|
+
const entryPath = resolve20(config.input.entry);
|
|
33705
|
+
if (existsSync26(entryPath)) {
|
|
33284
33706
|
return entryPath;
|
|
33285
33707
|
}
|
|
33286
33708
|
}
|
|
33287
33709
|
} catch {
|
|
33288
33710
|
}
|
|
33289
33711
|
}
|
|
33290
|
-
const promptscriptDir =
|
|
33291
|
-
if (
|
|
33712
|
+
const promptscriptDir = resolve20(".promptscript");
|
|
33713
|
+
if (existsSync26(promptscriptDir)) {
|
|
33292
33714
|
const entries = await readdir7(promptscriptDir);
|
|
33293
33715
|
const prsFiles = entries.filter((f) => f.endsWith(".prs"));
|
|
33294
33716
|
if (prsFiles.length === 1) {
|
|
33295
|
-
return
|
|
33717
|
+
return resolve20(promptscriptDir, prsFiles[0]);
|
|
33296
33718
|
}
|
|
33297
33719
|
if (prsFiles.length > 1) {
|
|
33298
33720
|
if (prsFiles.includes("project.prs")) {
|
|
33299
|
-
return
|
|
33721
|
+
return resolve20(promptscriptDir, "project.prs");
|
|
33300
33722
|
}
|
|
33301
33723
|
throw new Error(
|
|
33302
33724
|
`Multiple .prs files found in .promptscript/. Use --file to specify which one.`
|
|
@@ -33340,7 +33762,7 @@ function extractUsePath(line) {
|
|
|
33340
33762
|
}
|
|
33341
33763
|
async function loadLockfile2() {
|
|
33342
33764
|
const defaultLockfile = { version: LOCKFILE_VERSION, dependencies: {} };
|
|
33343
|
-
if (!
|
|
33765
|
+
if (!existsSync26(LOCKFILE_PATH)) {
|
|
33344
33766
|
return defaultLockfile;
|
|
33345
33767
|
}
|
|
33346
33768
|
try {
|
|
@@ -33359,6 +33781,14 @@ async function saveLockfile(lockfile) {
|
|
|
33359
33781
|
async function skillsAddCommand(rawSource, options) {
|
|
33360
33782
|
const spinner = createSpinner("Adding skill...").start();
|
|
33361
33783
|
try {
|
|
33784
|
+
if (/^http:\/\//i.test(rawSource.trim())) {
|
|
33785
|
+
spinner.fail("Plain HTTP sources are not allowed (security)");
|
|
33786
|
+
ConsoleOutput.error(
|
|
33787
|
+
"Use https:// or git@host:owner/repo. Cleartext git transport is rejected to prevent man-in-the-middle attacks."
|
|
33788
|
+
);
|
|
33789
|
+
process.exitCode = 1;
|
|
33790
|
+
return;
|
|
33791
|
+
}
|
|
33362
33792
|
const source = normalizeSkillSource(rawSource);
|
|
33363
33793
|
const sourceError = validateRemoteSource(source);
|
|
33364
33794
|
if (sourceError) {
|
|
@@ -33387,15 +33817,52 @@ async function skillsAddCommand(rawSource, options) {
|
|
|
33387
33817
|
process.exitCode = 1;
|
|
33388
33818
|
return;
|
|
33389
33819
|
}
|
|
33820
|
+
const lockfile = await loadLockfile2();
|
|
33821
|
+
let integrity = "sha256-pending";
|
|
33822
|
+
let validationFailed = false;
|
|
33823
|
+
if (!options.skipValidation) {
|
|
33824
|
+
spinner.text = "Validating SKILL.md frontmatter...";
|
|
33825
|
+
try {
|
|
33826
|
+
const fetched = await fetchAndValidateRemoteSkill(source, {
|
|
33827
|
+
existingNames: collectExistingSkillNames(lockfile),
|
|
33828
|
+
version: "main"
|
|
33829
|
+
});
|
|
33830
|
+
if (fetched) {
|
|
33831
|
+
integrity = fetched.integrity || integrity;
|
|
33832
|
+
const hasErrors = !fetched.valid;
|
|
33833
|
+
const hasWarnings = fetched.issues.some((i) => i.severity === "warning");
|
|
33834
|
+
if (hasErrors || options.strict && hasWarnings) {
|
|
33835
|
+
spinner.fail("SKILL.md failed validation");
|
|
33836
|
+
printValidationIssues(fetched.issues);
|
|
33837
|
+
ConsoleOutput.newline();
|
|
33838
|
+
ConsoleOutput.muted(
|
|
33839
|
+
"Re-run with --skip-validation to bypass (not recommended) or fix the upstream SKILL.md."
|
|
33840
|
+
);
|
|
33841
|
+
process.exitCode = 1;
|
|
33842
|
+
validationFailed = true;
|
|
33843
|
+
} else if (fetched.issues.length > 0) {
|
|
33844
|
+
spinner.warn("SKILL.md has validation warnings");
|
|
33845
|
+
printValidationIssues(fetched.issues);
|
|
33846
|
+
spinner.start("Adding skill...");
|
|
33847
|
+
}
|
|
33848
|
+
}
|
|
33849
|
+
} catch (err) {
|
|
33850
|
+
spinner.warn("Could not validate SKILL.md ahead of time");
|
|
33851
|
+
ConsoleOutput.muted(
|
|
33852
|
+
`Reason: ${err instanceof Error ? err.message : String(err)}. Proceeding without frontmatter check.`
|
|
33853
|
+
);
|
|
33854
|
+
spinner.start("Adding skill...");
|
|
33855
|
+
}
|
|
33856
|
+
}
|
|
33857
|
+
if (validationFailed) return;
|
|
33390
33858
|
const insertionPoint = findInsertionPoint(lines);
|
|
33391
33859
|
const newLine = `@use ${source}`;
|
|
33392
33860
|
lines.splice(insertionPoint, 0, newLine);
|
|
33393
33861
|
const updatedContent = lines.join("\n");
|
|
33394
|
-
const lockfile = await loadLockfile2();
|
|
33395
33862
|
const lockEntry = {
|
|
33396
33863
|
version: "latest",
|
|
33397
33864
|
commit: validation.headCommit ?? "0000000000000000000000000000000000000000",
|
|
33398
|
-
integrity
|
|
33865
|
+
integrity,
|
|
33399
33866
|
source: "md"
|
|
33400
33867
|
};
|
|
33401
33868
|
lockfile.dependencies[source] = lockEntry;
|
|
@@ -33523,10 +33990,39 @@ async function skillsUpdateCommand(name, options) {
|
|
|
33523
33990
|
});
|
|
33524
33991
|
continue;
|
|
33525
33992
|
}
|
|
33993
|
+
let integrity = dep.integrity ?? "sha256-pending";
|
|
33994
|
+
if (!options.skipValidation) {
|
|
33995
|
+
try {
|
|
33996
|
+
const fetched = await fetchAndValidateRemoteSkill(key, {
|
|
33997
|
+
existingNames: collectExistingSkillNames(lockfile, key),
|
|
33998
|
+
version: dep.version === "latest" ? "main" : dep.version
|
|
33999
|
+
});
|
|
34000
|
+
if (fetched) {
|
|
34001
|
+
integrity = fetched.integrity || integrity;
|
|
34002
|
+
const hasErrors = !fetched.valid;
|
|
34003
|
+
const hasWarnings = fetched.issues.some((i) => i.severity === "warning");
|
|
34004
|
+
if (hasErrors || options.strict && hasWarnings) {
|
|
34005
|
+
skipped.push({
|
|
34006
|
+
key,
|
|
34007
|
+
reason: "SKILL.md failed validation after update"
|
|
34008
|
+
});
|
|
34009
|
+
printValidationIssues(fetched.issues);
|
|
34010
|
+
continue;
|
|
34011
|
+
} else if (hasWarnings) {
|
|
34012
|
+
ConsoleOutput.warn(`${key}: validation warnings`);
|
|
34013
|
+
printValidationIssues(fetched.issues);
|
|
34014
|
+
}
|
|
34015
|
+
}
|
|
34016
|
+
} catch (err) {
|
|
34017
|
+
ConsoleOutput.warn(
|
|
34018
|
+
`${key}: could not re-validate (${err instanceof Error ? err.message : String(err)})`
|
|
34019
|
+
);
|
|
34020
|
+
}
|
|
34021
|
+
}
|
|
33526
34022
|
lockfile.dependencies[key] = {
|
|
33527
34023
|
version: dep.version ?? "latest",
|
|
33528
34024
|
commit: validation.headCommit,
|
|
33529
|
-
integrity
|
|
34025
|
+
integrity,
|
|
33530
34026
|
source: "md",
|
|
33531
34027
|
fetchedAt
|
|
33532
34028
|
};
|
|
@@ -33573,7 +34069,7 @@ async function skillsUpdateCommand(name, options) {
|
|
|
33573
34069
|
|
|
33574
34070
|
// packages/cli/src/cli.ts
|
|
33575
34071
|
var __filename4 = fileURLToPath4(import.meta.url);
|
|
33576
|
-
var __dirname4 =
|
|
34072
|
+
var __dirname4 = dirname16(__filename4);
|
|
33577
34073
|
var program = new Command();
|
|
33578
34074
|
program.name("prs").description("PromptScript CLI - Standardize AI instructions").version(getPackageVersion(__dirname3, "./package.json")).option("--verbose", "Enable verbose output").option("--debug", "Enable debug output (includes verbose)").option("--quiet", "Suppress non-error output").hook("preAction", async (thisCommand, actionCommand) => {
|
|
33579
34075
|
const opts = thisCommand.opts();
|
|
@@ -33632,10 +34128,10 @@ program.command("resolve <import>").description("Show full resolution chain for
|
|
|
33632
34128
|
program.command("hook").argument("<action>", "Hook action: pre-edit or post-edit").description("Hook handler invoked by AI tools (not for direct use)").action(hookCommand);
|
|
33633
34129
|
program.command("hooks").argument("<action>", "Action: install or uninstall").argument("[tool]", "Tool: claude, gemini, copilot, cursor, windsurf, factory, cline").option("--all", "Install/uninstall for all detected tools").description("Manage PromptScript hooks for AI tools").action(hooksCommand);
|
|
33634
34130
|
var skills = program.command("skills").description("Manage PromptScript skills");
|
|
33635
|
-
skills.command("add <source>").description("Add a remote skill to the project").option("-f, --file <file>", "Target .prs file to modify").option("--dry-run", "Preview changes without writing").action((source, opts) => skillsAddCommand(source, opts));
|
|
34131
|
+
skills.command("add <source>").description("Add a remote skill to the project").option("-f, --file <file>", "Target .prs file to modify").option("--dry-run", "Preview changes without writing").option("--skip-validation", "Skip SKILL.md frontmatter validation (not recommended)").option("--strict", "Treat validation warnings as errors").action((source, opts) => skillsAddCommand(source, opts));
|
|
33636
34132
|
skills.command("remove <name>").description("Remove a skill from the project").option("--dry-run", "Preview changes without writing").action((name, opts) => skillsRemoveCommand(name, opts));
|
|
33637
34133
|
skills.command("list").description("List skills imported in the current project").action(() => skillsListCommand());
|
|
33638
|
-
skills.command("update [name]").description("Update lock entries for markdown-sourced skills").option("--dry-run", "Preview changes without writing").action((name, opts) => skillsUpdateCommand(name, opts));
|
|
34134
|
+
skills.command("update [name]").description("Update lock entries for markdown-sourced skills").option("--dry-run", "Preview changes without writing").option("--skip-validation", "Skip SKILL.md frontmatter validation (not recommended)").option("--strict", "Treat validation warnings as errors").action((name, opts) => skillsUpdateCommand(name, opts));
|
|
33639
34135
|
var registry = program.command("registry").description("Manage PromptScript registries");
|
|
33640
34136
|
registerRegistryCommands(registry);
|
|
33641
34137
|
function run(args = process.argv) {
|
|
@@ -33679,7 +34175,7 @@ toad-cache/dist/toad-cache.cjs:
|
|
|
33679
34175
|
(**
|
|
33680
34176
|
* toad-cache
|
|
33681
34177
|
*
|
|
33682
|
-
* @copyright
|
|
34178
|
+
* @copyright 2026 Igor Savin <kibertoad@gmail.com>
|
|
33683
34179
|
* @license MIT
|
|
33684
34180
|
* @version 3.7.0
|
|
33685
34181
|
*)
|