sh3-core 0.20.1 → 0.20.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.
Files changed (70) hide show
  1. package/dist/documents/backends.d.ts +12 -0
  2. package/dist/documents/backends.js +230 -3
  3. package/dist/documents/backends.test.js +147 -1
  4. package/dist/documents/config.d.ts +2 -0
  5. package/dist/documents/config.js +4 -0
  6. package/dist/documents/handle.js +40 -0
  7. package/dist/documents/handle.test.js +88 -1
  8. package/dist/documents/http-backend.d.ts +6 -0
  9. package/dist/documents/http-backend.js +61 -0
  10. package/dist/documents/http-backend.test.js +51 -1
  11. package/dist/documents/picker-api.test.js +2 -2
  12. package/dist/documents/types.d.ts +76 -14
  13. package/dist/documents/types.js +4 -0
  14. package/dist/primitives/widgets/DocumentFilePicker.d.ts +6 -2
  15. package/dist/primitives/widgets/DocumentFilePicker.js +12 -5
  16. package/dist/primitives/widgets/DocumentFilePicker.svelte +23 -1
  17. package/dist/primitives/widgets/DocumentFilePicker.svelte.d.ts +14 -0
  18. package/dist/primitives/widgets/DocumentFilePicker.test.d.ts +1 -0
  19. package/dist/primitives/widgets/DocumentFilePicker.test.js +33 -0
  20. package/dist/primitives/widgets/DocumentOpener.svelte +20 -0
  21. package/dist/primitives/widgets/DocumentOpener.svelte.d.ts +14 -0
  22. package/dist/primitives/widgets/DocumentSaver.svelte +17 -0
  23. package/dist/primitives/widgets/DocumentSaver.svelte.d.ts +13 -0
  24. package/dist/primitives/widgets/_DocumentBrowser.svelte +414 -27
  25. package/dist/primitives/widgets/_DocumentBrowser.svelte.d.ts +12 -0
  26. package/dist/primitives/widgets/_DocumentBrowser.svelte.test.d.ts +1 -0
  27. package/dist/primitives/widgets/_DocumentBrowser.svelte.test.js +277 -0
  28. package/dist/primitives/widgets/_FolderConfirmDelete.svelte +57 -0
  29. package/dist/primitives/widgets/_FolderConfirmDelete.svelte.d.ts +12 -0
  30. package/dist/sh3Api/headless.js +10 -0
  31. package/dist/shards/activate.svelte.js +2 -2
  32. package/dist/shell-shard/Terminal.svelte +4 -1
  33. package/dist/shell-shard/Terminal.svelte.d.ts +2 -0
  34. package/dist/shell-shard/dispatch.d.ts +2 -0
  35. package/dist/shell-shard/dispatch.js +2 -0
  36. package/dist/shell-shard/manifest.js +7 -1
  37. package/dist/shell-shard/shellShard.svelte.js +1 -1
  38. package/dist/shell-shard/verbs/cat.d.ts +2 -0
  39. package/dist/shell-shard/verbs/cat.js +35 -0
  40. package/dist/shell-shard/verbs/cat.test.d.ts +1 -0
  41. package/dist/shell-shard/verbs/cat.test.js +49 -0
  42. package/dist/shell-shard/verbs/index.js +12 -0
  43. package/dist/shell-shard/verbs/ls.d.ts +2 -0
  44. package/dist/shell-shard/verbs/ls.js +48 -0
  45. package/dist/shell-shard/verbs/ls.test.d.ts +1 -0
  46. package/dist/shell-shard/verbs/ls.test.js +64 -0
  47. package/dist/shell-shard/verbs/mkdir.d.ts +2 -0
  48. package/dist/shell-shard/verbs/mkdir.js +30 -0
  49. package/dist/shell-shard/verbs/mkdir.test.d.ts +1 -0
  50. package/dist/shell-shard/verbs/mkdir.test.js +48 -0
  51. package/dist/shell-shard/verbs/mv.d.ts +2 -0
  52. package/dist/shell-shard/verbs/mv.js +33 -0
  53. package/dist/shell-shard/verbs/mv.test.d.ts +1 -0
  54. package/dist/shell-shard/verbs/mv.test.js +55 -0
  55. package/dist/shell-shard/verbs/rm.d.ts +2 -0
  56. package/dist/shell-shard/verbs/rm.js +28 -0
  57. package/dist/shell-shard/verbs/rm.test.d.ts +1 -0
  58. package/dist/shell-shard/verbs/rm.test.js +47 -0
  59. package/dist/shell-shard/verbs/scope-parse.d.ts +7 -0
  60. package/dist/shell-shard/verbs/scope-parse.js +33 -0
  61. package/dist/shell-shard/verbs/scope-parse.test.d.ts +1 -0
  62. package/dist/shell-shard/verbs/scope-parse.test.js +76 -0
  63. package/dist/shell-shard/verbs/xfer.d.ts +2 -0
  64. package/dist/shell-shard/verbs/xfer.js +101 -0
  65. package/dist/shell-shard/verbs/xfer.test.d.ts +1 -0
  66. package/dist/shell-shard/verbs/xfer.test.js +96 -0
  67. package/dist/verbs/types.d.ts +18 -0
  68. package/dist/version.d.ts +1 -1
  69. package/dist/version.js +1 -1
  70. package/package.json +1 -1
