@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.
@@ -249,20 +249,26 @@ function _loadInstalledSkillsManifest(configDir) {
249
249
  for (const entry of entries) {
250
250
  if (!entry.isDirectory())
251
251
  continue;
252
- if (!entry.name.startsWith('gsd-'))
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 'gsd-' prefix to get the skill stem
255
- const stem = entry.name.slice(4); // 'gsd-'.length === 4
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 gsd-<stem>/ directory with no
263
- // SKILL.md must NOT register the stem — otherwise the capability would be
264
- // wrongly reported surfaced/enabled and a verify:post hook would render
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: hasBraveSearch,
188
- firecrawl: hasFirecrawl,
189
- exa_search: hasExaSearch,
190
- tavily_search: hasTavilySearch,
191
- ref_search: hasRefSearch,
192
- perplexity: hasPerplexity,
193
- jina: hasJina,
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 GSD's own installed skills — only surface project-specific skills
445
- if (entry.name.startsWith('gsd-'))
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))
@@ -10,6 +10,10 @@
10
10
  "brave_search",
11
11
  "firecrawl",
12
12
  "exa_search",
13
+ "tavily_search",
14
+ "ref_search",
15
+ "perplexity",
16
+ "jina",
13
17
  "workflow.plan_check",
14
18
  "workflow.verifier",
15
19
  "workflow.auto_advance",