@thiagodiogo/pscode 2.3.0 → 2.4.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/dist/core/init.d.ts +0 -2
- package/dist/core/init.js +7 -77
- package/dist/core/profile-sync-drift.js +1 -15
- package/dist/core/profiles.d.ts +1 -1
- package/dist/core/profiles.js +0 -13
- package/dist/core/shared/index.d.ts +1 -0
- package/dist/core/shared/index.js +1 -0
- package/dist/core/shared/prune-orphans.d.ts +39 -0
- package/dist/core/shared/prune-orphans.js +149 -0
- package/dist/core/shared/skill-generation.js +2 -14
- package/dist/core/shared/tool-detection.d.ts +2 -2
- package/dist/core/shared/tool-detection.js +1 -13
- package/dist/core/templates/skill-templates.d.ts +1 -7
- package/dist/core/templates/skill-templates.js +1 -7
- package/dist/core/templates/workflows/{archive-change.d.ts → complete-change.d.ts} +1 -1
- package/dist/core/templates/workflows/{archive-change.js → complete-change.js} +2 -2
- package/dist/core/update.d.ts +0 -20
- package/dist/core/update.js +29 -115
- package/package.json +1 -1
- package/dist/core/templates/workflows/bulk-archive-change.d.ts +0 -10
- package/dist/core/templates/workflows/bulk-archive-change.js +0 -491
- package/dist/core/templates/workflows/continue-change.d.ts +0 -10
- package/dist/core/templates/workflows/continue-change.js +0 -233
- package/dist/core/templates/workflows/ff-change.d.ts +0 -10
- package/dist/core/templates/workflows/ff-change.js +0 -199
- package/dist/core/templates/workflows/new-change.d.ts +0 -10
- package/dist/core/templates/workflows/new-change.js +0 -142
- package/dist/core/templates/workflows/onboard.d.ts +0 -10
- package/dist/core/templates/workflows/onboard.js +0 -606
- package/dist/core/templates/workflows/verify-change.d.ts +0 -10
- package/dist/core/templates/workflows/verify-change.js +0 -337
package/dist/core/init.d.ts
CHANGED
package/dist/core/init.js
CHANGED
|
@@ -19,9 +19,9 @@ import { generateCommands, CommandAdapterRegistry, } from './command-generation/
|
|
|
19
19
|
import { detectLegacyArtifacts, cleanupLegacyArtifacts, formatCleanupSummary, formatDetectionSummary, } from './legacy-cleanup.js';
|
|
20
20
|
import { detectLegacyToolArtifacts, runLegacyToolMigration, formatLegacyToolDetectionSummary, formatLegacyToolMigrationSummary, pscodeDirExists, } from './openspec-migration.js';
|
|
21
21
|
import { runTrelloInitPrompt } from './trello-init-prompt.js';
|
|
22
|
-
import { getToolsWithSkillsDir, getToolStates, getSkillTemplates, getCommandContents, generateSkillContent, } from './shared/index.js';
|
|
22
|
+
import { getToolsWithSkillsDir, getToolStates, getSkillTemplates, getCommandContents, generateSkillContent, pruneOrphansForTool, } from './shared/index.js';
|
|
23
23
|
import { getGlobalConfig } from './global-config.js';
|
|
24
|
-
import { getProfileWorkflows, isValidProfile, DEFAULT_PROFILE, PROFILES
|
|
24
|
+
import { getProfileWorkflows, isValidProfile, DEFAULT_PROFILE, PROFILES } from './profiles.js';
|
|
25
25
|
import { detectDixiStack, getDixiStackFamily, getDixiStackLabel, installDixiExtras, migrateLegacyPastelsddDir } from './presets/dixi.js';
|
|
26
26
|
import { stringify as stringifyYaml } from 'yaml';
|
|
27
27
|
import { parse as parseYaml } from 'yaml';
|
|
@@ -38,31 +38,6 @@ const PROGRESS_SPINNER = {
|
|
|
38
38
|
interval: 80,
|
|
39
39
|
frames: ['░░░', '▒░░', '▒▒░', '▒▒▒', '▓▒▒', '▓▓▒', '▓▓▓', '▒▓▓', '░▒▓'],
|
|
40
40
|
};
|
|
41
|
-
const WORKFLOW_TO_SKILL_DIR = {
|
|
42
|
-
'explore': 'pscode-explore',
|
|
43
|
-
'new': 'pscode-new-change',
|
|
44
|
-
'continue': 'pscode-continue-change',
|
|
45
|
-
'apply': 'pscode-apply-change',
|
|
46
|
-
'ff': 'pscode-ff-change',
|
|
47
|
-
'complete': 'pscode-archive-change',
|
|
48
|
-
'bulk-archive': 'pscode-bulk-archive-change',
|
|
49
|
-
'verify': 'pscode-verify-change',
|
|
50
|
-
'onboard': 'pscode-onboard',
|
|
51
|
-
'propose': 'pscode-propose',
|
|
52
|
-
// Trello-specific workflows
|
|
53
|
-
'trello-setup': 'pscode-trello-setup',
|
|
54
|
-
'draft': 'pscode-trello-draft',
|
|
55
|
-
// Productivity workflows
|
|
56
|
-
'handoff': 'pscode-handoff',
|
|
57
|
-
// Dixi-specific workflows
|
|
58
|
-
'rfc': 'pscode-dixi-rfc',
|
|
59
|
-
'design': 'pscode-dixi-design',
|
|
60
|
-
'tasks': 'pscode-dixi-tasks',
|
|
61
|
-
'arch-check': 'pscode-dixi-arch-check',
|
|
62
|
-
'adr': 'pscode-dixi-adr',
|
|
63
|
-
'jira-sync': 'pscode-dixi-jira-sync',
|
|
64
|
-
'dod': 'pscode-dixi-dod',
|
|
65
|
-
};
|
|
66
41
|
// -----------------------------------------------------------------------------
|
|
67
42
|
// Init Command Class
|
|
68
43
|
// -----------------------------------------------------------------------------
|
|
@@ -529,10 +504,6 @@ export class InitCommand {
|
|
|
529
504
|
await FileSystemUtils.writeFile(skillFile, skillContent);
|
|
530
505
|
}
|
|
531
506
|
}
|
|
532
|
-
if (!shouldGenerateSkills) {
|
|
533
|
-
const skillsDir = path.join(projectPath, tool.skillsDir, 'skills');
|
|
534
|
-
removedSkillCount += await this.removeSkillDirs(skillsDir);
|
|
535
|
-
}
|
|
536
507
|
// Generate commands if delivery includes commands
|
|
537
508
|
if (shouldGenerateCommands) {
|
|
538
509
|
const adapter = CommandAdapterRegistry.get(tool.value);
|
|
@@ -547,9 +518,11 @@ export class InitCommand {
|
|
|
547
518
|
commandsSkipped.push(tool.value);
|
|
548
519
|
}
|
|
549
520
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
521
|
+
// Prune by filesystem scan: drop any Pscode-managed artifact not desired
|
|
522
|
+
// for the active profile/delivery, including orphans of removed workflows.
|
|
523
|
+
const pruned = pruneOrphansForTool(projectPath, tool.value, workflows, delivery);
|
|
524
|
+
removedSkillCount += pruned.removedSkillDirs;
|
|
525
|
+
removedCommandCount += pruned.removedCommandFiles;
|
|
553
526
|
spinner.succeed(`Setup complete for ${tool.name}`);
|
|
554
527
|
if (tool.wasConfigured) {
|
|
555
528
|
refreshedTools.push(tool);
|
|
@@ -689,10 +662,6 @@ export class InitCommand {
|
|
|
689
662
|
console.log(chalk.bold('Getting started:'));
|
|
690
663
|
console.log(' Start your first change: /ps:propose "your idea"');
|
|
691
664
|
}
|
|
692
|
-
else if (activeWorkflows.includes('new')) {
|
|
693
|
-
console.log(chalk.bold('Getting started:'));
|
|
694
|
-
console.log(' Start your first change: /ps:new "your idea"');
|
|
695
|
-
}
|
|
696
665
|
else {
|
|
697
666
|
console.log("Done. Run 'pscode config profile' to switch profiles.");
|
|
698
667
|
}
|
|
@@ -773,44 +742,5 @@ export class InitCommand {
|
|
|
773
742
|
spinner: PROGRESS_SPINNER,
|
|
774
743
|
}).start();
|
|
775
744
|
}
|
|
776
|
-
async removeSkillDirs(skillsDir) {
|
|
777
|
-
let removed = 0;
|
|
778
|
-
for (const workflow of ALL_WORKFLOWS) {
|
|
779
|
-
const dirName = WORKFLOW_TO_SKILL_DIR[workflow];
|
|
780
|
-
if (!dirName)
|
|
781
|
-
continue;
|
|
782
|
-
const skillDir = path.join(skillsDir, dirName);
|
|
783
|
-
try {
|
|
784
|
-
if (fs.existsSync(skillDir)) {
|
|
785
|
-
await fs.promises.rm(skillDir, { recursive: true, force: true });
|
|
786
|
-
removed++;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
catch {
|
|
790
|
-
// Ignore errors
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
return removed;
|
|
794
|
-
}
|
|
795
|
-
async removeCommandFiles(projectPath, toolId) {
|
|
796
|
-
let removed = 0;
|
|
797
|
-
const adapter = CommandAdapterRegistry.get(toolId);
|
|
798
|
-
if (!adapter)
|
|
799
|
-
return 0;
|
|
800
|
-
for (const workflow of ALL_WORKFLOWS) {
|
|
801
|
-
const cmdPath = adapter.getFilePath(workflow);
|
|
802
|
-
const fullPath = path.isAbsolute(cmdPath) ? cmdPath : path.join(projectPath, cmdPath);
|
|
803
|
-
try {
|
|
804
|
-
if (fs.existsSync(fullPath)) {
|
|
805
|
-
await fs.promises.unlink(fullPath);
|
|
806
|
-
removed++;
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
catch {
|
|
810
|
-
// Ignore errors
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
return removed;
|
|
814
|
-
}
|
|
815
745
|
}
|
|
816
746
|
//# sourceMappingURL=init.js.map
|
|
@@ -9,14 +9,8 @@ import { COMMAND_IDS, getConfiguredTools } from './shared/index.js';
|
|
|
9
9
|
*/
|
|
10
10
|
export const WORKFLOW_TO_SKILL_DIR = {
|
|
11
11
|
'explore': 'pscode-explore',
|
|
12
|
-
'new': 'pscode-new-change',
|
|
13
|
-
'continue': 'pscode-continue-change',
|
|
14
12
|
'apply': 'pscode-apply-change',
|
|
15
|
-
'
|
|
16
|
-
'complete': 'pscode-archive-change',
|
|
17
|
-
'bulk-archive': 'pscode-bulk-archive-change',
|
|
18
|
-
'verify': 'pscode-verify-change',
|
|
19
|
-
'onboard': 'pscode-onboard',
|
|
13
|
+
'complete': 'pscode-complete-change',
|
|
20
14
|
'propose': 'pscode-propose',
|
|
21
15
|
// Trello-specific workflows
|
|
22
16
|
'trello-setup': 'pscode-trello-setup',
|
|
@@ -24,14 +18,6 @@ export const WORKFLOW_TO_SKILL_DIR = {
|
|
|
24
18
|
// Productivity workflows
|
|
25
19
|
'handoff': 'pscode-handoff',
|
|
26
20
|
'grill-me': 'pscode-grill-me',
|
|
27
|
-
// Dixi-specific workflows
|
|
28
|
-
'rfc': 'pscode-dixi-rfc',
|
|
29
|
-
'design': 'pscode-dixi-design',
|
|
30
|
-
'tasks': 'pscode-dixi-tasks',
|
|
31
|
-
'arch-check': 'pscode-dixi-arch-check',
|
|
32
|
-
'adr': 'pscode-dixi-adr',
|
|
33
|
-
'jira-sync': 'pscode-dixi-jira-sync',
|
|
34
|
-
'dod': 'pscode-dixi-dod',
|
|
35
21
|
};
|
|
36
22
|
function toKnownWorkflows(workflows) {
|
|
37
23
|
return workflows.filter((workflow) => ALL_WORKFLOWS.includes(workflow));
|
package/dist/core/profiles.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* `pscode init --profile <name>` or `pscode config profile <name>`.
|
|
6
6
|
* The workflow lists are fixed in code — users cannot customise them.
|
|
7
7
|
*/
|
|
8
|
-
export declare const ALL_WORKFLOWS: readonly ["propose", "explore", "
|
|
8
|
+
export declare const ALL_WORKFLOWS: readonly ["propose", "explore", "apply", "complete", "trello-setup", "draft", "handoff", "grill-me"];
|
|
9
9
|
export type WorkflowId = (typeof ALL_WORKFLOWS)[number];
|
|
10
10
|
export interface ProfileDefinition {
|
|
11
11
|
description: string;
|
package/dist/core/profiles.js
CHANGED
|
@@ -8,23 +8,10 @@
|
|
|
8
8
|
export const ALL_WORKFLOWS = [
|
|
9
9
|
'propose',
|
|
10
10
|
'explore',
|
|
11
|
-
'new',
|
|
12
|
-
'continue',
|
|
13
11
|
'apply',
|
|
14
|
-
'ff',
|
|
15
12
|
'complete',
|
|
16
|
-
'bulk-archive',
|
|
17
|
-
'verify',
|
|
18
|
-
'onboard',
|
|
19
13
|
'trello-setup',
|
|
20
14
|
'draft',
|
|
21
|
-
'rfc',
|
|
22
|
-
'design',
|
|
23
|
-
'tasks',
|
|
24
|
-
'arch-check',
|
|
25
|
-
'adr',
|
|
26
|
-
'jira-sync',
|
|
27
|
-
'dod',
|
|
28
15
|
'handoff',
|
|
29
16
|
'grill-me',
|
|
30
17
|
];
|
|
@@ -5,4 +5,5 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { SKILL_NAMES, type SkillName, COMMAND_IDS, type CommandId, type ToolSkillStatus, type ToolVersionStatus, getToolsWithSkillsDir, getToolSkillStatus, getToolStates, extractGeneratedByVersion, getToolVersionStatus, getConfiguredTools, getAllToolVersionStatus, } from './tool-detection.js';
|
|
7
7
|
export { type SkillTemplateEntry, type CommandTemplateEntry, getSkillTemplates, getCommandTemplates, getCommandContents, generateSkillContent, } from './skill-generation.js';
|
|
8
|
+
export { type PruneResult, pruneOrphans, pruneOrphansForTool, } from './prune-orphans.js';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -5,4 +5,5 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { SKILL_NAMES, COMMAND_IDS, getToolsWithSkillsDir, getToolSkillStatus, getToolStates, extractGeneratedByVersion, getToolVersionStatus, getConfiguredTools, getAllToolVersionStatus, } from './tool-detection.js';
|
|
7
7
|
export { getSkillTemplates, getCommandTemplates, getCommandContents, generateSkillContent, } from './skill-generation.js';
|
|
8
|
+
export { pruneOrphans, pruneOrphansForTool, } from './prune-orphans.js';
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orphan Artifact Pruning
|
|
3
|
+
*
|
|
4
|
+
* Removes Pscode-managed skill directories and slash command files that no
|
|
5
|
+
* longer correspond to a desired workflow, by **scanning the filesystem**
|
|
6
|
+
* rather than iterating `ALL_WORKFLOWS`. This is what lets `init`/`update`
|
|
7
|
+
* clean up artifacts of workflows that were deleted (or renamed) from the
|
|
8
|
+
* enum entirely — a loop over `ALL_WORKFLOWS` would never visit them.
|
|
9
|
+
*
|
|
10
|
+
* The "desired" set is computed from the same generators used when writing
|
|
11
|
+
* (`getSkillTemplates` / `adapter.getFilePath`), so there is a single source
|
|
12
|
+
* of truth and a valid artifact is never removed.
|
|
13
|
+
*
|
|
14
|
+
* Removal is strictly limited to Pscode-managed naming patterns (skill dirs
|
|
15
|
+
* prefixed `pscode-`; command files matching the adapter's own filename
|
|
16
|
+
* pattern), so user files are preserved.
|
|
17
|
+
*/
|
|
18
|
+
import type { Delivery } from '../global-config.js';
|
|
19
|
+
export interface PruneResult {
|
|
20
|
+
removedSkillDirs: number;
|
|
21
|
+
removedCommandFiles: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Scans installed Pscode artifacts for a single tool and removes orphans —
|
|
25
|
+
* artifacts that do not belong to a desired workflow for the active delivery.
|
|
26
|
+
*
|
|
27
|
+
* - Skills: every `pscode-*` directory whose name is not in the desired set is
|
|
28
|
+
* removed. When skills are not generated (commands-only delivery) the desired
|
|
29
|
+
* set is empty, so all Pscode skill dirs are removed.
|
|
30
|
+
* - Commands: every Pscode-managed command file whose decoded id is not in the
|
|
31
|
+
* desired set is removed. When commands are not generated (skills-only) the
|
|
32
|
+
* desired set is empty, so all managed command files are removed.
|
|
33
|
+
*/
|
|
34
|
+
export declare function pruneOrphansForTool(projectPath: string, toolId: string, desiredWorkflows: readonly string[], delivery: Delivery): PruneResult;
|
|
35
|
+
/**
|
|
36
|
+
* Prunes orphan artifacts across multiple tools, aggregating the counts.
|
|
37
|
+
*/
|
|
38
|
+
export declare function pruneOrphans(projectPath: string, toolIds: readonly string[], desiredWorkflows: readonly string[], delivery: Delivery): PruneResult;
|
|
39
|
+
//# sourceMappingURL=prune-orphans.d.ts.map
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orphan Artifact Pruning
|
|
3
|
+
*
|
|
4
|
+
* Removes Pscode-managed skill directories and slash command files that no
|
|
5
|
+
* longer correspond to a desired workflow, by **scanning the filesystem**
|
|
6
|
+
* rather than iterating `ALL_WORKFLOWS`. This is what lets `init`/`update`
|
|
7
|
+
* clean up artifacts of workflows that were deleted (or renamed) from the
|
|
8
|
+
* enum entirely — a loop over `ALL_WORKFLOWS` would never visit them.
|
|
9
|
+
*
|
|
10
|
+
* The "desired" set is computed from the same generators used when writing
|
|
11
|
+
* (`getSkillTemplates` / `adapter.getFilePath`), so there is a single source
|
|
12
|
+
* of truth and a valid artifact is never removed.
|
|
13
|
+
*
|
|
14
|
+
* Removal is strictly limited to Pscode-managed naming patterns (skill dirs
|
|
15
|
+
* prefixed `pscode-`; command files matching the adapter's own filename
|
|
16
|
+
* pattern), so user files are preserved.
|
|
17
|
+
*/
|
|
18
|
+
import path from 'path';
|
|
19
|
+
import * as fs from 'fs';
|
|
20
|
+
import { CommandAdapterRegistry } from '../command-generation/index.js';
|
|
21
|
+
import { AI_TOOLS } from '../config.js';
|
|
22
|
+
import { getSkillTemplates } from './skill-generation.js';
|
|
23
|
+
const SKILL_DIR_PREFIX = 'pscode-';
|
|
24
|
+
/** Sentinel unlikely to collide with a real command id. */
|
|
25
|
+
const PROBE_ID = '__pscode_probe__';
|
|
26
|
+
/**
|
|
27
|
+
* Lists the immediate child directory names of `dir`, or `[]` if it doesn't exist.
|
|
28
|
+
*/
|
|
29
|
+
function listDirs(dir) {
|
|
30
|
+
try {
|
|
31
|
+
return fs
|
|
32
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
33
|
+
.filter((e) => e.isDirectory())
|
|
34
|
+
.map((e) => e.name);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Lists the immediate child file names of `dir`, or `[]` if it doesn't exist.
|
|
42
|
+
*/
|
|
43
|
+
function listFiles(dir) {
|
|
44
|
+
try {
|
|
45
|
+
return fs
|
|
46
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
47
|
+
.filter((e) => e.isFile())
|
|
48
|
+
.map((e) => e.name);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Derives the command directory and the Pscode-managed filename pattern for an
|
|
56
|
+
* adapter by probing `getFilePath` with a sentinel id. Returns the directory,
|
|
57
|
+
* the filename prefix/suffix that wrap the id, and a decoder from filename → id.
|
|
58
|
+
*/
|
|
59
|
+
function resolveCommandPattern(toolId, projectPath) {
|
|
60
|
+
const adapter = CommandAdapterRegistry.get(toolId);
|
|
61
|
+
if (!adapter)
|
|
62
|
+
return null;
|
|
63
|
+
const probePath = adapter.getFilePath(PROBE_ID);
|
|
64
|
+
const absProbe = path.isAbsolute(probePath) ? probePath : path.join(projectPath, probePath);
|
|
65
|
+
const dir = path.dirname(absProbe);
|
|
66
|
+
const base = path.basename(absProbe);
|
|
67
|
+
const idx = base.indexOf(PROBE_ID);
|
|
68
|
+
if (idx === -1)
|
|
69
|
+
return null;
|
|
70
|
+
const prefix = base.slice(0, idx);
|
|
71
|
+
const suffix = base.slice(idx + PROBE_ID.length);
|
|
72
|
+
const idFromFile = (file) => {
|
|
73
|
+
if (!file.startsWith(prefix) || !file.endsWith(suffix))
|
|
74
|
+
return null;
|
|
75
|
+
const id = file.slice(prefix.length, file.length - suffix.length);
|
|
76
|
+
return id.length > 0 ? id : null;
|
|
77
|
+
};
|
|
78
|
+
return { dir, prefix, suffix, idFromFile };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Scans installed Pscode artifacts for a single tool and removes orphans —
|
|
82
|
+
* artifacts that do not belong to a desired workflow for the active delivery.
|
|
83
|
+
*
|
|
84
|
+
* - Skills: every `pscode-*` directory whose name is not in the desired set is
|
|
85
|
+
* removed. When skills are not generated (commands-only delivery) the desired
|
|
86
|
+
* set is empty, so all Pscode skill dirs are removed.
|
|
87
|
+
* - Commands: every Pscode-managed command file whose decoded id is not in the
|
|
88
|
+
* desired set is removed. When commands are not generated (skills-only) the
|
|
89
|
+
* desired set is empty, so all managed command files are removed.
|
|
90
|
+
*/
|
|
91
|
+
export function pruneOrphansForTool(projectPath, toolId, desiredWorkflows, delivery) {
|
|
92
|
+
const tool = AI_TOOLS.find((t) => t.value === toolId);
|
|
93
|
+
if (!tool?.skillsDir)
|
|
94
|
+
return { removedSkillDirs: 0, removedCommandFiles: 0 };
|
|
95
|
+
const shouldGenerateSkills = delivery !== 'commands';
|
|
96
|
+
const shouldGenerateCommands = delivery !== 'skills';
|
|
97
|
+
let removedSkillDirs = 0;
|
|
98
|
+
let removedCommandFiles = 0;
|
|
99
|
+
// ── Skills ──────────────────────────────────────────────────────────────
|
|
100
|
+
const skillsDir = path.join(projectPath, tool.skillsDir, 'skills');
|
|
101
|
+
const desiredSkillDirs = new Set(shouldGenerateSkills ? getSkillTemplates(desiredWorkflows).map((t) => t.dirName) : []);
|
|
102
|
+
for (const name of listDirs(skillsDir)) {
|
|
103
|
+
if (!name.startsWith(SKILL_DIR_PREFIX))
|
|
104
|
+
continue; // never touch user dirs
|
|
105
|
+
if (desiredSkillDirs.has(name))
|
|
106
|
+
continue;
|
|
107
|
+
try {
|
|
108
|
+
fs.rmSync(path.join(skillsDir, name), { recursive: true, force: true });
|
|
109
|
+
removedSkillDirs++;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Ignore errors
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// ── Commands ────────────────────────────────────────────────────────────
|
|
116
|
+
const pattern = resolveCommandPattern(toolId, projectPath);
|
|
117
|
+
if (pattern) {
|
|
118
|
+
const desiredCommandIds = new Set(shouldGenerateCommands ? desiredWorkflows : []);
|
|
119
|
+
for (const file of listFiles(pattern.dir)) {
|
|
120
|
+
const id = pattern.idFromFile(file);
|
|
121
|
+
if (id == null)
|
|
122
|
+
continue; // not a Pscode-managed command file
|
|
123
|
+
if (desiredCommandIds.has(id))
|
|
124
|
+
continue;
|
|
125
|
+
try {
|
|
126
|
+
fs.unlinkSync(path.join(pattern.dir, file));
|
|
127
|
+
removedCommandFiles++;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// Ignore errors
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { removedSkillDirs, removedCommandFiles };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Prunes orphan artifacts across multiple tools, aggregating the counts.
|
|
138
|
+
*/
|
|
139
|
+
export function pruneOrphans(projectPath, toolIds, desiredWorkflows, delivery) {
|
|
140
|
+
let removedSkillDirs = 0;
|
|
141
|
+
let removedCommandFiles = 0;
|
|
142
|
+
for (const toolId of toolIds) {
|
|
143
|
+
const result = pruneOrphansForTool(projectPath, toolId, desiredWorkflows, delivery);
|
|
144
|
+
removedSkillDirs += result.removedSkillDirs;
|
|
145
|
+
removedCommandFiles += result.removedCommandFiles;
|
|
146
|
+
}
|
|
147
|
+
return { removedSkillDirs, removedCommandFiles };
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=prune-orphans.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Shared utilities for generating skill and command files.
|
|
5
5
|
*/
|
|
6
|
-
import { getExploreSkillTemplate,
|
|
6
|
+
import { getExploreSkillTemplate, getApplyChangeSkillTemplate, getCompleteChangeSkillTemplate, getProposeSkillTemplate, getTrelloSetupSkillTemplate, getTrelloDraftSkillTemplate, getHandoffSkillTemplate, getGrillMeSkillTemplate, getPsExploreCommandTemplate, getPsApplyCommandTemplate, getPsCompleteCommandTemplate, getPsProposeCommandTemplate, getTrelloSetupCommandTemplate, getTrelloDraftCommandTemplate, getHandoffCommandTemplate, getGrillMeCommandTemplate, } from '../templates/skill-templates.js';
|
|
7
7
|
/**
|
|
8
8
|
* Gets skill templates with their directory names, optionally filtered by workflow IDs.
|
|
9
9
|
*
|
|
@@ -12,14 +12,8 @@ import { getExploreSkillTemplate, getNewChangeSkillTemplate, getContinueChangeSk
|
|
|
12
12
|
export function getSkillTemplates(workflowFilter) {
|
|
13
13
|
const all = [
|
|
14
14
|
{ template: getExploreSkillTemplate(), dirName: 'pscode-explore', workflowId: 'explore' },
|
|
15
|
-
{ template: getNewChangeSkillTemplate(), dirName: 'pscode-new-change', workflowId: 'new' },
|
|
16
|
-
{ template: getContinueChangeSkillTemplate(), dirName: 'pscode-continue-change', workflowId: 'continue' },
|
|
17
15
|
{ template: getApplyChangeSkillTemplate(), dirName: 'pscode-apply-change', workflowId: 'apply' },
|
|
18
|
-
{ template:
|
|
19
|
-
{ template: getCompleteChangeSkillTemplate(), dirName: 'pscode-archive-change', workflowId: 'complete' },
|
|
20
|
-
{ template: getBulkArchiveChangeSkillTemplate(), dirName: 'pscode-bulk-archive-change', workflowId: 'bulk-archive' },
|
|
21
|
-
{ template: getVerifyChangeSkillTemplate(), dirName: 'pscode-verify-change', workflowId: 'verify' },
|
|
22
|
-
{ template: getOnboardSkillTemplate(), dirName: 'pscode-onboard', workflowId: 'onboard' },
|
|
16
|
+
{ template: getCompleteChangeSkillTemplate(), dirName: 'pscode-complete-change', workflowId: 'complete' },
|
|
23
17
|
{ template: getProposeSkillTemplate(), dirName: 'pscode-propose', workflowId: 'propose' },
|
|
24
18
|
// Trello-specific workflows
|
|
25
19
|
{ template: getTrelloSetupSkillTemplate(), dirName: 'pscode-trello-setup', workflowId: 'trello-setup' },
|
|
@@ -41,14 +35,8 @@ export function getSkillTemplates(workflowFilter) {
|
|
|
41
35
|
export function getCommandTemplates(workflowFilter) {
|
|
42
36
|
const all = [
|
|
43
37
|
{ template: getPsExploreCommandTemplate(), id: 'explore' },
|
|
44
|
-
{ template: getPsNewCommandTemplate(), id: 'new' },
|
|
45
|
-
{ template: getPsContinueCommandTemplate(), id: 'continue' },
|
|
46
38
|
{ template: getPsApplyCommandTemplate(), id: 'apply' },
|
|
47
|
-
{ template: getPsFfCommandTemplate(), id: 'ff' },
|
|
48
39
|
{ template: getPsCompleteCommandTemplate(), id: 'complete' },
|
|
49
|
-
{ template: getPsBulkArchiveCommandTemplate(), id: 'bulk-archive' },
|
|
50
|
-
{ template: getPsVerifyCommandTemplate(), id: 'verify' },
|
|
51
|
-
{ template: getPsOnboardCommandTemplate(), id: 'onboard' },
|
|
52
40
|
{ template: getPsProposeCommandTemplate(), id: 'propose' },
|
|
53
41
|
// Trello-specific workflows
|
|
54
42
|
{ template: getTrelloSetupCommandTemplate(), id: 'trello-setup' },
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
/**
|
|
7
7
|
* Names of skill directories created by pscode init.
|
|
8
8
|
*/
|
|
9
|
-
export declare const SKILL_NAMES: readonly ["pscode-explore", "pscode-
|
|
9
|
+
export declare const SKILL_NAMES: readonly ["pscode-explore", "pscode-apply-change", "pscode-complete-change", "pscode-propose"];
|
|
10
10
|
export type SkillName = (typeof SKILL_NAMES)[number];
|
|
11
11
|
/**
|
|
12
12
|
* IDs of command templates created by pscode init.
|
|
13
13
|
*/
|
|
14
|
-
export declare const COMMAND_IDS: readonly ["explore", "
|
|
14
|
+
export declare const COMMAND_IDS: readonly ["explore", "apply", "complete", "propose"];
|
|
15
15
|
export type CommandId = (typeof COMMAND_IDS)[number];
|
|
16
16
|
/**
|
|
17
17
|
* Status of skill configuration for a tool.
|
|
@@ -11,14 +11,8 @@ import { AI_TOOLS } from '../config.js';
|
|
|
11
11
|
*/
|
|
12
12
|
export const SKILL_NAMES = [
|
|
13
13
|
'pscode-explore',
|
|
14
|
-
'pscode-new-change',
|
|
15
|
-
'pscode-continue-change',
|
|
16
14
|
'pscode-apply-change',
|
|
17
|
-
'pscode-
|
|
18
|
-
'pscode-archive-change',
|
|
19
|
-
'pscode-bulk-archive-change',
|
|
20
|
-
'pscode-verify-change',
|
|
21
|
-
'pscode-onboard',
|
|
15
|
+
'pscode-complete-change',
|
|
22
16
|
'pscode-propose',
|
|
23
17
|
];
|
|
24
18
|
/**
|
|
@@ -26,14 +20,8 @@ export const SKILL_NAMES = [
|
|
|
26
20
|
*/
|
|
27
21
|
export const COMMAND_IDS = [
|
|
28
22
|
'explore',
|
|
29
|
-
'new',
|
|
30
|
-
'continue',
|
|
31
23
|
'apply',
|
|
32
|
-
'ff',
|
|
33
24
|
'complete',
|
|
34
|
-
'bulk-archive',
|
|
35
|
-
'verify',
|
|
36
|
-
'onboard',
|
|
37
25
|
'propose',
|
|
38
26
|
];
|
|
39
27
|
/**
|
|
@@ -5,14 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export type { SkillTemplate, CommandTemplate } from './types.js';
|
|
7
7
|
export { getExploreSkillTemplate, getPsExploreCommandTemplate } from './workflows/explore.js';
|
|
8
|
-
export { getNewChangeSkillTemplate, getPsNewCommandTemplate } from './workflows/new-change.js';
|
|
9
|
-
export { getContinueChangeSkillTemplate, getPsContinueCommandTemplate } from './workflows/continue-change.js';
|
|
10
8
|
export { getApplyChangeSkillTemplate, getPsApplyCommandTemplate } from './workflows/apply-change.js';
|
|
11
|
-
export {
|
|
12
|
-
export { getCompleteChangeSkillTemplate, getPsCompleteCommandTemplate } from './workflows/archive-change.js';
|
|
13
|
-
export { getBulkArchiveChangeSkillTemplate, getPsBulkArchiveCommandTemplate } from './workflows/bulk-archive-change.js';
|
|
14
|
-
export { getVerifyChangeSkillTemplate, getPsVerifyCommandTemplate } from './workflows/verify-change.js';
|
|
15
|
-
export { getOnboardSkillTemplate, getPsOnboardCommandTemplate } from './workflows/onboard.js';
|
|
9
|
+
export { getCompleteChangeSkillTemplate, getPsCompleteCommandTemplate } from './workflows/complete-change.js';
|
|
16
10
|
export { getProposeSkillTemplate, getPsProposeCommandTemplate } from './workflows/propose.js';
|
|
17
11
|
export { getFeedbackSkillTemplate } from './workflows/feedback.js';
|
|
18
12
|
export { getTrelloSetupSkillTemplate, getTrelloSetupCommandTemplate } from './workflows/trello-setup.js';
|
|
@@ -4,14 +4,8 @@
|
|
|
4
4
|
* Compatibility facade that re-exports split workflow template modules.
|
|
5
5
|
*/
|
|
6
6
|
export { getExploreSkillTemplate, getPsExploreCommandTemplate } from './workflows/explore.js';
|
|
7
|
-
export { getNewChangeSkillTemplate, getPsNewCommandTemplate } from './workflows/new-change.js';
|
|
8
|
-
export { getContinueChangeSkillTemplate, getPsContinueCommandTemplate } from './workflows/continue-change.js';
|
|
9
7
|
export { getApplyChangeSkillTemplate, getPsApplyCommandTemplate } from './workflows/apply-change.js';
|
|
10
|
-
export {
|
|
11
|
-
export { getCompleteChangeSkillTemplate, getPsCompleteCommandTemplate } from './workflows/archive-change.js';
|
|
12
|
-
export { getBulkArchiveChangeSkillTemplate, getPsBulkArchiveCommandTemplate } from './workflows/bulk-archive-change.js';
|
|
13
|
-
export { getVerifyChangeSkillTemplate, getPsVerifyCommandTemplate } from './workflows/verify-change.js';
|
|
14
|
-
export { getOnboardSkillTemplate, getPsOnboardCommandTemplate } from './workflows/onboard.js';
|
|
8
|
+
export { getCompleteChangeSkillTemplate, getPsCompleteCommandTemplate } from './workflows/complete-change.js';
|
|
15
9
|
export { getProposeSkillTemplate, getPsProposeCommandTemplate } from './workflows/propose.js';
|
|
16
10
|
export { getFeedbackSkillTemplate } from './workflows/feedback.js';
|
|
17
11
|
// Trello-specific workflows
|
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
import type { SkillTemplate, CommandTemplate } from '../types.js';
|
|
8
8
|
export declare function getCompleteChangeSkillTemplate(): SkillTemplate;
|
|
9
9
|
export declare function getPsCompleteCommandTemplate(): CommandTemplate;
|
|
10
|
-
//# sourceMappingURL=
|
|
10
|
+
//# sourceMappingURL=complete-change.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export function getCompleteChangeSkillTemplate() {
|
|
2
2
|
return {
|
|
3
|
-
name: 'pscode-
|
|
3
|
+
name: 'pscode-complete-change',
|
|
4
4
|
description: 'Complete a completed change. Use when the user wants to finalize and complete a change after implementation is complete.',
|
|
5
5
|
instructions: getArchiveInstructions(),
|
|
6
6
|
compatibility: 'Requires pscode CLI.',
|
|
@@ -223,4 +223,4 @@ Target archive directory already exists.
|
|
|
223
223
|
- All content written to Trello must be in Portuguese
|
|
224
224
|
`;
|
|
225
225
|
}
|
|
226
|
-
//# sourceMappingURL=
|
|
226
|
+
//# sourceMappingURL=complete-change.js.map
|
package/dist/core/update.d.ts
CHANGED
|
@@ -38,26 +38,6 @@ export declare class UpdateCommand {
|
|
|
38
38
|
* Displays a note about extra workflows installed that aren't in the active profile.
|
|
39
39
|
*/
|
|
40
40
|
private displayExtraWorkflowsNote;
|
|
41
|
-
/**
|
|
42
|
-
* Removes skill directories for workflows when delivery changed to commands-only.
|
|
43
|
-
* Returns the number of directories removed.
|
|
44
|
-
*/
|
|
45
|
-
private removeSkillDirs;
|
|
46
|
-
/**
|
|
47
|
-
* Removes skill directories for workflows that are no longer selected in the active profile.
|
|
48
|
-
* Returns the number of directories removed.
|
|
49
|
-
*/
|
|
50
|
-
private removeUnselectedSkillDirs;
|
|
51
|
-
/**
|
|
52
|
-
* Removes command files for workflows when delivery changed to skills-only.
|
|
53
|
-
* Returns the number of files removed.
|
|
54
|
-
*/
|
|
55
|
-
private removeCommandFiles;
|
|
56
|
-
/**
|
|
57
|
-
* Removes command files for workflows that are no longer selected in the active profile.
|
|
58
|
-
* Returns the number of files removed.
|
|
59
|
-
*/
|
|
60
|
-
private removeUnselectedCommandFiles;
|
|
61
41
|
/**
|
|
62
42
|
* Detect and handle legacy Pscode artifacts.
|
|
63
43
|
* Unlike init, update warns but continues if legacy files found in non-interactive mode.
|