@pareto4/pp-core 1.8.2 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +3 -0
- package/bin/install.js +9 -1
- package/gemini-extension.json +1 -1
- package/package.json +6 -3
- package/pareto-skills/pp-project-setup/SKILL.md +32 -440
- package/pp-core/bin/lib/capability-state.cjs +13 -7
- package/pp-core/bin/lib/config.cjs +7 -22
- package/pp-core/bin/lib/loop-resolver.cjs +6 -0
- package/pp-core/bin/lib/profile-output.cjs +4 -2
- package/pp-core/bin/shared/config-schema.manifest.json +4 -0
- package/pp-core/workflows/discovery-sprint.md +409 -16
- package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +250 -0
- package/pp-core/workflows/discovery-to-build.md +218 -48
- package/pp-core/workflows/discuss-phase.md +1 -1
- package/pp-core/workflows/execute-phase.md +1 -1
- package/pp-core/workflows/plan-phase.md +1 -1
- package/scripts/changeset/lint.cjs +20 -5
- package/scripts/lint-docs-required.cjs +10 -3
- package/scripts/release-channel.cjs +58 -0
- package/scripts/release-tarball-smoke.cjs +4 -0
- package/scripts/verify-opengsd-sweep.cjs +12 -0
- package/scripts/verify-rename-guard.cjs +333 -0
|
@@ -249,20 +249,26 @@ function _loadInstalledSkillsManifest(configDir) {
|
|
|
249
249
|
for (const entry of entries) {
|
|
250
250
|
if (!entry.isDirectory())
|
|
251
251
|
continue;
|
|
252
|
-
|
|
252
|
+
// Dual-prefix match: current 'pp-' naming plus legacy 'gsd-' directories
|
|
253
|
+
// (backward compatibility retained per D-11 keep-token policy). Mirrors
|
|
254
|
+
// the established idiom in src/init.cts's buildSkillManifest (commit
|
|
255
|
+
// 242aab99).
|
|
256
|
+
const isPp = entry.name.startsWith('pp-');
|
|
257
|
+
const isGsd = entry.name.startsWith('gsd-');
|
|
258
|
+
if (!isPp && !isGsd)
|
|
253
259
|
continue;
|
|
254
|
-
// Strip the
|
|
255
|
-
const stem = entry.name.slice(
|
|
260
|
+
// Strip the prefix to get the skill stem ('pp-'.length === 3, 'gsd-'.length === 4)
|
|
261
|
+
const stem = entry.name.slice(isPp ? 3 : 4);
|
|
256
262
|
if (!stem)
|
|
257
263
|
continue;
|
|
258
264
|
const skillMdPath = node_path_1.default.join(skillsDir, entry.name, 'SKILL.md');
|
|
259
265
|
// Parity with loadSkillsManifest: a stem exists only when its artifact
|
|
260
266
|
// file is present. loadSkillsManifest registers a stem per .md FILE (and
|
|
261
267
|
// tolerates an unreadable file as []), but never invents a stem for which
|
|
262
|
-
// no file exists. Mirror that here: a stale
|
|
263
|
-
// SKILL.md must NOT register the stem — otherwise the
|
|
264
|
-
// wrongly reported surfaced/enabled and a
|
|
265
|
-
// for a skill that cannot run.
|
|
268
|
+
// no file exists. Mirror that here: a stale pp-<stem>/ or gsd-<stem>/
|
|
269
|
+
// directory with no SKILL.md must NOT register the stem — otherwise the
|
|
270
|
+
// capability would be wrongly reported surfaced/enabled and a
|
|
271
|
+
// verify:post hook would render for a skill that cannot run.
|
|
266
272
|
if (!node_fs_1.default.existsSync(skillMdPath))
|
|
267
273
|
continue;
|
|
268
274
|
let content = '';
|
|
@@ -143,21 +143,6 @@ function validateShipPrBodySections(value) {
|
|
|
143
143
|
function buildNewProjectConfig(userChoices) {
|
|
144
144
|
const choices = userChoices || {};
|
|
145
145
|
const homedir = node_os_1.default.homedir();
|
|
146
|
-
// Detect API key availability
|
|
147
|
-
const braveKeyFile = node_path_1.default.join(homedir, '.gsd', 'brave_api_key');
|
|
148
|
-
const hasBraveSearch = !!(process.env['BRAVE_API_KEY'] || node_fs_1.default.existsSync(braveKeyFile));
|
|
149
|
-
const firecrawlKeyFile = node_path_1.default.join(homedir, '.gsd', 'firecrawl_api_key');
|
|
150
|
-
const hasFirecrawl = !!(process.env['FIRECRAWL_API_KEY'] || node_fs_1.default.existsSync(firecrawlKeyFile));
|
|
151
|
-
const exaKeyFile = node_path_1.default.join(homedir, '.gsd', 'exa_api_key');
|
|
152
|
-
const hasExaSearch = !!(process.env['EXA_API_KEY'] || node_fs_1.default.existsSync(exaKeyFile));
|
|
153
|
-
const tavilyKeyFile = node_path_1.default.join(homedir, '.gsd', 'tavily_api_key');
|
|
154
|
-
const hasTavilySearch = !!(process.env['TAVILY_API_KEY'] || node_fs_1.default.existsSync(tavilyKeyFile));
|
|
155
|
-
const refKeyFile = node_path_1.default.join(homedir, '.gsd', 'ref_api_key');
|
|
156
|
-
const hasRefSearch = !!(process.env['REF_API_KEY'] || node_fs_1.default.existsSync(refKeyFile));
|
|
157
|
-
const perplexityKeyFile = node_path_1.default.join(homedir, '.gsd', 'perplexity_api_key');
|
|
158
|
-
const hasPerplexity = !!(process.env['PERPLEXITY_API_KEY'] || node_fs_1.default.existsSync(perplexityKeyFile));
|
|
159
|
-
const jinaKeyFile = node_path_1.default.join(homedir, '.gsd', 'jina_api_key');
|
|
160
|
-
const hasJina = !!(process.env['JINA_API_KEY'] || node_fs_1.default.existsSync(jinaKeyFile));
|
|
161
146
|
// Load user-level defaults from ~/.gsd/defaults.json if available
|
|
162
147
|
const globalDefaultsPath = node_path_1.default.join(homedir, '.gsd', 'defaults.json');
|
|
163
148
|
let userDefaults = {};
|
|
@@ -184,13 +169,13 @@ function buildNewProjectConfig(userChoices) {
|
|
|
184
169
|
commit_docs: CONFIG_DEFAULTS.commit_docs,
|
|
185
170
|
parallelization: CONFIG_DEFAULTS.parallelization,
|
|
186
171
|
search_gitignored: CONFIG_DEFAULTS.search_gitignored,
|
|
187
|
-
brave_search:
|
|
188
|
-
firecrawl:
|
|
189
|
-
exa_search:
|
|
190
|
-
tavily_search:
|
|
191
|
-
ref_search:
|
|
192
|
-
perplexity:
|
|
193
|
-
jina:
|
|
172
|
+
brave_search: false,
|
|
173
|
+
firecrawl: false,
|
|
174
|
+
exa_search: false,
|
|
175
|
+
tavily_search: false,
|
|
176
|
+
ref_search: false,
|
|
177
|
+
perplexity: false,
|
|
178
|
+
jina: false,
|
|
194
179
|
git: {
|
|
195
180
|
branching_strategy: CONFIG_DEFAULTS.branching_strategy,
|
|
196
181
|
create_tag: true,
|
|
@@ -461,6 +461,12 @@ function cmdLoopRenderHooks(cwd, point, raw, options = {}) {
|
|
|
461
461
|
if (state.warnings && state.warnings.length > 0) {
|
|
462
462
|
envelope.warnings = state.warnings;
|
|
463
463
|
}
|
|
464
|
+
// No rawValue third argument, so --raw emits the JSON envelope rather than
|
|
465
|
+
// plain text. This is deliberate and load-bearing: 23 workflow call sites do
|
|
466
|
+
// `HOOKS_JSON=$(pp_run loop render-hooks <point> --raw)` and read `activeHooks`
|
|
467
|
+
// off the parsed envelope. Callers who want the human-readable text read the
|
|
468
|
+
// envelope's `rendered` field. Same convention as the deliberate
|
|
469
|
+
// `output(result, raw, undefined)` sites in src/check-command-router.cts.
|
|
464
470
|
coreOutput(envelope, raw);
|
|
465
471
|
}
|
|
466
472
|
module.exports = {
|
|
@@ -441,8 +441,10 @@ function generateSkillsSection(cwd) {
|
|
|
441
441
|
for (const entry of entries) {
|
|
442
442
|
if (!entry.isDirectory())
|
|
443
443
|
continue;
|
|
444
|
-
// Skip
|
|
445
|
-
|
|
444
|
+
// Skip pp-core's own installed skills (current 'pp-' naming plus legacy
|
|
445
|
+
// 'gsd-' directories, backward compatibility retained) — only surface
|
|
446
|
+
// project-specific skills.
|
|
447
|
+
if (entry.name.startsWith('pp-') || entry.name.startsWith('gsd-'))
|
|
446
448
|
continue;
|
|
447
449
|
const skillMdPath = node_path_1.default.join(absDir, entry.name, 'SKILL.md');
|
|
448
450
|
if (!node_fs_1.default.existsSync(skillMdPath))
|