@cordfuse/crosstalk 7.0.0-alpha.16 → 7.0.0-alpha.18

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 (75) hide show
  1. package/GUIDE-CLI.md +322 -0
  2. package/GUIDE-PROMPTS.md +112 -0
  3. package/LICENSE +21 -0
  4. package/README.md +337 -62
  5. package/bin/crosstalk.js +88 -54
  6. package/commands/agent.js +69 -0
  7. package/commands/auth.js +273 -0
  8. package/commands/channel.js +54 -44
  9. package/commands/chat.js +107 -71
  10. package/commands/daemon.js +121 -0
  11. package/commands/logs.js +108 -19
  12. package/commands/message.js +125 -0
  13. package/commands/server.js +153 -0
  14. package/commands/settings.js +49 -0
  15. package/commands/token.js +136 -0
  16. package/commands/transport.js +272 -0
  17. package/commands/version.js +3 -3
  18. package/commands/workflow.js +234 -0
  19. package/deploy/crosstalk@.service +62 -0
  20. package/deploy/install.sh +82 -0
  21. package/lib/api-client.js +77 -22
  22. package/lib/credentials.js +207 -0
  23. package/lib/nativeServer.js +174 -0
  24. package/lib/resolve.js +95 -43
  25. package/package.json +27 -4
  26. package/src/activation.ts +104 -0
  27. package/src/api.ts +1716 -0
  28. package/src/auth/enforce.ts +68 -0
  29. package/src/auth/handlers.ts +266 -0
  30. package/src/auth/middleware.ts +132 -0
  31. package/src/auth/setup.ts +263 -0
  32. package/src/auth/tokens.ts +285 -0
  33. package/src/auth/users.ts +267 -0
  34. package/src/channel.ts +202 -0
  35. package/src/dispatch.ts +492 -0
  36. package/src/dispatchers.ts +91 -0
  37. package/src/filenames.ts +28 -0
  38. package/src/frontmatter.ts +26 -0
  39. package/src/init.ts +116 -0
  40. package/src/invoke.ts +201 -0
  41. package/src/log-buffer.ts +67 -0
  42. package/src/models.ts +283 -0
  43. package/src/replies.ts +73 -0
  44. package/src/resolve.ts +100 -0
  45. package/src/run.ts +250 -0
  46. package/src/state.ts +190 -0
  47. package/src/status.ts +84 -0
  48. package/src/stop.ts +37 -0
  49. package/src/transport.ts +243 -0
  50. package/src/web/auth-pages.ts +160 -0
  51. package/src/web/channels.ts +395 -0
  52. package/src/web/chat-page.ts +636 -0
  53. package/src/web/chat-pty.ts +238 -0
  54. package/src/web/dashboard.ts +129 -0
  55. package/src/web/layout.ts +237 -0
  56. package/src/web/stubs.ts +510 -0
  57. package/src/web/workflows.ts +490 -0
  58. package/src/workflow.ts +470 -0
  59. package/template/CLAUDE.md +10 -0
  60. package/template/CROSSTALK-VERSION +1 -0
  61. package/template/CROSSTALK.md +258 -0
  62. package/template/PROTOCOL.md +66 -0
  63. package/template/README.md +64 -0
  64. package/template/auth/.gitkeep +0 -0
  65. package/template/auth/README.md +224 -0
  66. package/template/data/crosstalk.yaml +196 -0
  67. package/template/gitignore +4 -0
  68. package/commands/down.js +0 -40
  69. package/commands/init.js +0 -241
  70. package/commands/pull.js +0 -22
  71. package/commands/replies.js +0 -40
  72. package/commands/restart.js +0 -29
  73. package/commands/rm.js +0 -109
  74. package/commands/run.js +0 -115
  75. package/commands/up.js +0 -133
