@papillon6814/copi 0.4.0 → 0.4.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 CHANGED
@@ -26,7 +26,7 @@ copi migrate --resolve [--dry-run]
26
26
  copi help
27
27
  ```
28
28
 
29
- `setup` requires an interactive terminal. It first asks where copi may look: only the Pi agent directories (`~/.pi/agent`, `~/.pi/agent-*`, `~/.pi/agent_*` and `~/.agents`; the default and usually fast), your whole `HOME` (this can take a minute or more; a progress bar advances per top-level folder), this project only, or both. Selecting the entire `HOME` is broad: it can inspect supported resources throughout that directory, including Pi profiles and the configured Pi agent directory, but skips worktree checkout copies (`.worktrees`, `.claude/worktrees`, `.config/superpowers/worktrees`, `.treehouse`). Selecting the current project scopes discovery to that project. Candidates with the same kind, name and content are merged into one row marked `(+N identical copies)`; the kept row prefers a source under `~/.pi` or `~/.agents`. Copi then asks for explicit authorization before searching; declining performs no search. Search warnings are summarized (for example, resources found outside the selected roots are counted rather than listed one by one), and missing files are skipped silently.
29
+ `setup` requires an interactive terminal. It first asks where copi may look: the Pi agent directories (`~/.pi/agent`, `~/.pi/agent-*`, `~/.pi/agent_*` and `~/.agents`; the default), this project only, or both. Settings and packages declared by those Pi profiles are expanded too, so configured paths elsewhere under `HOME` may be read; setup never walks your whole `HOME`. Symbolic links are not followed, and worktree checkout copies (`.worktrees`, `.claude/worktrees`, `.config/superpowers/worktrees`, `.treehouse`) are skipped. Selecting the current project scopes discovery to that project; when the current directory is `HOME` itself, only the Pi agent directories are offered. Candidates with the same kind, name and content are merged into one row marked `(+N identical copies)`; the kept row prefers a source under `~/.pi` or `~/.agents`. Copi then asks for explicit authorization before searching; declining performs no search. Search warnings are summarized (for example, resources found outside the selected roots are counted rather than listed one by one), and missing files are skipped silently.
30
30
 
31
31
  Candidates are listed with a source label, size and modification date, and entries whose name matches an already saved resource are marked `already saved`. After you select resources, name conflicts are resolved right away, before any preview: keep one of the same-named selections, rename the display name only (the files, body and destination are not changed), skip the resource (keeping the saved copy), or go back to the list.
32
32
 
@@ -404,20 +404,26 @@ export async function runSetup(libraryDir, roots) {
404
404
  assertModernCatalog(initial);
405
405
  assertNoNameConflicts(initial);
406
406
  intro("copi setup");
407
+ note([
408
+ "Copi keeps private copies of your Pi resources",
409
+ `(skills, subagents, instructions, settings) in ${displayPath(libraryDir, roots.homeDir)}`,
410
+ "and applies them to projects by group.",
411
+ "setup: find \u2192 review masked previews \u2192 save to groups.",
412
+ "Later: copi apply <group> <project>.",
413
+ "Your original files are never changed.",
414
+ ].join("\n"), "What copi does");
407
415
  const homeDir = roots.homeDir;
408
416
  const projectLabel = displayPath(roots.projectDir, homeDir);
409
417
  const homeBase = homeDir.length > 1 && homeDir.endsWith(path.sep) ? homeDir.slice(0, -1) : homeDir;
410
418
  const projectIsHome = Boolean(homeDir) && roots.projectDir === homeBase;
411
- const projectInsideHome = Boolean(homeDir) && !projectIsHome && roots.projectDir.startsWith(homeBase + path.sep);
412
419
  const locationOptions = [];
413
- if (homeDir) {
420
+ // Searching a project that is HOME itself would mean searching all of HOME, which setup no longer offers.
421
+ if (homeDir)
414
422
  locationOptions.push({ value: "pi", label: "Pi agent directories only \u2014 ~/.pi/agent, ~/.pi/agent-*, ~/.agents (fast)" });
415
- locationOptions.push({ value: "home", label: "All of HOME \u2014 ~ (can take a minute or more; worktree copies skipped)" });
416
- }
417
423
  if (!projectIsHome)
418
424
  locationOptions.push({ value: "project", label: `This project only \u2014 ${projectLabel} (fast)` });
419
- if (homeDir && !projectIsHome && !projectInsideHome)
420
- locationOptions.push({ value: "both", label: "Both" });
425
+ if (homeDir && !projectIsHome)
426
+ locationOptions.push({ value: "both", label: "Both \u2014 Pi agent directories and this project" });
421
427
  locationOptions.push({ value: "cancel", label: "Cancel" });
422
428
  const choice = await select({
423
429
  message: "Choose the locations copi may inspect",
@@ -428,15 +434,15 @@ export async function runSetup(libraryDir, roots) {
428
434
  cancel("Setup cancelled.");
429
435
  return;
430
436
  }
431
- const scopes = { home: choice === "home" || choice === "both", project: choice === "project" || choice === "both", ...(choice === "pi" ? { piDirs: true } : {}) };
432
- const piDirectories = choice === "pi" ? (await piAgentDirectories(homeDir)).directories : [];
437
+ const searchesPiDirs = choice === "pi" || choice === "both";
438
+ const scopes = { home: false, project: choice === "project" || choice === "both", ...(searchesPiDirs ? { piDirs: true } : {}) };
439
+ const piDirectories = searchesPiDirs ? (await piAgentDirectories(homeDir)).directories : [];
433
440
  const searchOptions = buildSearchOptions(roots, scopes); // every non-cancel choice enables at least one scope
434
441
  note([
435
- `HOME: ${scopes.home ? displayPath(roots.homeDir, homeDir) : "not selected"}`,
436
- `Pi agent directory: ${scopes.home ? displayPath(roots.agentDir, homeDir) : choice === "pi" ? (piDirectories.map((dir) => displayPath(dir, homeDir)).join(", ") || "none found") : "not selected"}`,
442
+ `Pi agent directories: ${searchesPiDirs ? (piDirectories.map((dir) => displayPath(dir, homeDir)).join(", ") || "none found") : "not selected"}`,
437
443
  `Project: ${scopes.project ? projectLabel : "not selected"}`,
438
444
  "Always excluded: entire directories named auth (authentication-specific code may be missing), auth.json, mcp-auth.json, oauth.json, .env* paths, history, cache/caches, .cache, .npm, node_modules, and .git. Folder searches also skip worktree copies (.worktrees, .claude/worktrees, .config/superpowers/worktrees, .treehouse).",
439
- ...(choice === "pi" ? ["Settings and packages declared by these Pi profiles may point elsewhere under HOME; those configured paths are read too."] : []),
445
+ ...(searchesPiDirs ? ["Settings and packages declared by these Pi profiles may point elsewhere under HOME; those configured paths are read too."] : []),
440
446
  "Secret detection is heuristic and cannot guarantee completeness. Preview text is masked by default.",
441
447
  ].join("\n"), "Search scope and exclusions");
442
448
  const authorized = await confirm({
@@ -449,7 +455,7 @@ export async function runSetup(libraryDir, roots) {
449
455
  }
450
456
  // A spinner covers the quick phases; once HOME's top-level directories are known, a bar fills one step per directory.
451
457
  let indicator = clackSpinner(inheritedSignal());
452
- indicator.start("Searching selected locations (searching all of HOME can take a minute or more)");
458
+ indicator.start("Searching selected locations");
453
459
  let bar;
454
460
  let barDone = 0;
455
461
  const onProgress = (event) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@papillon6814/copi",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Collect and organize reusable Pi coding-agent resources",
5
5
  "license": "MIT",
6
6
  "type": "module",