kubun 0.9.0 → 0.11.0

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 (47) hide show
  1. package/README.md +22 -234
  2. package/bin/dev.js +12 -4
  3. package/bin/run.js +11 -2
  4. package/lib/account.d.ts +2 -0
  5. package/lib/account.js +5 -0
  6. package/lib/client.d.ts +2 -0
  7. package/{dist → lib}/client.js +4 -1
  8. package/lib/commands/account.d.ts +2 -0
  9. package/lib/commands/account.js +24 -0
  10. package/lib/commands/graph.d.ts +2 -0
  11. package/lib/commands/graph.js +74 -0
  12. package/lib/commands/graphql.d.ts +2 -0
  13. package/lib/commands/graphql.js +33 -0
  14. package/lib/commands/mcp.d.ts +2 -0
  15. package/lib/commands/mcp.js +21 -0
  16. package/lib/commands/model.d.ts +2 -0
  17. package/lib/commands/model.js +69 -0
  18. package/lib/commands/serve.d.ts +2 -0
  19. package/lib/commands/serve.js +116 -0
  20. package/lib/fs.d.ts +4 -0
  21. package/{dist → lib}/fs.js +6 -2
  22. package/lib/identity.d.ts +19 -0
  23. package/lib/identity.js +31 -0
  24. package/lib/index.d.ts +3 -0
  25. package/lib/index.js +19 -0
  26. package/lib/options.d.ts +19 -0
  27. package/lib/options.js +47 -0
  28. package/lib/program.d.ts +2 -0
  29. package/lib/program.js +28 -0
  30. package/lib/ui.d.ts +5 -0
  31. package/lib/ui.js +23 -0
  32. package/package.json +36 -45
  33. package/bin/dev.cmd +0 -3
  34. package/bin/run.cmd +0 -3
  35. package/dist/account.js +0 -5
  36. package/dist/commands/account/generate.js +0 -10
  37. package/dist/commands/account/id.js +0 -18
  38. package/dist/commands/graph/deploy.js +0 -32
  39. package/dist/commands/graph/mutate.js +0 -32
  40. package/dist/commands/graph/query.js +0 -32
  41. package/dist/commands/graphql/schema.js +0 -41
  42. package/dist/commands/mcp.js +0 -33
  43. package/dist/commands/model/cluster.js +0 -35
  44. package/dist/commands/model/create.js +0 -69
  45. package/dist/commands/serve.js +0 -126
  46. package/dist/index.js +0 -1
  47. package/oclif.manifest.json +0 -533
