phewsh 0.15.74 → 0.15.76

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/bin/phewsh.js CHANGED
@@ -115,6 +115,7 @@ const COMMANDS = {
115
115
  dispatch: () => require('../commands/task')(),
116
116
  pack: () => require('../commands/pack')(),
117
117
  hook: () => require('../commands/hook')(),
118
+ feedback: () => require('../commands/feedback')(),
118
119
  welcome: () => require('../commands/welcome')(),
119
120
  intro: () => require('../commands/welcome')(),
120
121
  help: showHelp,
@@ -171,6 +172,7 @@ function showHelp() {
171
172
  console.log(` ${cyan('bypass')} ${g('Went around phewsh? Record why — 10 seconds, no guilt')}`);
172
173
  console.log('');
173
174
  console.log(` ${b(w('configure'))}`);
175
+ console.log(` ${cyan('feedback')} ${g('Tell us what you need — prefilled GitHub issue; `feedback list` shows the queue')}`);
174
176
  console.log(` ${cyan('login')} ${g('Identity + API key + cloud sync')}`);
175
177
  console.log(` ${cyan('link')} ${g('Link local .intent/ to cloud project')}`);
176
178
  console.log(` ${cyan('update')} ${g('Update phewsh — or `phewsh update auto on` to stay current automatically')}`);
@@ -0,0 +1,102 @@
1
+ // phewsh feedback — the door the launch post points at.
2
+ //
3
+ // phewsh feedback open a prefilled GitHub issue in the browser
4
+ // phewsh feedback "it broke..." same, with your words already in the body
5
+ //
6
+ // Deliberately no hidden telemetry: everything sent is shown first, travels
7
+ // as a URL you can read, and lands in the public issue tracker. Email stays
8
+ // the quiet alternative for anything private.
9
+
10
+ const os = require('os');
11
+ const { execFileSync } = require('child_process');
12
+
13
+ const REPO_ISSUES = 'https://github.com/cleverIdeaz/phewsh-cli/issues/new';
14
+ const EMAIL = 'hello@phewsh.com';
15
+
16
+ const b = (s) => `\x1b[1m${s}\x1b[0m`;
17
+ const g = (s) => `\x1b[38;5;247m${s}\x1b[0m`;
18
+ const w = (s) => `\x1b[97m${s}\x1b[0m`;
19
+ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
20
+
21
+ function buildUrl(text) {
22
+ const version = require('../package.json').version;
23
+ const body = [
24
+ text ? text.trim() : '<!-- What happened? What did you expect? -->',
25
+ '',
26
+ '---',
27
+ `phewsh ${version} · ${process.platform} ${os.release()} · node ${process.version}`,
28
+ ].join('\n');
29
+ const params = new URLSearchParams({ title: text ? text.trim().slice(0, 72) : '', body });
30
+ return `${REPO_ISSUES}?${params.toString()}`;
31
+ }
32
+
33
+ // Arg-array spawn only — the URL carries user text; it must never touch a shell.
34
+ function openBrowser(url) {
35
+ try {
36
+ if (process.platform === 'darwin') execFileSync('open', [url]);
37
+ else if (process.platform === 'win32') execFileSync('cmd', ['/c', 'start', '', url]);
38
+ else execFileSync('xdg-open', [url]);
39
+ return true;
40
+ } catch { return false; }
41
+ }
42
+
43
+ // Render the open feedback queue. Pure — testable without the network.
44
+ function formatIssues(issues) {
45
+ if (!Array.isArray(issues) || issues.length === 0) {
46
+ return [' No open feedback right now — the queue is clear.'];
47
+ }
48
+ const lines = issues.slice(0, 15).map(i => {
49
+ const age = Math.max(0, Math.floor((Date.now() - new Date(i.created_at).getTime()) / 86400000));
50
+ const labels = (i.labels || []).map(l => l.name).filter(Boolean).join(', ');
51
+ return ` ${g('#' + i.number)} ${w(String(i.title).slice(0, 70))} ${g(`· ${age}d${labels ? ' · ' + labels : ''}`)}`;
52
+ });
53
+ lines.push('');
54
+ lines.push(` ${g('Pull one into the project room:')} ${cyan('phewsh dispatch "fix: <title> (#<n>)"')} ${g('— teammate or agent claims it, PR closes the loop.')}`);
55
+ return lines;
56
+ }
57
+
58
+ // `phewsh feedback list` — read the public queue so feedback lands in
59
+ // phewsh's own loop (issue → task → claim → PR → record), with phewsh as
60
+ // the database rather than any one chat.
61
+ async function list() {
62
+ console.log('');
63
+ console.log(` ${b(w('Open feedback'))} ${g('— github.com/cleverIdeaz/phewsh-cli/issues')}`);
64
+ console.log('');
65
+ try {
66
+ const res = await fetch('https://api.github.com/repos/cleverIdeaz/phewsh-cli/issues?state=open&per_page=15', {
67
+ headers: { accept: 'application/vnd.github+json' },
68
+ signal: AbortSignal.timeout(6000),
69
+ });
70
+ if (!res.ok) throw new Error(`GitHub API ${res.status}`);
71
+ const issues = (await res.json()).filter(i => !i.pull_request); // issues only, not PRs
72
+ formatIssues(issues).forEach(l => console.log(l));
73
+ } catch (err) {
74
+ console.log(` ${g('Could not reach GitHub (' + err.message + ') — browse directly:')}`);
75
+ console.log(` ${w('https://github.com/cleverIdeaz/phewsh-cli/issues')}`);
76
+ }
77
+ console.log('');
78
+ }
79
+
80
+ function main() {
81
+ const argv = process.argv.slice(3);
82
+ if (argv[0] === 'list') return list();
83
+ const text = argv.filter(a => !a.startsWith('--')).join(' ');
84
+ const url = buildUrl(text);
85
+ console.log('');
86
+ console.log(` ${b(w('phewsh feedback'))} ${g('— where it breaks is exactly what we want to hear')}`);
87
+ console.log(` ${g('Includes only what you see: your words + version/OS/node. Nothing else.')}`);
88
+ console.log('');
89
+ const opened = openBrowser(url);
90
+ if (opened) {
91
+ console.log(` ${cyan('●')} ${g('Opened a prefilled GitHub issue in your browser.')}`);
92
+ } else {
93
+ console.log(` ${g('Open this to file it:')}`);
94
+ console.log(` ${w(url)}`);
95
+ }
96
+ console.log(` ${g('Prefer email?')} ${w(EMAIL)}`);
97
+ console.log('');
98
+ }
99
+
100
+ module.exports = main;
101
+ module.exports.buildUrl = buildUrl;
102
+ module.exports.formatIssues = formatIssues;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phewsh",
3
- "version": "0.15.74",
3
+ "version": "0.15.76",
4
4
  "description": "Turn intent into action. Structure your thinking, execute your next step.",
5
5
  "bin": {
6
6
  "phewsh": "bin/phewsh.js"