@fermindi/pwn-cli 0.3.3 → 0.3.4
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/cli/index.js +7 -0
- package/cli/mode.js +206 -0
- package/package.json +1 -1
- package/src/core/state.js +46 -1
package/cli/index.js
CHANGED
|
@@ -28,6 +28,7 @@ if (!command || command === '--help' || command === '-h') {
|
|
|
28
28
|
console.log(' validate Validate workspace structure');
|
|
29
29
|
console.log(' notify Send notifications (test, send, config)');
|
|
30
30
|
console.log(' batch Execute tasks autonomously');
|
|
31
|
+
console.log(' mode Manage session mode (interactive/batch)');
|
|
31
32
|
console.log(' patterns Manage patterns and triggers');
|
|
32
33
|
console.log(' knowledge Knowledge lifecycle management');
|
|
33
34
|
console.log(' codespaces GitHub Codespaces integration');
|
|
@@ -41,6 +42,7 @@ if (!command || command === '--help' || command === '-h') {
|
|
|
41
42
|
console.log(' validate --verbose Show detailed structure report');
|
|
42
43
|
console.log(' notify test [ch] Test notification channel');
|
|
43
44
|
console.log(' batch --count 5 Execute 5 tasks');
|
|
45
|
+
console.log(' mode batch --max-tasks=3 Configure batch mode');
|
|
44
46
|
console.log(' patterns eval <f> Evaluate triggers for file');
|
|
45
47
|
console.log(' knowledge status Show knowledge system status');
|
|
46
48
|
console.log(' codespaces init Add devcontainer config\n');
|
|
@@ -90,6 +92,11 @@ switch (command) {
|
|
|
90
92
|
await batchCmd(args);
|
|
91
93
|
break;
|
|
92
94
|
|
|
95
|
+
case 'mode':
|
|
96
|
+
const { default: modeCmd } = await import('./mode.js');
|
|
97
|
+
await modeCmd(args);
|
|
98
|
+
break;
|
|
99
|
+
|
|
93
100
|
case 'patterns':
|
|
94
101
|
const { default: patternsCmd } = await import('./patterns.js');
|
|
95
102
|
await patternsCmd(args);
|
package/cli/mode.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
hasWorkspace,
|
|
4
|
+
getState,
|
|
5
|
+
updateState,
|
|
6
|
+
getBatchConfig,
|
|
7
|
+
updateBatchConfig,
|
|
8
|
+
DEFAULT_BATCH_CONFIG
|
|
9
|
+
} from '../src/core/state.js';
|
|
10
|
+
|
|
11
|
+
export default async function modeCommand(args = []) {
|
|
12
|
+
// Check workspace
|
|
13
|
+
if (!hasWorkspace()) {
|
|
14
|
+
console.log('❌ No PWN workspace found');
|
|
15
|
+
console.log(' Run: pwn inject');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const subcommand = args[0];
|
|
20
|
+
const subArgs = args.slice(1);
|
|
21
|
+
|
|
22
|
+
// No arguments: show current mode
|
|
23
|
+
if (!subcommand) {
|
|
24
|
+
return showCurrentMode();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Subcommands
|
|
28
|
+
switch (subcommand) {
|
|
29
|
+
case 'interactive':
|
|
30
|
+
return setInteractiveMode();
|
|
31
|
+
case 'batch':
|
|
32
|
+
return setBatchMode(subArgs);
|
|
33
|
+
default:
|
|
34
|
+
console.log(`❌ Unknown mode: ${subcommand}`);
|
|
35
|
+
console.log(' Valid modes: interactive, batch');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function showCurrentMode() {
|
|
41
|
+
const state = getState();
|
|
42
|
+
const mode = state?.session_mode || 'interactive';
|
|
43
|
+
const config = getBatchConfig();
|
|
44
|
+
|
|
45
|
+
console.log(`📋 Session Mode: ${mode}\n`);
|
|
46
|
+
console.log('Batch config:');
|
|
47
|
+
printConfig(config);
|
|
48
|
+
console.log('\nUsage:');
|
|
49
|
+
console.log(' pwn mode interactive Switch to interactive mode');
|
|
50
|
+
console.log(' pwn mode batch Switch to batch mode');
|
|
51
|
+
console.log(' pwn mode batch --help Show batch options');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function setInteractiveMode() {
|
|
55
|
+
updateState({ session_mode: 'interactive' });
|
|
56
|
+
console.log('✅ Switched to interactive mode\n');
|
|
57
|
+
console.log('Batch config preserved for next batch session.');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function setBatchMode(args) {
|
|
61
|
+
// Check for help
|
|
62
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
63
|
+
showBatchHelp();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check for reset
|
|
68
|
+
if (args.includes('--reset')) {
|
|
69
|
+
updateBatchConfig(DEFAULT_BATCH_CONFIG);
|
|
70
|
+
updateState({ session_mode: 'batch' });
|
|
71
|
+
console.log('✅ Switched to batch mode (config reset to defaults)\n');
|
|
72
|
+
console.log('Config:');
|
|
73
|
+
printConfig(DEFAULT_BATCH_CONFIG);
|
|
74
|
+
console.log('\nRun \'pwn batch\' to start executing tasks from backlog.');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Parse config updates
|
|
79
|
+
const currentConfig = getBatchConfig();
|
|
80
|
+
const updates = parseConfigArgs(args);
|
|
81
|
+
const hasUpdates = Object.keys(updates).length > 0;
|
|
82
|
+
|
|
83
|
+
// Apply updates if any
|
|
84
|
+
if (hasUpdates) {
|
|
85
|
+
updateBatchConfig(updates);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Switch to batch mode
|
|
89
|
+
updateState({ session_mode: 'batch' });
|
|
90
|
+
|
|
91
|
+
// Show result
|
|
92
|
+
if (hasUpdates) {
|
|
93
|
+
console.log('✅ Switched to batch mode\n');
|
|
94
|
+
console.log('Config updated:');
|
|
95
|
+
printConfigChanges(currentConfig, updates);
|
|
96
|
+
} else {
|
|
97
|
+
console.log('✅ Switched to batch mode\n');
|
|
98
|
+
console.log('Config:');
|
|
99
|
+
printConfig(getBatchConfig());
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log('\nRun \'pwn batch\' to start executing tasks from backlog.');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function parseConfigArgs(args) {
|
|
106
|
+
const updates = {};
|
|
107
|
+
|
|
108
|
+
for (const arg of args) {
|
|
109
|
+
// --max-tasks=N
|
|
110
|
+
if (arg.startsWith('--max-tasks=')) {
|
|
111
|
+
const value = parseInt(arg.split('=')[1], 10);
|
|
112
|
+
if (!isNaN(value) && value > 0) {
|
|
113
|
+
updates.max_tasks = value;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// --max-hours=N
|
|
117
|
+
else if (arg.startsWith('--max-hours=')) {
|
|
118
|
+
const value = parseInt(arg.split('=')[1], 10);
|
|
119
|
+
if (!isNaN(value) && value > 0) {
|
|
120
|
+
updates.max_duration_hours = value;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// --quality-gates=X,Y,Z
|
|
124
|
+
else if (arg.startsWith('--quality-gates=')) {
|
|
125
|
+
const value = arg.split('=')[1];
|
|
126
|
+
if (value) {
|
|
127
|
+
updates.quality_gates = value.split(',').map(g => g.trim()).filter(Boolean);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Boolean flags
|
|
131
|
+
else if (arg === '--auto-commit') {
|
|
132
|
+
updates.auto_commit = true;
|
|
133
|
+
}
|
|
134
|
+
else if (arg === '--no-auto-commit') {
|
|
135
|
+
updates.auto_commit = false;
|
|
136
|
+
}
|
|
137
|
+
else if (arg === '--auto-push') {
|
|
138
|
+
updates.auto_push = true;
|
|
139
|
+
}
|
|
140
|
+
else if (arg === '--no-auto-push') {
|
|
141
|
+
updates.auto_push = false;
|
|
142
|
+
}
|
|
143
|
+
else if (arg === '--create-pr') {
|
|
144
|
+
updates.create_pr = true;
|
|
145
|
+
}
|
|
146
|
+
else if (arg === '--no-create-pr') {
|
|
147
|
+
updates.create_pr = false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return updates;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function printConfig(config) {
|
|
155
|
+
console.log(` max_tasks: ${config.max_tasks}`);
|
|
156
|
+
console.log(` max_hours: ${config.max_duration_hours}`);
|
|
157
|
+
console.log(` quality_gates: ${config.quality_gates.join(', ')}`);
|
|
158
|
+
console.log(` auto_commit: ${config.auto_commit}`);
|
|
159
|
+
console.log(` auto_push: ${config.auto_push}`);
|
|
160
|
+
console.log(` create_pr: ${config.create_pr}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function printConfigChanges(oldConfig, updates) {
|
|
164
|
+
const newConfig = { ...oldConfig, ...updates };
|
|
165
|
+
|
|
166
|
+
if ('max_tasks' in updates) {
|
|
167
|
+
console.log(` max_tasks: ${oldConfig.max_tasks} → ${newConfig.max_tasks}`);
|
|
168
|
+
}
|
|
169
|
+
if ('max_duration_hours' in updates) {
|
|
170
|
+
console.log(` max_hours: ${oldConfig.max_duration_hours} → ${newConfig.max_duration_hours}`);
|
|
171
|
+
}
|
|
172
|
+
if ('quality_gates' in updates) {
|
|
173
|
+
console.log(` quality_gates: ${oldConfig.quality_gates.join(', ')} → ${newConfig.quality_gates.join(', ')}`);
|
|
174
|
+
}
|
|
175
|
+
if ('auto_commit' in updates) {
|
|
176
|
+
console.log(` auto_commit: ${oldConfig.auto_commit} → ${newConfig.auto_commit}`);
|
|
177
|
+
}
|
|
178
|
+
if ('auto_push' in updates) {
|
|
179
|
+
console.log(` auto_push: ${oldConfig.auto_push} → ${newConfig.auto_push}`);
|
|
180
|
+
}
|
|
181
|
+
if ('create_pr' in updates) {
|
|
182
|
+
console.log(` create_pr: ${oldConfig.create_pr} → ${newConfig.create_pr}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function showBatchHelp() {
|
|
187
|
+
console.log('PWN Mode - Batch Configuration\n');
|
|
188
|
+
console.log('Usage: pwn mode batch [options]\n');
|
|
189
|
+
console.log('Options:');
|
|
190
|
+
console.log(' --max-tasks=N Maximum tasks per batch (default: 5)');
|
|
191
|
+
console.log(' --max-hours=N Maximum duration in hours (default: 4)');
|
|
192
|
+
console.log(' --quality-gates=X,Y,Z Quality gates to run (default: typecheck,lint,test)');
|
|
193
|
+
console.log(' --auto-commit Enable auto commit (default)');
|
|
194
|
+
console.log(' --no-auto-commit Disable auto commit');
|
|
195
|
+
console.log(' --auto-push Enable auto push');
|
|
196
|
+
console.log(' --no-auto-push Disable auto push (default)');
|
|
197
|
+
console.log(' --create-pr Enable PR creation');
|
|
198
|
+
console.log(' --no-create-pr Disable PR creation (default)');
|
|
199
|
+
console.log(' --reset Reset config to defaults');
|
|
200
|
+
console.log(' --help, -h Show this help\n');
|
|
201
|
+
console.log('Examples:');
|
|
202
|
+
console.log(' pwn mode batch Switch to batch with current config');
|
|
203
|
+
console.log(' pwn mode batch --max-tasks=3 Set max tasks to 3');
|
|
204
|
+
console.log(' pwn mode batch --auto-push --create-pr Enable push and PR creation');
|
|
205
|
+
console.log(' pwn mode batch --reset Reset to defaults');
|
|
206
|
+
}
|
package/package.json
CHANGED
package/src/core/state.js
CHANGED
|
@@ -2,6 +2,20 @@ import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { execSync } from 'child_process';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Default batch configuration
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_BATCH_CONFIG = {
|
|
9
|
+
max_tasks: 5,
|
|
10
|
+
max_duration_hours: 4,
|
|
11
|
+
quality_gates: ['typecheck', 'lint', 'test'],
|
|
12
|
+
auto_commit: true,
|
|
13
|
+
auto_push: false,
|
|
14
|
+
create_pr: false,
|
|
15
|
+
branch_format: 'feature/{id}-{slug}',
|
|
16
|
+
commit_format: 'conventional'
|
|
17
|
+
};
|
|
18
|
+
|
|
5
19
|
/**
|
|
6
20
|
* Get the path to state.json in a workspace
|
|
7
21
|
* @param {string} cwd - Working directory (defaults to process.cwd())
|
|
@@ -81,11 +95,42 @@ export function initState(cwd = process.cwd()) {
|
|
|
81
95
|
const state = {
|
|
82
96
|
developer: getGitUser(),
|
|
83
97
|
session_started: new Date().toISOString(),
|
|
98
|
+
session_mode: 'interactive',
|
|
84
99
|
current_task: null,
|
|
85
|
-
context_loaded: []
|
|
100
|
+
context_loaded: [],
|
|
101
|
+
batch_config: { ...DEFAULT_BATCH_CONFIG }
|
|
86
102
|
};
|
|
87
103
|
|
|
88
104
|
const statePath = getStatePath(cwd);
|
|
89
105
|
writeFileSync(statePath, JSON.stringify(state, null, 2));
|
|
90
106
|
return state;
|
|
91
107
|
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get batch configuration with defaults
|
|
111
|
+
* @param {string} cwd - Working directory
|
|
112
|
+
* @returns {object} Batch config merged with defaults
|
|
113
|
+
*/
|
|
114
|
+
export function getBatchConfig(cwd = process.cwd()) {
|
|
115
|
+
const state = getState(cwd);
|
|
116
|
+
if (!state) return { ...DEFAULT_BATCH_CONFIG };
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
...DEFAULT_BATCH_CONFIG,
|
|
120
|
+
...(state.batch_config || {})
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Update batch configuration
|
|
126
|
+
* @param {object} updates - Fields to update in batch_config
|
|
127
|
+
* @param {string} cwd - Working directory
|
|
128
|
+
* @returns {object} Updated batch config
|
|
129
|
+
*/
|
|
130
|
+
export function updateBatchConfig(updates, cwd = process.cwd()) {
|
|
131
|
+
const currentConfig = getBatchConfig(cwd);
|
|
132
|
+
const newConfig = { ...currentConfig, ...updates };
|
|
133
|
+
|
|
134
|
+
updateState({ batch_config: newConfig }, cwd);
|
|
135
|
+
return newConfig;
|
|
136
|
+
}
|