@paw-workflow/cli 0.0.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.
Files changed (38) hide show
  1. package/README.md +124 -0
  2. package/bin/paw.js +82 -0
  3. package/dist/agents/PAW-Review.agent.md +86 -0
  4. package/dist/agents/PAW.agent.md +171 -0
  5. package/dist/skills/paw-code-research/SKILL.md +209 -0
  6. package/dist/skills/paw-docs-guidance/SKILL.md +163 -0
  7. package/dist/skills/paw-git-operations/SKILL.md +196 -0
  8. package/dist/skills/paw-impl-review/SKILL.md +178 -0
  9. package/dist/skills/paw-implement/SKILL.md +153 -0
  10. package/dist/skills/paw-init/SKILL.md +118 -0
  11. package/dist/skills/paw-plan-review/SKILL.md +117 -0
  12. package/dist/skills/paw-planning/SKILL.md +217 -0
  13. package/dist/skills/paw-pr/SKILL.md +157 -0
  14. package/dist/skills/paw-review-baseline/SKILL.md +268 -0
  15. package/dist/skills/paw-review-correlation/SKILL.md +307 -0
  16. package/dist/skills/paw-review-critic/SKILL.md +373 -0
  17. package/dist/skills/paw-review-feedback/SKILL.md +437 -0
  18. package/dist/skills/paw-review-gap/SKILL.md +639 -0
  19. package/dist/skills/paw-review-github/SKILL.md +336 -0
  20. package/dist/skills/paw-review-impact/SKILL.md +569 -0
  21. package/dist/skills/paw-review-response/SKILL.md +118 -0
  22. package/dist/skills/paw-review-understanding/SKILL.md +372 -0
  23. package/dist/skills/paw-review-workflow/SKILL.md +239 -0
  24. package/dist/skills/paw-spec/SKILL.md +257 -0
  25. package/dist/skills/paw-spec-research/SKILL.md +138 -0
  26. package/dist/skills/paw-spec-review/SKILL.md +101 -0
  27. package/dist/skills/paw-status/SKILL.md +160 -0
  28. package/dist/skills/paw-transition/SKILL.md +134 -0
  29. package/dist/skills/paw-work-shaping/SKILL.md +99 -0
  30. package/dist/skills/paw-workflow/SKILL.md +142 -0
  31. package/lib/commands/install.js +103 -0
  32. package/lib/commands/list.js +18 -0
  33. package/lib/commands/uninstall.js +95 -0
  34. package/lib/commands/upgrade.js +119 -0
  35. package/lib/manifest.js +42 -0
  36. package/lib/paths.js +42 -0
  37. package/lib/registry.js +41 -0
  38. package/package.json +40 -0