@@ -0,0 +1,96 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { xferVerb } from './xfer';
3
+ function makeDocs(overrides = {}) {
4
+ return Object.assign({ listDocuments: vi.fn(async () => []), listShards: vi.fn(async () => []), watchDocuments: vi.fn(() => () => { }), transferToScope: vi.fn(async () => { }) }, overrides);
5
+ }
6
+ function makeSh3(scope) {
7
+ return {
8
+ getActiveScope: () => scope,
9
+ listProjects: () => [],
10
+ };
11
+ }
12
+ function makeCtx(docs, sh3) {
13
+ const pushed = [];
14
+ const ctx = {
15
+ sh3: sh3 !== null && sh3 !== void 0 ? sh3 : {},
16
+ scrollback: { push: (e) => pushed.push(e) },
17
+ session: {},
18
+ cwd: '/',
19
+ fs: {},
20
+ docs,
21
+ dispatch: async () => { },
22
+ };
23
+ return { ctx, pushed };
24
+ }
25
+ const projectScope = { id: 'proj-abc', isProject: true, personalId: 'user-me' };
26
+ const personalScope = { id: 'user-me', isProject: false, personalId: 'user-me' };
27
+ describe('xfer verb', () => {
28
+ it('emits error when docs capability missing', async () => {
29
+ const sh3 = makeSh3(projectScope);
30
+ const { ctx, pushed } = makeCtx(undefined, sh3);
31
+ await xferVerb.run(ctx, ['@project-proj-abc:notes/draft.md', '@me:notes/draft.md']);
32
+ const err = pushed.find((e) => e.kind === 'status' && e.level === 'error');
33
+ expect(err).toBeDefined();
34
+ });
35
+ it('emits error when active scope is not a project', async () => {
36
+ const sh3 = makeSh3(personalScope);
37
+ const { ctx, pushed } = makeCtx(makeDocs(), sh3);
38
+ await xferVerb.run(ctx, ['notes/draft.md', '@me:notes/draft.md']);
39
+ const err = pushed.find((e) => e.kind === 'status' && e.level === 'error');
40
+ expect(err).toBeDefined();
41
+ expect(err.text).toMatch(/project/i);
42
+ });
43
+ it('emits usage error when fewer than two args', async () => {
44
+ const sh3 = makeSh3(projectScope);
45
+ const { ctx, pushed } = makeCtx(makeDocs(), sh3);
46
+ await xferVerb.run(ctx, ['notes/draft.md']);
47
+ const err = pushed.find((e) => e.kind === 'status' && e.level === 'error');
48
+ expect(err.text).toMatch(/usage/i);
49
+ });
50
+ it('moves (default) a doc from project to personal scope', async () => {
51
+ const transferToScope = vi.fn(async () => { });
52
+ const docs = makeDocs({ transferToScope });
53
+ const sh3 = makeSh3(projectScope);
54
+ const { ctx, pushed } = makeCtx(docs, sh3);
55
+ await xferVerb.run(ctx, ['@project-proj-abc:notes/draft.md', '@me:notes/draft.md']);
56
+ expect(transferToScope).toHaveBeenCalledWith('notes', 'draft.md', 'user-me', expect.objectContaining({ delete: true }));
57
+ const ok = pushed.find((e) => e.kind === 'status' && e.level === 'info');
58
+ expect(ok).toBeDefined();
59
+ });
60
+ it('-C flag copies without deleting source', async () => {
61
+ const transferToScope = vi.fn(async () => { });
62
+ const docs = makeDocs({ transferToScope });
63
+ const sh3 = makeSh3(projectScope);
64
+ const { ctx } = makeCtx(docs, sh3);
65
+ await xferVerb.run(ctx, ['-C', '@project-proj-abc:notes/draft.md', '@me:notes/draft.md']);
66
+ expect(transferToScope).toHaveBeenCalledWith('notes', 'draft.md', 'user-me', expect.objectContaining({ delete: false }));
67
+ });
68
+ it('rejects when src scope is not the active project (v1 limitation)', async () => {
69
+ const transferToScope = vi.fn(async () => { });
70
+ const docs = makeDocs({ transferToScope });
71
+ const sh3 = makeSh3(projectScope);
72
+ const { ctx, pushed } = makeCtx(docs, sh3);
73
+ // @me src while project is active → src tenant differs from active
74
+ await xferVerb.run(ctx, ['@me:notes/draft.md', '@project-proj-abc:notes/draft.md']);
75
+ expect(transferToScope).not.toHaveBeenCalled();
76
+ const err = pushed.find((e) => e.kind === 'status' && e.level === 'error');
77
+ expect(err).toBeDefined();
78
+ });
79
+ it('-R flag recurses over all docs matching src prefix', async () => {
80
+ const transferToScope = vi.fn(async () => { });
81
+ const allDocs = [
82
+ { shardId: 'notes', path: 'ideas/a.md', size: 1, lastModified: 0 },
83
+ { shardId: 'notes', path: 'ideas/b.md', size: 1, lastModified: 0 },
84
+ { shardId: 'notes', path: 'other.md', size: 1, lastModified: 0 },
85
+ ];
86
+ const docs = makeDocs({
87
+ transferToScope,
88
+ listDocuments: vi.fn(async () => allDocs),
89
+ });
90
+ const sh3 = makeSh3(projectScope);
91
+ const { ctx } = makeCtx(docs, sh3);
92
+ await xferVerb.run(ctx, ['-R', '@project-proj-abc:notes/ideas', '@me:notes/ideas']);
93
+ // Only the two docs under ideas/ should be transferred
94
+ expect(transferToScope).toHaveBeenCalledTimes(2);
95
+ });
96
+ });
@@ -5,6 +5,7 @@ import type { TreeRootRef } from '../layout/types';
5
5
  import type { DispatchToTerminalResult } from '../shell-shard/dispatch-to-terminal';