package/commands/run.js DELETED
@@ -1,115 +0,0 @@
1
- // crosstalk run — dispatch a primitive or workflow via POST /messages.
2
- //
3
- // Mirrors crosstalkd's run surface:
4
- // crosstalk run --type primitive --to <model>[@<machine>] [--as <persona>]
5
- // [--fanout <n>] [--channel <name|uuid>] [--from <name>]
6
- // [--new] <body|file|->
7
- // crosstalk run --type workflow [--channel <name|uuid>] [--from <name>]
8
- // [--new] <file|->
9
-
10
- import { readFileSync, existsSync, statSync } from 'fs';
11
- import { apiFor } from '../lib/api-client.js';
12
- import { reportAndExit } from '../lib/errors.js';
13
- import { flag, has, positionals } from '../lib/argv.js';
14
-
15
- const FLAGS_WITH_VALUE = new Set(['--type', '--to', '--as', '--fanout', '--channel', '--from', '--containername', '-c']);
16
-
17
- function usage(exit = 0) {
18
- const w = exit === 0 ? process.stdout : process.stderr;
19
- w.write(
20
- `Usage:
21
- crosstalk run --type primitive --to <model>[@<machine>] \\
22
- [--as <persona>] [--fanout <n>] \\
23
- [--channel <name|uuid>] [--from <name>] [--new] \\
24
- <body|file|->
25
-
26
- crosstalk run --type workflow [--channel <name|uuid>] \\
27
- [--from <name>] [--new] <file|->
28
- `,
29
- );
30
- process.exit(exit);
31
- }
32
-
33
- function readStdin() {
34
- try {
35
- return readFileSync(0, 'utf-8');
36
- } catch {
37
- return '';
38
- }
39
- }
40
-
41
- function resolveBody(arg) {
42
- if (arg == null) return null;
43
- if (arg === '-') return readStdin();
44
- if (existsSync(arg)) {
45
- try {
46
- if (statSync(arg).isFile()) return readFileSync(arg, 'utf-8');
47
- } catch { /* fall through to inline */ }
48
- }
49
- return arg;
50
- }
51
-
52
- export async function run(argv) {
53
- if (has(argv, '--help') || has(argv, '-h')) usage(0);
54
-
55
- const api = apiFor(argv);
56
- const type = flag(argv, '--type');
57
- if (type !== 'primitive' && type !== 'workflow') usage(1);
58
-
59
- // Body is the last positional. positionals() skips flag values so the
60
- // body resolves regardless of flag order — `--containername a8 hello`
61
- // and `hello --containername a8` both work.
62
- const pos = positionals(argv, [...FLAGS_WITH_VALUE]);
63
- const bodyArg = pos[pos.length - 1];
64
-
65
- const body = resolveBody(bodyArg);
66
- if (body == null || body.length === 0) {
67
- process.stderr.write('crosstalk run: missing body (file path, inline string, or `-` for stdin)\n');
68
- return 1;
69
- }
70
-
71
- const channel = flag(argv, '--channel');
72
- const from = flag(argv, '--from') ?? process.env.USER ?? 'operator';
73
-
74
- let payload;
75
- if (type === 'primitive') {
76
- const to = flag(argv, '--to');
77
- if (!to) {
78
- process.stderr.write('crosstalk run --type primitive: --to <model> is required\n');
79
- return 1;
80
- }
81
- const fanoutRaw = flag(argv, '--fanout');
82
- const fanout = fanoutRaw ? Math.max(1, parseInt(fanoutRaw, 10)) : 1;
83
- payload = {
84
- type: 'primitive',
85
- to,
86
- as: flag(argv, '--as'),
87
- channel,
88
- from,
89
- fanout,
90
- body,
91
- };
92
- } else {
93
- payload = {
94
- type: 'workflow',
95
- channel,
96
- from,
97
- body,
98
- };
99
- }
100
-
101
- let resp;
102
- try {
103
- resp = await api.post('/messages', payload);
104
- } catch (err) {
105
- reportAndExit(err, 'crosstalk run');
106
- }
107
-
108
- if (resp.type === 'primitive') {
109
- for (const p of resp.relPaths) process.stdout.write(`Sent: ${p}\n`);
110
- } else {
111
- process.stdout.write(`Workflow dispatched: ${resp.relPath}\n`);
112
- process.stdout.write(`Child channel: ${resp.childChannel} (parent: ${resp.channel.slice(0, 8)})\n`);
113
- }
114
- return 0;
115
- }
package/commands/up.js DELETED
@@ -1,133 +0,0 @@
1
- // crosstalk up — bring up the engine container for a transport.
2
- //
3
- // alpha.6: no cwd magic. Resolves container by --containername flag
4
- // (default 'crosstalk') and operates against <base>/<name>/.
5
- //
6
- // Three lifecycle cases:
7
- // 1. Container already running → error (use chat/restart instead).
8
- // 2. Storage exists, no container → resume; print one-line notice.
9
- // 3. Storage doesn't exist → error pointing to `crosstalk init`.
10
- //
11
- // First-time up generates <base>/<name>/docker-compose.yml from a template.
12
- // Subsequent ups respect operator edits — only regenerate if missing.
13
-
14
- import { writeFileSync, existsSync, readFileSync } from 'fs';
15
- import { spawnSync } from 'child_process';
16
- import { has } from '../lib/argv.js';
17
- import {
18
- requireInitialized,
19
- isRunning,
20
- containerExists,
21
- apiPortFor,
22
- DEFAULT_CONTAINER_NAME,
23
- DEFAULT_IMAGE,
24
- CROSSTALK_LABEL,
25
- } from '../lib/resolve.js';
26
-
27
- function usage(exit = 0) {
28
- const w = exit === 0 ? process.stdout : process.stderr;
29
- w.write(
30
- `Usage: crosstalk up [--containername <name>]
31
-
32
- Starts the engine container for a transport that has already been
33
- 'crosstalk init'd. Default container is 'crosstalk'; pass --containername
34
- to address a named one.
35
-
36
- If the storage at <base>/<name>/ already exists (operator previously
37
- brought it up then 'crosstalk down'd it), the container resumes against
38
- that state — installed agent CLIs, OAuth tokens, dispatcher cursor all
39
- carry over.
40
-
41
- Environment:
42
- CROSSTALK_IMAGE Override the engine image
43
- CROSSTALK_ALIAS Override the engine's machine identity
44
- (defaults to the container name)
45
- `,
46
- );
47
- process.exit(exit);
48
- }
49
-
50
- function renderCompose({ name, image, apiPort, alias, uid, gid, paths }) {
51
- return `# Generated by 'crosstalk up'. Machine-local — runtime-owned.
52
- # Storage mode: ${paths.mode}
53
- # transport (container /var/lib/crosstalk-transport) → ${paths.transportDir}
54
- # crosstalk-root (container /crosstalk-root) → ${paths.crosstalkRoot}
55
- # crosstalk-state (container /var/lib/crosstalk-state) → ${paths.crosstalkState}
56
-
57
- services:
58
- crosstalkd:
59
- image: ${image}
60
- container_name: ${name}
61
- restart: unless-stopped
62
- labels:
63
- ${CROSSTALK_LABEL.replace('=', ': "')}"
64
- ports:
65
- - "127.0.0.1:${apiPort}:7000"
66
- volumes:
67
- - ${paths.transportDir}:/var/lib/crosstalk-transport
68
- - ${paths.crosstalkRoot}:/crosstalk-root
69
- - ${paths.crosstalkState}:/var/lib/crosstalk-state
70
- environment:
71
- CROSSTALK_ALIAS: ${alias}
72
- CROSSTALK_UID: "${uid}"
73
- CROSSTALK_GID: "${gid}"
74
- CROSSTALKD_API_PORT: "7000"
75
- DISPATCH_JSON: "true"
76
- DISPATCH_POLL_SECONDS: "30"
77
- `;
78
- }
79
-
80
- export async function run(argv) {
81
- if (has(argv, '--help') || has(argv, '-h')) usage(0);
82
-
83
- const { name, paths } = requireInitialized(argv);
84
-
85
- // Case 1: already running → error, don't surprise the operator with
86
- // a silent no-op or implicit restart.
87
- if (isRunning(name)) {
88
- process.stderr.write(
89
- `crosstalk up: '${name}' is already running.\n` +
90
- ` Use 'crosstalk chat${name === DEFAULT_CONTAINER_NAME ? '' : ` --containername ${name}`}' to attach,\n` +
91
- ` 'crosstalk restart${name === DEFAULT_CONTAINER_NAME ? '' : ` --containername ${name}`}' to recreate,\n` +
92
- ` or 'crosstalk down${name === DEFAULT_CONTAINER_NAME ? '' : ` --containername ${name}`}' first.\n`,
93
- );
94
- return 1;
95
- }
96
-
97
- // Case "stopped but not removed" — `docker stop` without compose down.
98
- // Silently remove the dead container so the recreate works.
99
- if (containerExists(name)) {
100
- spawnSync('docker', ['rm', '-f', name], { stdio: 'ignore' });
101
- }
102
-
103
- // Compose file generation. If operator edited theirs, respect it.
104
- const generated = !existsSync(paths.composeFile);
105
- if (generated) {
106
- const alias = process.env.CROSSTALK_ALIAS ?? name;
107
- const uid = typeof process.getuid === 'function' ? process.getuid() : 1000;
108
- const gid = typeof process.getgid === 'function' ? process.getgid() : 1000;
109
- const apiPort = apiPortFor(name);
110
- const image = DEFAULT_IMAGE;
111
- const content = renderCompose({ name, image, apiPort, alias, uid, gid, paths });
112
- writeFileSync(paths.composeFile, content);
113
- }
114
-
115
- // Resume notice when storage is non-fresh (operator brought it up
116
- // before, has installed CLIs / auth state in crosstalk-root/). Heuristic:
117
- // crosstalk-root has more than just a .gitkeep / nothing.
118
- if (!generated) {
119
- process.stdout.write(`Resuming '${name}' (existing state at ${paths.storageRoot})\n`);
120
- }
121
-
122
- const r = spawnSync('docker', ['compose', '-f', paths.composeFile, 'up', '-d'], {
123
- stdio: 'inherit',
124
- });
125
- if (r.status !== 0) {
126
- process.stderr.write(`crosstalk up: docker compose exited ${r.status}\n`);
127
- return r.status ?? 1;
128
- }
129
- process.stdout.write(
130
- `\n'${name}' starting. Check with 'crosstalk status${name === DEFAULT_CONTAINER_NAME ? '' : ` --containername ${name}`}' (give it ~5s).\n`,
131
- );
132
- return 0;
133
- }