@@ -0,0 +1,119 @@
1
+ import { spawn, execSync } from 'child_process';
2
+ import { readManifest } from '../manifest.js';
3
+ import { getLatestVersion } from '../registry.js';
4
+
5
+ function isGlobalInstall() {
6
+ try {
7
+ // Check if this script is running from global node_modules
8
+ const globalRoot = execSync('npm root -g', { encoding: 'utf-8' }).trim();
9
+ return process.argv[1].startsWith(globalRoot);
10
+ } catch {
11
+ return false;
12
+ }
13
+ }
14
+
15
+ function runCommand(command, args) {
16
+ return new Promise((resolve, reject) => {
17
+ const child = spawn(command, args, {
18
+ stdio: 'inherit',
19
+ shell: true,
20
+ });
21
+
22
+ child.on('close', (code) => {
23
+ if (code === 0) {
24
+ resolve();
25
+ } else {
26
+ reject(new Error(`Command failed with exit code ${code}`));
27
+ }
28
+ });
29
+
30
+ child.on('error', (err) => {
31
+ reject(new Error(`Failed to run command: ${err.message}`));
32
+ });
33
+ });
34
+ }
35
+
36
+ export async function upgradeCommand(_flags = {}) {
37
+ const manifest = readManifest();
38
+
39
+ if (!manifest) {
40
+ console.log('PAW is not installed. Run "paw install copilot" first.');
41
+ return;
42
+ }
43
+
44
+ const currentVersion = manifest.version;
45
+ const target = manifest.target;
46
+
47
+ console.log(`Installed version: ${currentVersion}`);
48
+ console.log(`Target: ${target}`);
49
+ console.log('Checking npm registry for updates...\n');
50
+
51
+ let latestVersion;
52
+ try {
53
+ latestVersion = await getLatestVersion();
54
+ } catch (error) {
55
+ console.error(`Failed to check for updates: ${error.message}`);
56
+ console.log('Please check your network connection and try again.');
57
+ return;
58
+ }
59
+
60
+ if (!latestVersion) {
61
+ console.log('Could not determine latest version from npm registry.');
62
+ return;
63
+ }
64
+
65
+ console.log(`Latest version: ${latestVersion}`);
66
+
67
+ if (latestVersion === currentVersion) {
68
+ console.log('\n✓ You are already on the latest version.');
69
+ return;
70
+ }
71
+
72
+ // Compare versions (simple comparison, assumes semver-like format)
73
+ const current = currentVersion.split('.').map(Number);
74
+ const latest = latestVersion.split('.').map(Number);
75
+
76
+ let isNewer = false;
77
+ for (let i = 0; i < 3; i++) {
78
+ if (latest[i] > current[i]) {
79
+ isNewer = true;
80
+ break;
81
+ }
82
+ if (latest[i] < current[i]) {
83
+ break;
84
+ }
85
+ }
86
+
87
+ if (!isNewer) {
88
+ console.log('\n✓ You are already on the latest version.');
89
+ return;
90
+ }
91
+
92
+ console.log(`\n→ Upgrading: ${currentVersion} → ${latestVersion}\n`);
93
+
94
+ const isGlobal = isGlobalInstall();
95
+
96
+ if (isGlobal) {
97
+ // Upgrade global CLI installation first
98
+ console.log('Step 1/2: Upgrading @paw-workflow/cli globally...\n');
99
+ await runCommand('npm', ['install', '-g', `@paw-workflow/cli@${latestVersion}`]);
100
+
101
+ // Then reinstall agents/skills using the new CLI
102
+ console.log('\nStep 2/2: Installing PAW agents and skills to', target, '...\n');
103
+ await runCommand('paw', ['install', target, '--force']);
104
+ } else {
105
+ // Running via npx or local - just use npx to get latest
106
+ console.log('Downloading @paw-workflow/cli@' + latestVersion + ' and installing to', target, '...\n');
107
+ await runCommand('npx', [
108
+ `@paw-workflow/cli@${latestVersion}`,
109
+ 'install',
110
+ target,
111
+ '--force',
112
+ ]);
113
+ }
114
+
115
+ console.log('\n' + '─'.repeat(50));
116
+ console.log('✓ Upgrade complete!');
117
+ console.log(` CLI version: ${latestVersion}`);
118
+ console.log(` Agents and skills installed to: ${target}`);
119
+ }
@@ -0,0 +1,42 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from 'fs';
2
+ import { getManifestPath, getManifestDir } from './paths.js';
3
+
4
+ export function readManifest() {
5
+ const manifestPath = getManifestPath();
6
+ if (!existsSync(manifestPath)) {
7
+ return null;
8
+ }
9
+ try {
10
+ const content = readFileSync(manifestPath, 'utf-8');
11
+ return JSON.parse(content);
12
+ } catch {
13
+ return null;
14
+ }
15
+ }
16
+
17
+ export function writeManifest(manifest) {
18
+ const manifestDir = getManifestDir();
19
+ const manifestPath = getManifestPath();
20
+
21
+ if (!existsSync(manifestDir)) {
22
+ mkdirSync(manifestDir, { recursive: true });
23
+ }
24
+
25
+ writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
26
+ }
27
+
28
+ export function createManifest(version, target, files) {
29
+ return {
30
+ version,
31
+ installedAt: new Date().toISOString(),
32
+ target,
33
+ files,
34
+ };
35
+ }
36
+
37
+ export function deleteManifest() {
38
+ const manifestPath = getManifestPath();
39
+ if (existsSync(manifestPath)) {
40
+ unlinkSync(manifestPath);
41
+ }
42
+ }
package/lib/paths.js ADDED
@@ -0,0 +1,42 @@
1
+ import { homedir } from 'os';
2
+ import { join } from 'path';
3
+
4
+ export function getHomeDir() {
5
+ return homedir();
6
+ }
7
+
8
+ export function getCopilotDir() {
9
+ return join(getHomeDir(), '.copilot');
10
+ }
11
+
12
+ export function getCopilotAgentsDir() {
13
+ return join(getCopilotDir(), 'agents');
14
+ }
15
+
16
+ export function getCopilotSkillsDir() {
17
+ return join(getCopilotDir(), 'skills');
18
+ }
19
+
20
+ export function getPawDir() {
21
+ return join(getHomeDir(), '.paw');
22
+ }
23
+
24
+ export function getManifestDir() {
25
+ return join(getPawDir(), 'copilot-cli');
26
+ }
27
+
28
+ export function getManifestPath() {
29
+ return join(getManifestDir(), 'manifest.json');
30
+ }
31
+
32
+ export function getDistDir() {
33
+ return join(import.meta.dirname, '..', 'dist');
34
+ }
35
+
36
+ export function getDistAgentsDir() {
37
+ return join(getDistDir(), 'agents');
38
+ }
39
+
40
+ export function getDistSkillsDir() {
41
+ return join(getDistDir(), 'skills');
42
+ }
@@ -0,0 +1,41 @@
1
+ import { get } from 'https';
2
+
3
+ const REGISTRY_URL = 'https://registry.npmjs.org/@paw-workflow/cli';
4
+ const TIMEOUT_MS = 10000;
5
+
6
+ export async function getLatestVersion() {
7
+ return new Promise((resolve, reject) => {
8
+ const req = get(REGISTRY_URL, { timeout: TIMEOUT_MS }, (res) => {
9
+ if (res.statusCode === 404) {
10
+ // Package not published yet
11
+ resolve(null);
12
+ return;
13
+ }
14
+
15
+ if (res.statusCode !== 200) {
16
+ reject(new Error(`HTTP ${res.statusCode}`));
17
+ return;
18
+ }
19
+
20
+ let data = '';
21
+ res.on('data', chunk => data += chunk);
22
+ res.on('end', () => {
23
+ try {
24
+ const pkg = JSON.parse(data);
25
+ resolve(pkg['dist-tags']?.latest || null);
26
+ } catch {
27
+ reject(new Error('Invalid response from registry'));
28
+ }
29
+ });
30
+ });
31
+
32
+ req.on('error', (err) => {
33
+ reject(new Error(`Network error: ${err.message}`));
34
+ });
35
+
36
+ req.on('timeout', () => {
37
+ req.destroy();
38
+ reject(new Error('Request timed out'));
39
+ });
40
+ });
41
+ }
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@paw-workflow/cli",
3
+ "version": "0.0.1",
4
+ "description": "CLI installer for Phased Agent Workflow (PAW) agents and skills",
5
+ "type": "module",
6
+ "bin": {
7
+ "paw": "bin/paw.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "lib/",
12
+ "dist/"
13
+ ],
14
+ "scripts": {
15
+ "build": "node scripts/build-dist.js",
16
+ "test": "node --test test/*.test.js",
17
+ "lint": "eslint .",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "keywords": [
21
+ "paw",
22
+ "copilot",
23
+ "agent",
24
+ "workflow",
25
+ "cli"
26
+ ],
27
+ "author": "",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/lossyrob/phased-agent-workflow.git",
32
+ "directory": "cli"
33
+ },
34
+ "engines": {
35
+ "node": ">=18.0.0"
36
+ },
37
+ "devDependencies": {
38
+ "eslint": "^9.0.0"
39
+ }
40
+ }