sh3-core 0.15.1 → 0.15.2
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/actions/ctx-actions.svelte.test.js +111 -0
- package/dist/actions/dispatcher.svelte.js +23 -2
- package/dist/actions/dispatcher.test.js +33 -0
- package/dist/actions/listActionsFromEntries.test.js +78 -0
- package/dist/actions/listActive.d.ts +2 -1
- package/dist/actions/listActive.js +43 -17
- package/dist/actions/listeners.d.ts +16 -0
- package/dist/actions/listeners.js +68 -14
- package/dist/actions/programmatic-dispatch.svelte.test.d.ts +1 -0
- package/dist/actions/programmatic-dispatch.svelte.test.js +98 -0
- package/dist/actions/types.d.ts +37 -0
- package/dist/api.d.ts +1 -1
- package/dist/app-appearance/appearanceShard.svelte.js +19 -6
- package/dist/app-appearance/appearanceState.svelte.js +3 -3
- package/dist/host.js +2 -1
- package/dist/layouts-shard/LayoutSaveModal.svelte +145 -0
- package/dist/layouts-shard/LayoutSaveModal.svelte.d.ts +12 -0
- package/dist/layouts-shard/LayoutsSection.svelte +142 -0
- package/dist/layouts-shard/LayoutsSection.svelte.d.ts +3 -0
- package/dist/layouts-shard/filter.d.ts +3 -0
- package/dist/layouts-shard/filter.js +66 -0
- package/dist/layouts-shard/filter.test.d.ts +1 -0
- package/dist/layouts-shard/filter.test.js +123 -0
- package/dist/layouts-shard/index.d.ts +1 -0
- package/dist/layouts-shard/index.js +1 -0
- package/dist/layouts-shard/layoutsApi.d.ts +12 -0
- package/dist/layouts-shard/layoutsApi.js +41 -0
- package/dist/layouts-shard/layoutsApi.test.d.ts +1 -0
- package/dist/layouts-shard/layoutsApi.test.js +74 -0
- package/dist/layouts-shard/layoutsShard.svelte.d.ts +11 -0
- package/dist/layouts-shard/layoutsShard.svelte.js +231 -0
- package/dist/layouts-shard/layoutsShard.svelte.test.d.ts +1 -0
- package/dist/layouts-shard/layoutsShard.svelte.test.js +215 -0
- package/dist/layouts-shard/layoutsState.svelte.d.ts +9 -0
- package/dist/layouts-shard/layoutsState.svelte.js +50 -0
- package/dist/layouts-shard/layoutsState.test.d.ts +1 -0
- package/dist/layouts-shard/layoutsState.test.js +43 -0
- package/dist/layouts-shard/types.d.ts +21 -0
- package/dist/layouts-shard/types.js +6 -0
- package/dist/{app-appearance/AppAppearanceModal.svelte → overlays/EntityAppearanceModal.svelte} +36 -31
- package/dist/overlays/EntityAppearanceModal.svelte.d.ts +19 -0
- package/dist/overlays/EntityAppearanceModal.test.d.ts +1 -0
- package/dist/overlays/EntityAppearanceModal.test.js +57 -0
- package/dist/overlays/FloatFrame.svelte +17 -0
- package/dist/overlays/float.d.ts +17 -1
- package/dist/overlays/float.js +16 -0
- package/dist/overlays/float.test.js +35 -0
- package/dist/sh3core-shard/ShellHome.svelte +3 -0
- package/dist/shards/activate.svelte.js +11 -2
- package/dist/shards/types.d.ts +33 -1
- package/dist/shell-shard/CommandLine.svelte +143 -0
- package/dist/shell-shard/CommandLine.svelte.d.ts +26 -0
- package/dist/shell-shard/CommandLine.svelte.test.d.ts +1 -0
- package/dist/shell-shard/CommandLine.svelte.test.js +43 -0
- package/dist/shell-shard/InputLine.svelte +17 -40
- package/dist/shell-shard/InputLine.svelte.d.ts +2 -0
- package/dist/shell-shard/ScrollbackView.svelte +10 -3
- package/dist/shell-shard/ScrollbackView.svelte.d.ts +1 -0
- package/dist/shell-shard/Terminal.svelte +93 -22
- package/dist/shell-shard/buffer-store.d.ts +15 -0
- package/dist/shell-shard/buffer-store.js +124 -0
- package/dist/shell-shard/buffer-store.svelte.test.d.ts +1 -0
- package/dist/shell-shard/buffer-store.svelte.test.js +107 -0
- package/dist/shell-shard/buffer-zone-state.svelte.d.ts +38 -0
- package/dist/shell-shard/buffer-zone-state.svelte.js +31 -0
- package/dist/shell-shard/contract.d.ts +7 -0
- package/dist/shell-shard/dispatch-custom.test.js +3 -1
- package/dist/shell-shard/dispatch-gating.test.js +6 -2
- package/dist/shell-shard/dispatch-invoke.test.js +10 -8
- package/dist/shell-shard/dispatch.d.ts +7 -2
- package/dist/shell-shard/dispatch.js +23 -27
- package/dist/shell-shard/display-cwd.d.ts +1 -0
- package/dist/shell-shard/display-cwd.js +27 -0
- package/dist/shell-shard/display-cwd.test.d.ts +1 -0
- package/dist/shell-shard/display-cwd.test.js +29 -0
- package/dist/shell-shard/entries/StatusEntry.svelte +2 -0
- package/dist/shell-shard/manifest.js +2 -1
- package/dist/shell-shard/manifest.test.d.ts +1 -0
- package/dist/shell-shard/manifest.test.js +8 -0
- package/dist/shell-shard/mode-buffer.svelte.d.ts +8 -0
- package/dist/shell-shard/mode-buffer.svelte.js +19 -0
- package/dist/shell-shard/mode-buffer.svelte.test.d.ts +1 -0
- package/dist/shell-shard/mode-buffer.svelte.test.js +25 -0
- package/dist/shell-shard/modes/builtin.js +2 -0
- package/dist/shell-shard/modes/types.d.ts +8 -0
- package/dist/shell-shard/protocol.d.ts +12 -6
- package/dist/shell-shard/replay.d.ts +3 -0
- package/dist/shell-shard/replay.js +44 -0
- package/dist/shell-shard/replay.svelte.test.d.ts +1 -0
- package/dist/shell-shard/replay.svelte.test.js +47 -0
- package/dist/shell-shard/rich-registry.d.ts +5 -0
- package/dist/shell-shard/rich-registry.js +25 -0
- package/dist/shell-shard/rich-registry.test.d.ts +1 -0
- package/dist/shell-shard/rich-registry.test.js +31 -0
- package/dist/shell-shard/scrollback.svelte.d.ts +2 -0
- package/dist/shell-shard/scrollback.svelte.js +23 -0
- package/dist/shell-shard/scrollback.svelte.test.d.ts +1 -0
- package/dist/shell-shard/scrollback.svelte.test.js +51 -0
- package/dist/shell-shard/session-client.svelte.d.ts +18 -2
- package/dist/shell-shard/session-client.svelte.js +21 -4
- package/dist/shell-shard/shellApi.d.ts +2 -1
- package/dist/shell-shard/shellApi.js +31 -3
- package/dist/shell-shard/shellApi.svelte.test.d.ts +1 -0
- package/dist/shell-shard/shellApi.svelte.test.js +59 -0
- package/dist/shell-shard/shellShard.svelte.js +11 -1
- package/dist/shell-shard/terminal-dispatch.test.js +3 -1
- package/dist/shell-shard/verbs/apps.js +7 -0
- package/dist/shell-shard/verbs/env.js +4 -0
- package/dist/shell-shard/verbs/help.js +4 -0
- package/dist/shell-shard/verbs/history.js +8 -1
- package/dist/shell-shard/verbs/index.js +0 -8
- package/dist/shell-shard/verbs/shards.js +4 -0
- package/dist/shell-shard/verbs/views.js +4 -0
- package/dist/shell-shard/verbs/zones.js +7 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/app-appearance/AppAppearanceModal.svelte.d.ts +0 -8
- package/dist/shell-shard/verbs/cat.d.ts +0 -2
- package/dist/shell-shard/verbs/cat.js +0 -35
- package/dist/shell-shard/verbs/cd.test.js +0 -56
- package/dist/shell-shard/verbs/ls.d.ts +0 -2
- package/dist/shell-shard/verbs/ls.js +0 -30
- package/dist/shell-shard/verbs/ls.test.js +0 -49
- package/dist/shell-shard/verbs/session.d.ts +0 -4
- package/dist/shell-shard/verbs/session.js +0 -99
- /package/dist/{shell-shard/verbs/cd.test.d.ts → actions/ctx-actions.svelte.test.d.ts} +0 -0
- /package/dist/{shell-shard/verbs/ls.test.d.ts → actions/listActionsFromEntries.test.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export const catVerb = {
|
|
2
|
-
name: 'cat',
|
|
3
|
-
summary: 'Read a file into the scrollback.',
|
|
4
|
-
programmatic: true,
|
|
5
|
-
async run(ctx, args) {
|
|
6
|
-
if (args.length === 0) {
|
|
7
|
-
ctx.scrollback.push({
|
|
8
|
-
kind: 'status',
|
|
9
|
-
text: 'cat: missing file argument',
|
|
10
|
-
level: 'error',
|
|
11
|
-
ts: Date.now(),
|
|
12
|
-
});
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const path = args[0];
|
|
16
|
-
const target = ctx.session.cwd ? `${ctx.session.cwd}/${path}` : path;
|
|
17
|
-
try {
|
|
18
|
-
const text = await ctx.fs.read(target);
|
|
19
|
-
ctx.scrollback.push({
|
|
20
|
-
kind: 'text',
|
|
21
|
-
stream: 'stdout',
|
|
22
|
-
chunks: [text],
|
|
23
|
-
ts: Date.now(),
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
catch (err) {
|
|
27
|
-
ctx.scrollback.push({
|
|
28
|
-
kind: 'status',
|
|
29
|
-
text: `cat: ${err.message}`,
|
|
30
|
-
level: 'error',
|
|
31
|
-
ts: Date.now(),
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { cdVerb } from './session';
|
|
3
|
-
function makeCtx(initialCwd, fsStat) {
|
|
4
|
-
const pushed = [];
|
|
5
|
-
const session = { cwd: initialCwd };
|
|
6
|
-
const ctx = {
|
|
7
|
-
shell: {},
|
|
8
|
-
scrollback: { push: (e) => pushed.push(e) },
|
|
9
|
-
session,
|
|
10
|
-
cwd: initialCwd,
|
|
11
|
-
fs: {
|
|
12
|
-
list: async () => [],
|
|
13
|
-
stat: fsStat,
|
|
14
|
-
read: async () => '',
|
|
15
|
-
},
|
|
16
|
-
dispatch: async () => { },
|
|
17
|
-
};
|
|
18
|
-
return { ctx, session, pushed };
|
|
19
|
-
}
|
|
20
|
-
describe('cd verb', () => {
|
|
21
|
-
it('updates session.cwd on successful dir stat', async () => {
|
|
22
|
-
const { ctx, session } = makeCtx('', async (_path) => ({
|
|
23
|
-
name: 'projects',
|
|
24
|
-
kind: 'dir',
|
|
25
|
-
size: 0,
|
|
26
|
-
mtime: 0,
|
|
27
|
-
}));
|
|
28
|
-
await cdVerb.run(ctx, ['projects']);
|
|
29
|
-
expect(session.cwd).toBe('projects');
|
|
30
|
-
});
|
|
31
|
-
it('pushes error when target is a file, not a directory', async () => {
|
|
32
|
-
const { ctx, session, pushed } = makeCtx('', async (_path) => ({
|
|
33
|
-
name: 'readme.txt',
|
|
34
|
-
kind: 'file',
|
|
35
|
-
size: 100,
|
|
36
|
-
mtime: 0,
|
|
37
|
-
}));
|
|
38
|
-
await cdVerb.run(ctx, ['readme.txt']);
|
|
39
|
-
expect(session.cwd).toBe('');
|
|
40
|
-
const entry = pushed[0];
|
|
41
|
-
expect(entry.kind).toBe('status');
|
|
42
|
-
expect(entry.level).toBe('error');
|
|
43
|
-
expect(entry.text).toMatch(/not a directory/);
|
|
44
|
-
});
|
|
45
|
-
it('pushes error when fs.stat throws', async () => {
|
|
46
|
-
const { ctx, session, pushed } = makeCtx('', async (_path) => {
|
|
47
|
-
throw new Error('no such file');
|
|
48
|
-
});
|
|
49
|
-
await cdVerb.run(ctx, ['nonexistent']);
|
|
50
|
-
expect(session.cwd).toBe('');
|
|
51
|
-
const entry = pushed[0];
|
|
52
|
-
expect(entry.kind).toBe('status');
|
|
53
|
-
expect(entry.level).toBe('error');
|
|
54
|
-
expect(entry.text).toMatch(/no such file/);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export const lsVerb = {
|
|
2
|
-
name: 'ls',
|
|
3
|
-
summary: 'List the current directory.',
|
|
4
|
-
programmatic: true,
|
|
5
|
-
async run(ctx) {
|
|
6
|
-
let entries;
|
|
7
|
-
try {
|
|
8
|
-
entries = await ctx.fs.list(ctx.session.cwd);
|
|
9
|
-
}
|
|
10
|
-
catch (err) {
|
|
11
|
-
ctx.scrollback.push({
|
|
12
|
-
kind: 'status',
|
|
13
|
-
text: `ls: ${err.message}`,
|
|
14
|
-
level: 'error',
|
|
15
|
-
ts: Date.now(),
|
|
16
|
-
});
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
const lines = entries
|
|
20
|
-
.sort((a, b) => a.name.localeCompare(b.name))
|
|
21
|
-
.map((e) => (e.kind === 'dir' ? `${e.name}/` : e.name))
|
|
22
|
-
.join('\n');
|
|
23
|
-
ctx.scrollback.push({
|
|
24
|
-
kind: 'text',
|
|
25
|
-
stream: 'stdout',
|
|
26
|
-
chunks: [lines || '(empty)'],
|
|
27
|
-
ts: Date.now(),
|
|
28
|
-
});
|
|
29
|
-
},
|
|
30
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { lsVerb } from './ls';
|
|
3
|
-
function makeCtx(cwd, fsList) {
|
|
4
|
-
const pushed = [];
|
|
5
|
-
const ctx = {
|
|
6
|
-
shell: {},
|
|
7
|
-
scrollback: { push: (e) => pushed.push(e) },
|
|
8
|
-
session: { cwd },
|
|
9
|
-
cwd,
|
|
10
|
-
fs: {
|
|
11
|
-
list: fsList,
|
|
12
|
-
stat: async () => ({ kind: 'dir', name: '', size: 0, mtime: 0 }),
|
|
13
|
-
read: async () => '',
|
|
14
|
-
},
|
|
15
|
-
dispatch: async () => { },
|
|
16
|
-
};
|
|
17
|
-
return { ctx, pushed };
|
|
18
|
-
}
|
|
19
|
-
describe('ls verb', () => {
|
|
20
|
-
it('lists entries sorted, dirs with trailing slash', async () => {
|
|
21
|
-
const { ctx, pushed } = makeCtx('', async () => [
|
|
22
|
-
{ name: 'zebra.txt', kind: 'file', size: 1, mtime: 0 },
|
|
23
|
-
{ name: 'apple', kind: 'dir', size: 0, mtime: 0 },
|
|
24
|
-
{ name: 'mango.txt', kind: 'file', size: 2, mtime: 0 },
|
|
25
|
-
]);
|
|
26
|
-
await lsVerb.run(ctx, []);
|
|
27
|
-
expect(pushed).toHaveLength(1);
|
|
28
|
-
const entry = pushed[0];
|
|
29
|
-
expect(entry.kind).toBe('text');
|
|
30
|
-
expect(entry.chunks[0]).toBe('apple/\nmango.txt\nzebra.txt');
|
|
31
|
-
});
|
|
32
|
-
it('shows (empty) for empty directory', async () => {
|
|
33
|
-
const { ctx, pushed } = makeCtx('', async () => []);
|
|
34
|
-
await lsVerb.run(ctx, []);
|
|
35
|
-
const entry = pushed[0];
|
|
36
|
-
expect(entry.kind).toBe('text');
|
|
37
|
-
expect(entry.chunks[0]).toBe('(empty)');
|
|
38
|
-
});
|
|
39
|
-
it('pushes status error when fs.list throws', async () => {
|
|
40
|
-
const { ctx, pushed } = makeCtx('', async () => {
|
|
41
|
-
throw new Error('permission denied');
|
|
42
|
-
});
|
|
43
|
-
await lsVerb.run(ctx, []);
|
|
44
|
-
const entry = pushed[0];
|
|
45
|
-
expect(entry.kind).toBe('status');
|
|
46
|
-
expect(entry.level).toBe('error');
|
|
47
|
-
expect(entry.text).toMatch(/permission denied/);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Session verbs: pwd, cd, whoami.
|
|
3
|
-
*
|
|
4
|
-
* cd validates the target path via ctx.fs.stat() then updates session.cwd
|
|
5
|
-
* locally. The server still owns the authoritative cwd for forwarded
|
|
6
|
-
* commands, but local verbs track it via session.cwd.
|
|
7
|
-
*
|
|
8
|
-
* envVerb lives in env.ts (separate Svelte import).
|
|
9
|
-
*/
|
|
10
|
-
// ---------------------------------------------------------------------------
|
|
11
|
-
// Path helpers
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
function joinRel(cwd, input) {
|
|
14
|
-
if (input.startsWith('/'))
|
|
15
|
-
return normalizeRel(input.slice(1));
|
|
16
|
-
const parts = [...cwd.split('/').filter(Boolean), ...input.split('/')];
|
|
17
|
-
const stack = [];
|
|
18
|
-
for (const p of parts) {
|
|
19
|
-
if (p === '' || p === '.')
|
|
20
|
-
continue;
|
|
21
|
-
if (p === '..') {
|
|
22
|
-
stack.pop();
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
stack.push(p);
|
|
26
|
-
}
|
|
27
|
-
return stack.join('/');
|
|
28
|
-
}
|
|
29
|
-
function normalizeRel(s) {
|
|
30
|
-
return s.split('/').filter((p) => p && p !== '.').join('/');
|
|
31
|
-
}
|
|
32
|
-
// ---------------------------------------------------------------------------
|
|
33
|
-
// Verbs
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
export const pwdVerb = {
|
|
36
|
-
name: 'pwd',
|
|
37
|
-
summary: 'Show the current working directory.',
|
|
38
|
-
programmatic: true,
|
|
39
|
-
async run(ctx) {
|
|
40
|
-
const rel = ctx.session.cwd || '';
|
|
41
|
-
const display = rel.startsWith('/') ? rel : `/${rel}`;
|
|
42
|
-
ctx.scrollback.push({
|
|
43
|
-
kind: 'text',
|
|
44
|
-
stream: 'stdout',
|
|
45
|
-
chunks: [display + '\n'],
|
|
46
|
-
ts: Date.now(),
|
|
47
|
-
});
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
export const cdVerb = {
|
|
51
|
-
name: 'cd',
|
|
52
|
-
summary: 'Change the session working directory.',
|
|
53
|
-
async run(ctx, args) {
|
|
54
|
-
var _a;
|
|
55
|
-
const target = (_a = args[0]) !== null && _a !== void 0 ? _a : '';
|
|
56
|
-
if (target === '') {
|
|
57
|
-
ctx.session.cwd = '';
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const base = ctx.session.cwd;
|
|
61
|
-
const candidate = joinRel(base, target);
|
|
62
|
-
try {
|
|
63
|
-
const s = await ctx.fs.stat(candidate);
|
|
64
|
-
if (s.kind !== 'dir') {
|
|
65
|
-
ctx.scrollback.push({
|
|
66
|
-
kind: 'status',
|
|
67
|
-
text: `cd: not a directory: ${target}`,
|
|
68
|
-
level: 'error',
|
|
69
|
-
ts: Date.now(),
|
|
70
|
-
});
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
catch (err) {
|
|
75
|
-
ctx.scrollback.push({
|
|
76
|
-
kind: 'status',
|
|
77
|
-
text: `cd: ${err.message}`,
|
|
78
|
-
level: 'error',
|
|
79
|
-
ts: Date.now(),
|
|
80
|
-
});
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
ctx.session.cwd = candidate;
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
export const whoamiVerb = {
|
|
87
|
-
name: 'whoami',
|
|
88
|
-
summary: 'Show the current admin user and session info.',
|
|
89
|
-
programmatic: true,
|
|
90
|
-
async run(ctx) {
|
|
91
|
-
const me = ctx.shell.whoAmI();
|
|
92
|
-
ctx.scrollback.push({
|
|
93
|
-
kind: 'text',
|
|
94
|
-
stream: 'stdout',
|
|
95
|
-
chunks: [`${me.userId}${me.admin ? ' (admin)' : ''}\n`],
|
|
96
|
-
ts: Date.now(),
|
|
97
|
-
});
|
|
98
|
-
},
|
|
99
|
-
};
|
|
File without changes
|
|
File without changes
|