phewsh 0.15.76 → 0.15.78
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 +18 -1
- package/bin/phewsh.js +3 -1
- package/commands/ion.js +115 -0
- package/commands/serve.js +3 -3
- package/commands/status.js +1 -1
- package/lib/shims.js +1 -1
- package/lib/slash-commands.js +1 -1
- package/package.json +11 -3
package/README.md
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# phewsh
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**One mission. Many AI tools. No lost context.**
|
|
4
|
+
|
|
5
|
+
PHEWSH is the continuity layer for AI-assisted work: it turns what you're
|
|
6
|
+
building into durable project intent (`.intent/`) and carries it across
|
|
7
|
+
Claude Code, Codex, Cursor, Gemini, your terminal, and your team — so the
|
|
8
|
+
next AI knows what the last one learned.
|
|
4
9
|
|
|
5
10
|
## Install
|
|
6
11
|
|
|
@@ -204,6 +209,18 @@ the same canonical `.intent/` source.
|
|
|
204
209
|
|
|
205
210
|
[phewsh.com/intent](https://phewsh.com/intent)
|
|
206
211
|
|
|
212
|
+
## Feedback
|
|
213
|
+
|
|
214
|
+
Something missing, confusing, or broken?
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
phewsh feedback "what you expected vs what happened"
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
That opens a prefilled public issue on this repo (only your words plus
|
|
221
|
+
version/OS/node — documented in [SECURITY.md](./SECURITY.md)). Private
|
|
222
|
+
channel: hello@phewsh.com.
|
|
223
|
+
|
|
207
224
|
## License
|
|
208
225
|
|
|
209
226
|
MIT
|
package/bin/phewsh.js
CHANGED
|
@@ -113,6 +113,7 @@ const COMMANDS = {
|
|
|
113
113
|
remember: () => require('../commands/remember')(),
|
|
114
114
|
task: () => require('../commands/task')(),
|
|
115
115
|
dispatch: () => require('../commands/task')(),
|
|
116
|
+
ion: () => require('../commands/ion')(),
|
|
116
117
|
pack: () => require('../commands/pack')(),
|
|
117
118
|
hook: () => require('../commands/hook')(),
|
|
118
119
|
feedback: () => require('../commands/feedback')(),
|
|
@@ -159,7 +160,8 @@ function showHelp() {
|
|
|
159
160
|
console.log(` ${cyan('seq')} ${g('Sequence all memory → optimal context for any agent')}`);
|
|
160
161
|
console.log(` ${cyan('watch')} ${g('Auto-sync .intent/ → native harness files + cloud')}`);
|
|
161
162
|
console.log(` ${cyan('push/pull')} ${g('Manual sync to/from phewsh.com/intent')}`);
|
|
162
|
-
console.log(` ${cyan('serve')} ${g('Execution bridge — run from phewsh.com/intent')}`);
|
|
163
|
+
console.log(` ${cyan('serve')} ${g('Execution bridge — run from phewsh.com/ion or /intent')}`);
|
|
164
|
+
console.log(` ${cyan('ion')} ${g('Shared visual room for humans + local agents')}`);
|
|
163
165
|
console.log(` ${cyan('mcp')} ${g('Connect AI agents via MCP protocol')}`);
|
|
164
166
|
console.log(` ${cyan('ambient')} ${g('Continuity without launching phewsh — enhance your other tools')}`);
|
|
165
167
|
console.log(` ${cyan('shim')} ${g('Guaranteed launch banner — phewsh prints status before each tool')}`);
|
package/commands/ion.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// phewsh ion — command surface for the shared visual room.
|
|
2
|
+
//
|
|
3
|
+
// Ion is not a second execution system. It is the room over the existing
|
|
4
|
+
// Phewsh primitives:
|
|
5
|
+
// - `serve` exposes the local worker bridge
|
|
6
|
+
// - `task` owns shared requests, invites, claims, reviews, and receipts
|
|
7
|
+
// - `/ion` is the browser room where humans can see and steer the loop
|
|
8
|
+
|
|
9
|
+
const { execFileSync } = require('child_process');
|
|
10
|
+
|
|
11
|
+
const WEB_URL = 'https://phewsh.com/ion';
|
|
12
|
+
|
|
13
|
+
const cream = (s) => `\x1b[97m${s}\x1b[0m`;
|
|
14
|
+
const sage = (s) => `\x1b[38;5;247m${s}\x1b[0m`;
|
|
15
|
+
const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
|
|
16
|
+
const green = (s) => `\x1b[32m${s}\x1b[0m`;
|
|
17
|
+
const red = (s) => `\x1b[31m${s}\x1b[0m`;
|
|
18
|
+
|
|
19
|
+
function openBrowser(url = WEB_URL) {
|
|
20
|
+
try {
|
|
21
|
+
if (process.platform === 'darwin') execFileSync('open', [url]);
|
|
22
|
+
else if (process.platform === 'win32') execFileSync('cmd', ['/c', 'start', '', url]);
|
|
23
|
+
else execFileSync('xdg-open', [url]);
|
|
24
|
+
console.log(`\n ${green('✓')} Opened ${cream(url)}\n`);
|
|
25
|
+
} catch {
|
|
26
|
+
console.log(`\n ${sage('Could not open browser. Visit:')} ${cream(url)}\n`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function showHelp() {
|
|
31
|
+
console.log(`
|
|
32
|
+
${cream('phewsh ion')} — shared rooms for humans + local agents
|
|
33
|
+
|
|
34
|
+
${sage('Open the room')}
|
|
35
|
+
${cyan('phewsh ion')} ${sage('open phewsh.com/ion')}
|
|
36
|
+
${cyan('phewsh ion open')} ${sage('same')}
|
|
37
|
+
|
|
38
|
+
${sage('Make this machine available')}
|
|
39
|
+
${cyan('phewsh ion serve')} ${sage('start the local worker bridge')}
|
|
40
|
+
${cyan('phewsh ion status')} ${sage('show bridge/project/task status')}
|
|
41
|
+
|
|
42
|
+
${sage('Use the existing task loop')}
|
|
43
|
+
${cyan('phewsh ion task')} ${sage('list shared tasks')}
|
|
44
|
+
${cyan('phewsh ion request "..."')} ${sage('request work in the room')}
|
|
45
|
+
${cyan('phewsh ion claim next')} ${sage('manual claim + isolated PR flow')}
|
|
46
|
+
${cyan('phewsh ion invite <email>')} ${sage('invite a teammate')}
|
|
47
|
+
${cyan('phewsh ion join')} ${sage('accept pending invites')}
|
|
48
|
+
|
|
49
|
+
${sage('Connectors')}
|
|
50
|
+
${cyan('phewsh ion connectors')} ${sage('show Slack/Discord connector plan')}
|
|
51
|
+
`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function showConnectors() {
|
|
55
|
+
console.log(`
|
|
56
|
+
${cream('Ion connectors')}
|
|
57
|
+
|
|
58
|
+
${sage('Canonical room:')} ${cream('phewsh.com/ion')}
|
|
59
|
+
${sage('Execution:')} ${cream('phewsh ion serve')} ${sage('or')} ${cream('phewsh ion claim <id>')}
|
|
60
|
+
|
|
61
|
+
${sage('Slack and Discord are connectors, not the core room yet.')}
|
|
62
|
+
${sage('Planned flow:')}
|
|
63
|
+
Slack/Discord mention
|
|
64
|
+
→ Ion task request
|
|
65
|
+
→ human approval in Ion
|
|
66
|
+
→ local/VPS Phewsh worker runs
|
|
67
|
+
→ branch/PR/evidence returns to Ion
|
|
68
|
+
→ notification posts back to Slack/Discord
|
|
69
|
+
|
|
70
|
+
${sage('Do not build bot auto-execution first. Keep Ion as the source of truth.')}
|
|
71
|
+
`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function runTask(args) {
|
|
75
|
+
process.argv = [process.argv[0], process.argv[1], 'task', ...args];
|
|
76
|
+
return require('./task')();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function runServe(args) {
|
|
80
|
+
process.argv = [process.argv[0], process.argv[1], 'serve', ...args];
|
|
81
|
+
return require('./serve')();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = async function run() {
|
|
85
|
+
const args = process.argv.slice(3);
|
|
86
|
+
const sub = args[0] || 'open';
|
|
87
|
+
const rest = args.slice(1);
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
if (sub === '--help' || sub === '-h' || sub === 'help') return showHelp();
|
|
91
|
+
if (sub === 'open') return openBrowser();
|
|
92
|
+
if (sub === 'serve' || sub === 'worker') return runServe(rest);
|
|
93
|
+
if (sub === 'status') {
|
|
94
|
+
console.log(`\n ${cream('Ion room:')} ${cyan(WEB_URL)}`);
|
|
95
|
+
console.log(` ${sage('Local worker:')} ${cream('phewsh ion serve')}`);
|
|
96
|
+
return runTask(['list']);
|
|
97
|
+
}
|
|
98
|
+
if (sub === 'task' || sub === 'tasks') return runTask(rest.length ? rest : ['list']);
|
|
99
|
+
if (sub === 'request' || sub === 'new') return runTask(['new', ...rest]);
|
|
100
|
+
if (sub === 'claim') return runTask(['claim', ...rest]);
|
|
101
|
+
if (sub === 'invite') return runTask(['invite', ...rest]);
|
|
102
|
+
if (sub === 'join') return runTask(['join']);
|
|
103
|
+
if (sub === 'reconcile') return runTask(['reconcile', ...rest]);
|
|
104
|
+
if (sub === 'connectors' || sub === 'slack' || sub === 'discord') return showConnectors();
|
|
105
|
+
|
|
106
|
+
console.log(`\n ${red('✗')} Unknown ion command: ${sub}\n`);
|
|
107
|
+
showHelp();
|
|
108
|
+
process.exitCode = 1;
|
|
109
|
+
} catch (err) {
|
|
110
|
+
console.error(`\n ${red('✗')} ${err.message}\n`);
|
|
111
|
+
process.exitCode = 1;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
module.exports.openBrowser = openBrowser;
|
package/commands/serve.js
CHANGED
|
@@ -220,7 +220,7 @@ function json(req, res, data, status = 200) {
|
|
|
220
220
|
|
|
221
221
|
function main() {
|
|
222
222
|
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
223
|
-
console.log('\n phewsh serve — local execution bridge for phewsh.com/intent');
|
|
223
|
+
console.log('\n phewsh serve — local execution bridge for phewsh.com/ion and phewsh.com/intent');
|
|
224
224
|
console.log(' Runs a loopback server so the web workspace can dispatch to your');
|
|
225
225
|
console.log(' installed agents. Stays running until you stop it (ctrl+c).');
|
|
226
226
|
console.log('\n Usage: phewsh serve [--port <n>] (default 7483)\n');
|
|
@@ -358,7 +358,7 @@ function main() {
|
|
|
358
358
|
|
|
359
359
|
console.log('');
|
|
360
360
|
console.log(` ${b(w('PHEWSH Serve'))} ${g('v' + require('../package.json').version)}`);
|
|
361
|
-
console.log(` ${g('Live execution bridge for phewsh.com/intent')}`);
|
|
361
|
+
console.log(` ${g('Live execution bridge for phewsh.com/ion and phewsh.com/intent')}`);
|
|
362
362
|
console.log('');
|
|
363
363
|
console.log(` ${green('●')} Running on ${w(`http://localhost:${port}`)}`);
|
|
364
364
|
console.log(` ${g('Web cockpit:')} ${w('phewsh.com/cockpit')} ${g('— mirrors this machine live')}`);
|
|
@@ -374,7 +374,7 @@ function main() {
|
|
|
374
374
|
console.log(` ${g('https://docs.anthropic.com/en/docs/claude-code')}`);
|
|
375
375
|
}
|
|
376
376
|
console.log('');
|
|
377
|
-
console.log(` ${g('Open phewsh.com/
|
|
377
|
+
console.log(` ${g('Open phewsh.com/ion to see the worker online, or phewsh.com/intent → Work')}`);
|
|
378
378
|
console.log(` ${g('Press Ctrl+C to stop')}`);
|
|
379
379
|
console.log('');
|
|
380
380
|
});
|
package/commands/status.js
CHANGED
|
@@ -59,7 +59,7 @@ function main() {
|
|
|
59
59
|
if (!hasIntent) {
|
|
60
60
|
console.log(row('PROJECT', `${off} ${sage('no shared project truth here yet')}`));
|
|
61
61
|
console.log(row('', slate('create it so you — and the next AI — inherit context:')));
|
|
62
|
-
console.log(row('', cream('phewsh
|
|
62
|
+
console.log(row('', `${cream('phewsh init')} ${slate('(two questions) · guided:')} ${cream('phewsh clarify')}`));
|
|
63
63
|
} else {
|
|
64
64
|
const files = fs.readdirSync(intentDir).filter(f => /\.(md|json)$/.test(f));
|
|
65
65
|
const has = (f) => files.includes(f);
|
package/lib/shims.js
CHANGED
|
@@ -114,7 +114,7 @@ function preflightBanner(bin, cwd = process.cwd()) {
|
|
|
114
114
|
const n = bumpNudge(cwd);
|
|
115
115
|
if (n <= 3) {
|
|
116
116
|
return `${C.sage('😮💨🤫 phewsh')} ${C.slate('· no shared project truth here yet')}\n`
|
|
117
|
-
+ ` ${C.slate('so every AI tool stays in sync, create it:')} ${C.cream('phewsh
|
|
117
|
+
+ ` ${C.slate('so every AI tool stays in sync, create it:')} ${C.cream('phewsh init')} ${C.slate('· → ' + bin)}`;
|
|
118
118
|
}
|
|
119
119
|
return `${C.sage('😮💨🤫 phewsh active')} ${C.slate('· → ' + bin)}`;
|
|
120
120
|
}
|
package/lib/slash-commands.js
CHANGED
|
@@ -24,7 +24,7 @@ const INTENT_PROMPT = `Show me this project's current intent, read from its \`.i
|
|
|
24
24
|
- **Constraints** — budget, time, scope, non-negotiables
|
|
25
25
|
- **Recent decisions** — and any that are still open
|
|
26
26
|
|
|
27
|
-
If there is no \`.intent/\` directory here, say so and tell me I can create one with \`phewsh
|
|
27
|
+
If there is no \`.intent/\` directory here, say so and tell me I can create one with \`phewsh init\` so every AI tool I use shares the same project truth.`;
|
|
28
28
|
|
|
29
29
|
// Tools that support file-based custom slash commands, and how each wants them.
|
|
30
30
|
// parentDir must already exist (the tool is installed) before we write.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "phewsh",
|
|
3
|
-
"version": "0.15.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.15.78",
|
|
4
|
+
"description": "One mission. Many AI tools. No lost context. PHEWSH keeps your project's intent, decisions, and working context aligned across Claude Code, Codex, Cursor, Gemini and your team — so the next AI knows what the last one learned.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"phewsh": "bin/phewsh.js"
|
|
7
7
|
},
|
|
@@ -25,7 +25,15 @@
|
|
|
25
25
|
"claude",
|
|
26
26
|
"mcp",
|
|
27
27
|
"model-context-protocol",
|
|
28
|
-
"phewsh"
|
|
28
|
+
"phewsh",
|
|
29
|
+
"continuity",
|
|
30
|
+
"context",
|
|
31
|
+
"agents",
|
|
32
|
+
"claude-code",
|
|
33
|
+
"codex",
|
|
34
|
+
"cursor",
|
|
35
|
+
"gemini",
|
|
36
|
+
"agents-md"
|
|
29
37
|
],
|
|
30
38
|
"author": "Phewsh <hello@phewsh.com>",
|
|
31
39
|
"license": "MIT",
|