6
6
  import type { ActionDescriptor } from '../actions/types';
7
7
  import type { FieldsApi } from '../fields/types';
8
+ import type { BrowseCapability } from '../documents/browse';
8
9
  export interface Sh3Api {
9
10
  listApps(): Array<{
10
11
  id: string;
@@ -158,6 +159,21 @@ export interface Sh3Api {
158
159
  * Controllable-field surface — see fields/types.ts:FieldsApi for shape.
159
160
  */
160
161
  fields: FieldsApi;
162
+ /**
163
+ * Active scope identity. `id` is the current tenant (project or personal).
164
+ * `personalId` is always the user's base tenant regardless of active project.
165
+ * `isProject` is true when a project scope is currently active.
166
+ */
167
+ getActiveScope(): {
168
+ id: string;
169
+ isProject: boolean;
170
+ personalId: string;
171
+ };
172
+ /** List projects visible to the current user. */
173
+ listProjects(): Array<{
174
+ id: string;
175
+ name: string;
176
+ }>;
161
177
  }
162
178
  export type { DispatchToTerminalResult } from '../shell-shard/dispatch-to-terminal';
163
179
  export interface VerbContext {
@@ -166,6 +182,8 @@ export interface VerbContext {
166
182
  session: SessionClient;
167
183
  cwd: string;
168
184
  fs: TenantFsClient;
185
+ /** Document zone browse capability. Present when shell-shard has documents:browse permission. */
186
+ docs?: BrowseCapability;
169
187
  /** Invoke another registered verb programmatically (used by rich-entry clicks). */
170
188
  dispatch(line: string): Promise<void>;
171
189
  /**
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Auto-generated from package.json — do not edit manually. */
2
- export declare const VERSION = "0.20.1";
2
+ export declare const VERSION = "0.20.2";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Auto-generated from package.json — do not edit manually. */
2
- export const VERSION = '0.20.1';
2
+ export const VERSION = '0.20.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sh3-core",
3
- "version": "0.20.1",
3
+ "version": "0.20.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"