@@ -1,33 +0,0 @@
1
- import { createConfig } from '@kubun/mcp';
2
- import { serveProcess } from '@mokei/context-server';
3
- import { Command, Flags } from '@oclif/core';
4
- import { getSigner } from '../account.js';
5
- export default class MCP extends Command {
6
- static description = 'Start an MCP server for Kubun';
7
- static flags = {
8
- connect: Flags.string({
9
- char: 'c',
10
- description: 'URL of an existing Kubun HTTP server to connect to',
11
- exclusive: ['db'],
12
- }),
13
- db: Flags.string({
14
- char: 'd',
15
- description: 'SQLite database path or PostgreSQL URL',
16
- exclusive: ['connect'],
17
- }),
18
- privateKey: Flags.string({
19
- char: 'k',
20
- description: 'base64-encoded private key',
21
- env: 'KUBUN_PRIVATE_KEY',
22
- }),
23
- };
24
- async run() {
25
- const { flags } = await this.parse(MCP);
26
- const config = await createConfig({
27
- connect: flags.connect,
28
- database: flags.db,
29
- identity: flags.privateKey ? getSigner(flags.privateKey) : undefined,
30
- });
31
- serveProcess(config);
32
- }
33
- }
@@ -1,35 +0,0 @@
1
- import { ClusterBuilder } from '@kubun/protocol';
2
- import { Command, Flags } from '@oclif/core';
3
- import ora from 'ora';
4
- import { writeJSON } from '../../fs.js';
5
- export default class CreateClusterModel extends Command {
6
- static description = 'Create a documents cluster model';
7
- static flags = {
8
- model: Flags.string({
9
- description: 'document model as JSON string',
10
- char: 'm',
11
- multiple: true,
12
- required: true,
13
- }),
14
- output: Flags.file({
15
- description: 'output file for the cluster',
16
- char: 'o',
17
- }),
18
- };
19
- async run() {
20
- const spinner = ora('Creating cluster model...').start();
21
- const { flags } = await this.parse(CreateClusterModel);
22
- const builder = new ClusterBuilder();
23
- builder.addAll(flags.model.map((model) => JSON.parse(model)));
24
- const cluster = builder.build();
25
- if (flags.output == null) {
26
- spinner.succeed('Cluster model created');
27
- this.log(JSON.stringify(cluster));
28
- }
29
- else {
30
- await writeJSON(flags.output, cluster);
31
- spinner.succeed(`Cluster model written to ${flags.output}`);
32
- }
33
- return cluster;
34
- }
35
- }
@@ -1,69 +0,0 @@
1
- import { ClusterBuilder, } from '@kubun/protocol';
2
- import { Args, Command, Flags } from '@oclif/core';
3
- import ora from 'ora';
4
- import { writeJSON } from '../../fs.js';
5
- export default class CreateDocumentModel extends Command {
6
- static description = 'Create a document model';
7
- static args = {
8
- name: Args.string({ description: 'document model name', required: true }),
9
- schema: Args.string({ description: 'document schema as JSON string', required: true }),
10
- };
11
- static flags = {
12
- behavior: Flags.string({
13
- description: 'behavior of the document',
14
- char: 'b',
15
- options: ['default', 'interface', 'unique'],
16
- default: 'default',
17
- }),
18
- cluster: Flags.boolean({
19
- description: 'create a cluster model instead of a document model',
20
- char: 'c',
21
- }),
22
- output: Flags.file({
23
- description: 'output file',
24
- char: 'o',
25
- }),
26
- uniqueField: Flags.string({
27
- description: 'unique field of the document when behavior is set to "unique"',
28
- char: 'u',
29
- multiple: true,
30
- }),
31
- };
32
- async run() {
33
- const spinner = ora('Creating document model...').start();
34
- const { args, flags } = await this.parse(CreateDocumentModel);
35
- const behavior = flags.behavior;
36
- const model = {
37
- name: args.name,
38
- behavior,
39
- schema: JSON.parse(args.schema),
40
- };
41
- if (behavior === 'unique') {
42
- model.uniqueFields = flags.uniqueField;
43
- }
44
- const builder = new ClusterBuilder();
45
- builder.add(model);
46
- if (flags.cluster) {
47
- const cluster = builder.build();
48
- if (flags.output == null) {
49
- spinner.succeed('Cluster model created');
50
- this.log(JSON.stringify(cluster));
51
- }
52
- else {
53
- await writeJSON(flags.output, cluster);
54
- spinner.succeed(`Cluster model written to ${flags.output}`);
55
- }
56
- return cluster;
57
- }
58
- const document = builder.cluster[0];
59
- if (flags.output == null) {
60
- spinner.succeed('Document model created');
61
- this.log(JSON.stringify(document));
62
- }
63
- else {
64
- await writeJSON(flags.output, document);
65
- spinner.succeed(`Document model written to ${flags.output}`);
66
- }
67
- return document;
68
- }
69
- }
@@ -1,126 +0,0 @@
1
- import { fromB64, toB64 } from '@enkaku/codec';
2
- import { createFullIdentity, randomIdentity } from '@enkaku/token';
3
- import { NodeSQLiteAdapter } from '@kubun/db-node-sqlite';
4
- import { PostgresAdapter } from '@kubun/db-postgres';
5
- import { KubunEngine } from '@kubun/engine';
6
- import { getKubunLogger } from '@kubun/logger';
7
- import { createHTTPPlugin } from '@kubun/plugin-http';
8
- import { createP2PPlugin } from '@kubun/plugin-p2p';
9
- import { createRPCPlugin } from '@kubun/plugin-rpc';
10
- import { configureSync, getConsoleSink, getLogLevels } from '@logtape/logtape';
11
- import { Command, Flags } from '@oclif/core';
12
- import ora from 'ora';
13
- import { resolvePath } from '../fs.js';
14
- export default class Serve extends Command {
15
- static description = 'Start a local Kubun server';
16
- static flags = {
17
- allowedOrigin: Flags.string({
18
- char: 'a',
19
- description: 'allowed HTTP origin',
20
- env: 'KUBUN_ALLOWED_ORIGIN',
21
- default: '*',
22
- }),
23
- autoAcceptPeers: Flags.string({
24
- description: 'comma-separated DIDs to auto-accept for peer join flows',
25
- dependsOn: ['p2p'],
26
- }),
27
- db: Flags.file({ description: 'path to the local SQLite database' }),
28
- id: Flags.string({ description: 'server ID' }),
29
- logLevel: Flags.string({
30
- char: 'l',
31
- description: 'log level',
32
- options: getLogLevels(),
33
- default: 'warning',
34
- }),
35
- p2p: Flags.boolean({ description: 'enable P2P mode with sync and graph protocols over HTTP' }),
36
- port: Flags.integer({ char: 'p', description: 'port to listen on' }),
37
- privateKey: Flags.string({
38
- char: 'k',
39
- description: 'base64-encoded private key',
40
- env: 'KUBUN_PRIVATE_KEY',
41
- exclusive: ['id'],
42
- }),
43
- };
44
- async run() {
45
- const spinner = ora();
46
- const { flags } = await this.parse(Serve);
47
- spinner.start('Starting the server...');
48
- // Configure logging
49
- configureSync({
50
- reset: true,
51
- sinks: { console: getConsoleSink() },
52
- loggers: [
53
- { category: ['logtape', 'meta'], lowestLevel: 'error', sinks: ['console'] },
54
- {
55
- category: ['kubun'],
56
- lowestLevel: (flags.logLevel ?? 'warning'),
57
- sinks: ['console'],
58
- },
59
- ],
60
- });
61
- // Resolve identity
62
- const logger = getKubunLogger('cli');
63
- let identity;
64
- if (flags.privateKey != null) {
65
- const privateKey = fromB64(flags.privateKey);
66
- identity = { ...createFullIdentity(privateKey), privateKey };
67
- }
68
- else if (flags.id != null) {
69
- if (flags.p2p) {
70
- this.error('P2P mode requires a signing identity. Use --private-key instead of --id.');
71
- }
72
- identity = { id: flags.id };
73
- }
74
- else {
75
- const generated = randomIdentity();
76
- logger.warn('Generated random identity for server: {privateKey}, DID: {id}', {
77
- id: generated.id,
78
- privateKey: toB64(generated.privateKey),
79
- });
80
- identity = generated;
81
- }
82
- // Create DB adapter
83
- const adapter = flags.db == null || flags.db === ':memory:'
84
- ? new NodeSQLiteAdapter({ database: ':memory:' })
85
- : flags.db.startsWith('postgres://') || flags.db.startsWith('postgresql://')
86
- ? new PostgresAdapter({ url: flags.db })
87
- : new NodeSQLiteAdapter({ database: resolvePath(flags.db) });
88
- // Build plugin list
89
- const autoAcceptPeers = flags.autoAcceptPeers
90
- ? flags.autoAcceptPeers.split(',').map((s) => s.trim())
91
- : undefined;
92
- const rpcAccessRules = autoAcceptPeers != null ? { '*': { allow: [identity.id, ...autoAcceptPeers] } } : undefined;
93
- const plugins = [
94
- createRPCPlugin({
95
- ...(rpcAccessRules != null ? { accessRules: rpcAccessRules } : undefined),
96
- allowDelegatedMutations: flags.p2p,
97
- }),
98
- createHTTPPlugin({ port: flags.port, allowedOrigin: flags.allowedOrigin }),
99
- ];
100
- if (flags.p2p) {
101
- plugins.push(createP2PPlugin({ http: true, autoAcceptPeers }));
102
- }
103
- // Create engine with plugins
104
- const engine = new KubunEngine({
105
- db: adapter,
106
- identity,
107
- plugins,
108
- });
109
- const http = await engine.getAPI('http');
110
- await http.listening;
111
- if (flags.p2p) {
112
- const p2p = await engine.getAPI('p2p');
113
- await p2p.syncReady;
114
- }
115
- spinner.succeed(`HTTP server listening at ${http.getURL()}\n DID: ${identity.id}\n`);
116
- if (flags.p2p && autoAcceptPeers) {
117
- this.log(` Auto-accept peers: ${autoAcceptPeers.length} DID(s)`);
118
- }
119
- // Keep process alive until SIGINT/SIGTERM
120
- await new Promise((resolve) => {
121
- process.once('SIGINT', resolve);
122
- process.once('SIGTERM', resolve);
123
- });
124
- await engine.dispose();
125
- }
126
- }
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- export { run } from '@oclif/core';