@ezlkg/shn 1.0.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 (51) hide show
  1. package/dist/commands/logs.d.ts +5 -0
  2. package/dist/commands/logs.d.ts.map +1 -0
  3. package/dist/commands/logs.js +53 -0
  4. package/dist/commands/logs.js.map +1 -0
  5. package/dist/commands/start.d.ts +14 -0
  6. package/dist/commands/start.d.ts.map +1 -0
  7. package/dist/commands/start.js +146 -0
  8. package/dist/commands/start.js.map +1 -0
  9. package/dist/commands/status.d.ts +5 -0
  10. package/dist/commands/status.d.ts.map +1 -0
  11. package/dist/commands/status.js +23 -0
  12. package/dist/commands/status.js.map +1 -0
  13. package/dist/commands/stop.d.ts +5 -0
  14. package/dist/commands/stop.d.ts.map +1 -0
  15. package/dist/commands/stop.js +9 -0
  16. package/dist/commands/stop.js.map +1 -0
  17. package/dist/commands/update.d.ts +5 -0
  18. package/dist/commands/update.d.ts.map +1 -0
  19. package/dist/commands/update.js +9 -0
  20. package/dist/commands/update.js.map +1 -0
  21. package/dist/commands/workspaces.d.ts +5 -0
  22. package/dist/commands/workspaces.d.ts.map +1 -0
  23. package/dist/commands/workspaces.js +19 -0
  24. package/dist/commands/workspaces.js.map +1 -0
  25. package/dist/docker.d.ts +58 -0
  26. package/dist/docker.d.ts.map +1 -0
  27. package/dist/docker.js +159 -0
  28. package/dist/docker.js.map +1 -0
  29. package/dist/env.d.ts +26 -0
  30. package/dist/env.d.ts.map +1 -0
  31. package/dist/env.js +119 -0
  32. package/dist/env.js.map +1 -0
  33. package/dist/home.d.ts +16 -0
  34. package/dist/home.d.ts.map +1 -0
  35. package/dist/home.js +52 -0
  36. package/dist/home.js.map +1 -0
  37. package/dist/index.d.ts +17 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +167 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/paths.d.ts +25 -0
  42. package/dist/paths.d.ts.map +1 -0
  43. package/dist/paths.js +57 -0
  44. package/dist/paths.js.map +1 -0
  45. package/dist/splash.d.ts +5 -0
  46. package/dist/splash.d.ts.map +1 -0
  47. package/dist/splash.js +38 -0
  48. package/dist/splash.js.map +1 -0
  49. package/infra/compose.yml +50 -0
  50. package/infra/router-config.json +33 -0
  51. package/package.json +42 -0
@@ -0,0 +1,5 @@
1
+ /**
2
+ * `shannon logs` command — tail a workspace's workflow log.
3
+ */
4
+ export declare function logs(workspaceId: string): void;
5
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,wBAAgB,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAkD9C"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * `shannon logs` command — tail a workspace's workflow log.
3
+ */
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { spawn } from 'node:child_process';
7
+ import { getWorkspacesDir } from '../home.js';
8
+ export function logs(workspaceId) {
9
+ const workspacesDir = getWorkspacesDir();
10
+ let logFile = '';
11
+ // 1. Direct match
12
+ const directPath = path.join(workspacesDir, workspaceId, 'workflow.log');
13
+ if (fs.existsSync(directPath)) {
14
+ logFile = directPath;
15
+ }
16
+ // 2. Resume workflow ID (e.g. workspace_resume_123)
17
+ if (!logFile) {
18
+ const base = workspaceId.replace(/_resume_\d+$/, '');
19
+ if (base !== workspaceId) {
20
+ const resumePath = path.join(workspacesDir, base, 'workflow.log');
21
+ if (fs.existsSync(resumePath)) {
22
+ logFile = resumePath;
23
+ }
24
+ }
25
+ }
26
+ // 3. Named workspace ID (e.g. workspace_shannon-123)
27
+ if (!logFile) {
28
+ const base = workspaceId.replace(/_shannon-\d+$/, '');
29
+ if (base !== workspaceId) {
30
+ const namedPath = path.join(workspacesDir, base, 'workflow.log');
31
+ if (fs.existsSync(namedPath)) {
32
+ logFile = namedPath;
33
+ }
34
+ }
35
+ }
36
+ if (!logFile) {
37
+ console.error(`ERROR: Workflow log not found for: ${workspaceId}`);
38
+ console.error('');
39
+ console.error('Possible causes:');
40
+ console.error(' - Workflow hasn\'t started yet');
41
+ console.error(' - Workspace ID is incorrect');
42
+ console.error('');
43
+ console.error('Check the Temporal Web UI at http://localhost:8233 for workflow details');
44
+ process.exit(1);
45
+ }
46
+ console.log(`Tailing workflow log: ${logFile}`);
47
+ const tail = spawn('tail', ['-f', logFile], { stdio: 'inherit' });
48
+ process.on('SIGINT', () => {
49
+ tail.kill();
50
+ process.exit(0);
51
+ });
52
+ }
53
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,UAAU,IAAI,CAAC,WAAmB;IACtC,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,kBAAkB;IAClB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;IACzE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO,GAAG,UAAU,CAAC;IACvB,CAAC;IAED,oDAAoD;IACpD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACrD,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YACzB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;YAClE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9B,OAAO,GAAG,UAAU,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACtD,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;YACjE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC7B,OAAO,GAAG,SAAS,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,sCAAsC,WAAW,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;QACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,yBAAyB,OAAO,EAAE,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAElE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `shannon start` command — launch a pentest scan.
3
+ */
4
+ export interface StartArgs {
5
+ url: string;
6
+ repo: string;
7
+ config?: string;
8
+ workspace?: string;
9
+ pipelineTesting: boolean;
10
+ router: boolean;
11
+ version: string;
12
+ }
13
+ export declare function start(args: StartArgs): void;
14
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAyH3C"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * `shannon start` command — launch a pentest scan.
3
+ */
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { execSync } from 'node:child_process';
7
+ import { initHome, getWorkspacesDir, getCredentialsPath } from '../home.js';
8
+ import { loadEnv, buildEnvFlags, validateCredentials } from '../env.js';
9
+ import { resolveRepo, resolveConfig, ensureDeliverables } from '../paths.js';
10
+ import { ensureInfra, pullImage, spawnWorker, randomSuffix } from '../docker.js';
11
+ import { displaySplash } from '../splash.js';
12
+ export function start(args) {
13
+ // 1. Initialize ~/.shannon and load env
14
+ initHome();
15
+ loadEnv();
16
+ // 2. Validate credentials
17
+ const creds = validateCredentials(args.router);
18
+ if (!creds.valid) {
19
+ console.error(`ERROR: ${creds.error}`);
20
+ process.exit(1);
21
+ }
22
+ // 3. Resolve paths
23
+ const repo = resolveRepo(args.repo);
24
+ const config = args.config ? resolveConfig(args.config) : undefined;
25
+ ensureDeliverables(repo.hostPath);
26
+ // 4. Ensure workspaces dir is writable by container user (UID 1001)
27
+ const workspacesDir = getWorkspacesDir();
28
+ fs.mkdirSync(workspacesDir, { recursive: true });
29
+ fs.chmodSync(workspacesDir, 0o777);
30
+ // 5. Handle router env
31
+ if (args.router) {
32
+ process.env.ANTHROPIC_BASE_URL = 'http://shannon-router:3456';
33
+ process.env.ANTHROPIC_AUTH_TOKEN = 'shannon-router-key';
34
+ }
35
+ // 6. Pull image and start infra
36
+ pullImage();
37
+ ensureInfra(args.router);
38
+ // 7. Generate unique task queue and container name
39
+ const suffix = randomSuffix();
40
+ const taskQueue = `shannon-${suffix}`;
41
+ const containerName = `shannon-worker-${suffix}`;
42
+ // 8. Generate workspace name if not provided
43
+ let workspace = args.workspace;
44
+ if (!workspace) {
45
+ const hostname = new URL(args.url).hostname.replace(/[^a-zA-Z0-9-]/g, '-');
46
+ workspace = `${hostname}_shannon-${Date.now()}`;
47
+ }
48
+ // 9. Check for GCP credentials
49
+ const credentialsPath = getCredentialsPath();
50
+ const hasCredentials = fs.existsSync(credentialsPath);
51
+ // 10. Display splash screen
52
+ displaySplash(args.version);
53
+ // 11. Spawn worker container
54
+ const proc = spawnWorker({
55
+ url: args.url,
56
+ repo,
57
+ workspacesDir,
58
+ taskQueue,
59
+ containerName,
60
+ envFlags: buildEnvFlags(),
61
+ ...(config && { config }),
62
+ ...(hasCredentials && { credentials: credentialsPath }),
63
+ ...(workspace && { workspace }),
64
+ ...(args.pipelineTesting && { pipelineTesting: true }),
65
+ });
66
+ // 12. Wait for workflow.log to appear, then display info
67
+ const workflowLog = path.join(workspacesDir, workspace, 'workflow.log');
68
+ proc.on('error', (err) => {
69
+ console.error(`Failed to start worker: ${err.message}`);
70
+ process.exit(1);
71
+ });
72
+ // Poll for workflow.log header
73
+ process.stdout.write('Waiting for workflow to start...');
74
+ let workflowId = '';
75
+ let attempts = 0;
76
+ const pollInterval = setInterval(() => {
77
+ attempts++;
78
+ if (attempts > 60) {
79
+ clearInterval(pollInterval);
80
+ process.stdout.write('\n');
81
+ console.error('Timeout waiting for workflow to start');
82
+ process.exit(1);
83
+ }
84
+ try {
85
+ const content = fs.readFileSync(workflowLog, 'utf-8');
86
+ if (content.includes('====')) {
87
+ clearInterval(pollInterval);
88
+ // Extract workflow ID
89
+ const match = /^Workflow ID: (.+)$/m.exec(content);
90
+ if (match?.[1]) {
91
+ workflowId = match[1];
92
+ }
93
+ // Clear waiting line and show info
94
+ process.stdout.write('\r\x1b[K');
95
+ printInfo(args, workspace, workflowId, repo.hostPath);
96
+ return;
97
+ }
98
+ }
99
+ catch {
100
+ // File doesn't exist yet
101
+ }
102
+ process.stdout.write('.');
103
+ }, 2000);
104
+ // Handle SIGINT — stop the worker container
105
+ const cleanup = () => {
106
+ clearInterval(pollInterval);
107
+ console.log(`\nStopping worker ${containerName}...`);
108
+ try {
109
+ execSync(`docker stop ${containerName}`, { stdio: 'pipe' });
110
+ }
111
+ catch {
112
+ // Container may have already exited
113
+ }
114
+ process.exit(0);
115
+ };
116
+ process.on('SIGINT', cleanup);
117
+ process.on('SIGTERM', cleanup);
118
+ }
119
+ function printInfo(args, workspace, workflowId, repoPath) {
120
+ console.log(` Target: ${args.url}`);
121
+ console.log(` Repository: ${repoPath}`);
122
+ console.log(` Workspace: ${workspace}`);
123
+ if (args.config) {
124
+ console.log(` Config: ${path.resolve(args.config)}`);
125
+ }
126
+ if (args.pipelineTesting) {
127
+ console.log(' Mode: Pipeline Testing');
128
+ }
129
+ if (args.router) {
130
+ console.log(' Router: Enabled');
131
+ }
132
+ console.log('');
133
+ console.log(' Monitor:');
134
+ if (workflowId) {
135
+ console.log(` Web UI: http://localhost:8233/namespaces/default/workflows/${workflowId}`);
136
+ }
137
+ else {
138
+ console.log(' Web UI: http://localhost:8233');
139
+ }
140
+ console.log(` Logs: npx @ezlkg/shn logs ${workspace}`);
141
+ console.log('');
142
+ console.log(' Output:');
143
+ console.log(` Reports: ~/.shannon/workspaces/${workspace}/`);
144
+ console.log('');
145
+ }
146
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * `shannon status` command — show running workers and Temporal health.
3
+ */
4
+ export declare function status(): void;
5
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,MAAM,IAAI,IAAI,CAiB7B"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `shannon status` command — show running workers and Temporal health.
3
+ */
4
+ import { isTemporalReady, listRunningWorkers } from '../docker.js';
5
+ export function status() {
6
+ // 1. Temporal health
7
+ const temporalUp = isTemporalReady();
8
+ console.log(`Temporal: ${temporalUp ? 'running' : 'not running'}`);
9
+ if (temporalUp) {
10
+ console.log(' Web UI: http://localhost:8233');
11
+ }
12
+ console.log('');
13
+ // 2. Running workers
14
+ const workers = listRunningWorkers();
15
+ if (workers) {
16
+ console.log('Workers:');
17
+ console.log(workers);
18
+ }
19
+ else {
20
+ console.log('Workers: none running');
21
+ }
22
+ }
23
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEnE,MAAM,UAAU,MAAM;IACpB,qBAAqB;IACrB,MAAM,UAAU,GAAG,eAAe,EAAE,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,aAAa,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;IACnE,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,qBAAqB;IACrB,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACvC,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * `shannon stop` command — stop workers and infrastructure.
3
+ */
4
+ export declare function stop(clean: boolean): void;
5
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAGzC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * `shannon stop` command — stop workers and infrastructure.
3
+ */
4
+ import { stopWorkers, stopInfra } from '../docker.js';
5
+ export function stop(clean) {
6
+ stopWorkers();
7
+ stopInfra(clean);
8
+ }
9
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,UAAU,IAAI,CAAC,KAAc;IACjC,WAAW,EAAE,CAAC;IACd,SAAS,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * `shannon update` command — pull the latest worker image.
3
+ */
4
+ export declare function update(): void;
5
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,MAAM,IAAI,IAAI,CAG7B"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * `shannon update` command — pull the latest worker image.
3
+ */
4
+ import { pullLatest } from '../docker.js';
5
+ export function update() {
6
+ pullLatest();
7
+ console.log('Update complete.');
8
+ }
9
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,UAAU,MAAM;IACpB,UAAU,EAAE,CAAC;IACb,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * `shannon workspaces` command — list all workspaces.
3
+ */
4
+ export declare function workspaces(): void;
5
+ //# sourceMappingURL=workspaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/commands/workspaces.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,wBAAgB,UAAU,IAAI,IAAI,CAcjC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `shannon workspaces` command — list all workspaces.
3
+ */
4
+ import { execSync } from 'node:child_process';
5
+ import { getWorkspacesDir } from '../home.js';
6
+ import { getWorkerImage } from '../docker.js';
7
+ export function workspaces() {
8
+ const workspacesDir = getWorkspacesDir();
9
+ const image = getWorkerImage();
10
+ try {
11
+ execSync(`docker run --rm -v "${workspacesDir}:/app/workspaces" -e "WORKSPACES_DIR=/app/workspaces" "${image}" node dist/temporal/workspaces.js`, { stdio: 'inherit' });
12
+ }
13
+ catch {
14
+ console.error('ERROR: Failed to list workspaces. Is the Docker image available?');
15
+ console.error(` Run: docker pull ${image}`);
16
+ process.exit(1);
17
+ }
18
+ }
19
+ //# sourceMappingURL=workspaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../src/commands/workspaces.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,UAAU,UAAU;IACxB,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,QAAQ,CACN,uBAAuB,aAAa,0DAA0D,KAAK,oCAAoC,EACvI,EAAE,KAAK,EAAE,SAAS,EAAE,CACrB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAClF,OAAO,CAAC,KAAK,CAAC,sBAAsB,KAAK,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Docker orchestration — compose lifecycle, network, image pull, worker spawning.
3
+ */
4
+ import { type ChildProcess } from 'node:child_process';
5
+ export declare function getWorkerImage(): string;
6
+ /** Generate an 8-char random hex suffix for container/queue names. */
7
+ export declare function randomSuffix(): string;
8
+ /**
9
+ * Check if Temporal is running and healthy.
10
+ */
11
+ export declare function isTemporalReady(): boolean;
12
+ /**
13
+ * Ensure Temporal (and optionally router) are running via compose.
14
+ */
15
+ export declare function ensureInfra(useRouter: boolean): void;
16
+ /**
17
+ * Pull the worker image if not already present.
18
+ */
19
+ export declare function pullImage(): void;
20
+ export interface WorkerOptions {
21
+ url: string;
22
+ repo: {
23
+ hostPath: string;
24
+ containerPath: string;
25
+ };
26
+ workspacesDir: string;
27
+ taskQueue: string;
28
+ containerName: string;
29
+ envFlags: string[];
30
+ config?: {
31
+ hostPath: string;
32
+ containerPath: string;
33
+ };
34
+ credentials?: string;
35
+ workspace?: string;
36
+ pipelineTesting?: boolean;
37
+ }
38
+ /**
39
+ * Spawn the worker container in detached mode and return the process.
40
+ */
41
+ export declare function spawnWorker(opts: WorkerOptions): ChildProcess;
42
+ /**
43
+ * Stop all running shannon-worker-* containers.
44
+ */
45
+ export declare function stopWorkers(): void;
46
+ /**
47
+ * Tear down the compose stack.
48
+ */
49
+ export declare function stopInfra(clean: boolean): void;
50
+ /**
51
+ * Pull the latest worker image (for `update` command).
52
+ */
53
+ export declare function pullLatest(): void;
54
+ /**
55
+ * List running worker containers.
56
+ */
57
+ export declare function listRunningWorkers(): string;
58
+ //# sourceMappingURL=docker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../src/docker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAWxE,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,sEAAsE;AACtE,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAqBD;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAIzC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAqBpD;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAQhC;AAgBD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,YAAY,CAwC7D;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAMlC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAK9C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAGjC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
package/dist/docker.js ADDED
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Docker orchestration — compose lifecycle, network, image pull, worker spawning.
3
+ */
4
+ import { execSync, spawn } from 'node:child_process';
5
+ import path from 'node:path';
6
+ import os from 'node:os';
7
+ import crypto from 'node:crypto';
8
+ import { fileURLToPath } from 'node:url';
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ const WORKER_IMAGE = 'ezlkgp/shn:latest';
11
+ const COMPOSE_FILE = path.resolve(__dirname, '..', 'infra', 'compose.yml');
12
+ export function getWorkerImage() {
13
+ return WORKER_IMAGE;
14
+ }
15
+ /** Generate an 8-char random hex suffix for container/queue names. */
16
+ export function randomSuffix() {
17
+ return crypto.randomBytes(4).toString('hex');
18
+ }
19
+ /** Run a command silently, return true if it succeeds. */
20
+ function execQuiet(cmd) {
21
+ try {
22
+ execSync(cmd, { stdio: 'pipe' });
23
+ return true;
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ /** Run a command and return stdout, or empty string on failure. */
30
+ function execOutput(cmd) {
31
+ try {
32
+ return execSync(cmd, { stdio: 'pipe', encoding: 'utf-8' }).trim();
33
+ }
34
+ catch {
35
+ return '';
36
+ }
37
+ }
38
+ /**
39
+ * Check if Temporal is running and healthy.
40
+ */
41
+ export function isTemporalReady() {
42
+ return execQuiet('docker exec shannon-temporal temporal operator cluster health --address localhost:7233 2>/dev/null | grep -q SERVING');
43
+ }
44
+ /**
45
+ * Ensure Temporal (and optionally router) are running via compose.
46
+ */
47
+ export function ensureInfra(useRouter) {
48
+ if (isTemporalReady()) {
49
+ return;
50
+ }
51
+ console.log('Starting Shannon infrastructure...');
52
+ const profiles = useRouter ? '--profile router' : '';
53
+ execSync(`docker compose -f "${COMPOSE_FILE}" ${profiles} up -d`, {
54
+ stdio: 'inherit',
55
+ });
56
+ console.log('Waiting for Temporal to be ready...');
57
+ for (let i = 0; i < 30; i++) {
58
+ if (isTemporalReady()) {
59
+ console.log('Temporal is ready!');
60
+ return;
61
+ }
62
+ execSync('sleep 2');
63
+ }
64
+ console.error('Timeout waiting for Temporal');
65
+ process.exit(1);
66
+ }
67
+ /**
68
+ * Pull the worker image if not already present.
69
+ */
70
+ export function pullImage() {
71
+ const exists = execQuiet(`docker image inspect "${WORKER_IMAGE}" 2>/dev/null`);
72
+ if (exists) {
73
+ return;
74
+ }
75
+ console.log(`Pulling ${WORKER_IMAGE}...`);
76
+ execSync(`docker pull "${WORKER_IMAGE}"`, { stdio: 'inherit' });
77
+ }
78
+ /**
79
+ * Detect if --add-host is needed (Linux without Podman).
80
+ * macOS has host.docker.internal built in.
81
+ */
82
+ function addHostFlag() {
83
+ if (os.platform() === 'linux') {
84
+ const hasPodman = execQuiet('command -v podman');
85
+ if (!hasPodman) {
86
+ return ['--add-host', 'host.docker.internal:host-gateway'];
87
+ }
88
+ }
89
+ return [];
90
+ }
91
+ /**
92
+ * Spawn the worker container in detached mode and return the process.
93
+ */
94
+ export function spawnWorker(opts) {
95
+ const args = ['run', '-d', '--rm', '--name', opts.containerName, '--network', 'shannon-net'];
96
+ // Add host flag for Linux
97
+ args.push(...addHostFlag());
98
+ // Volume mounts
99
+ args.push('-v', `${opts.workspacesDir}:/app/workspaces`);
100
+ args.push('-v', `${opts.repo.hostPath}:${opts.repo.containerPath}`);
101
+ if (opts.config) {
102
+ args.push('-v', `${opts.config.hostPath}:${opts.config.containerPath}:ro`);
103
+ }
104
+ if (opts.credentials) {
105
+ args.push('-v', `${opts.credentials}:/app/credentials/google-sa-vertex-key.json:ro`);
106
+ }
107
+ // Environment
108
+ args.push(...opts.envFlags);
109
+ // Container settings
110
+ args.push('--shm-size', '2gb', '--ipc', 'host', '--security-opt', 'seccomp=unconfined');
111
+ // Image
112
+ args.push(WORKER_IMAGE);
113
+ // Worker command
114
+ args.push('node', 'dist/temporal/worker.js', opts.url, opts.repo.containerPath);
115
+ args.push('--task-queue', opts.taskQueue);
116
+ if (opts.config) {
117
+ args.push('--config', opts.config.containerPath);
118
+ }
119
+ if (opts.workspace) {
120
+ args.push('--workspace', opts.workspace);
121
+ }
122
+ if (opts.pipelineTesting) {
123
+ args.push('--pipeline-testing');
124
+ }
125
+ return spawn('docker', args, { stdio: 'pipe' });
126
+ }
127
+ /**
128
+ * Stop all running shannon-worker-* containers.
129
+ */
130
+ export function stopWorkers() {
131
+ const workers = execOutput('docker ps -q --filter "name=shannon-worker-"');
132
+ if (workers) {
133
+ console.log('Stopping worker containers...');
134
+ execSync(`echo "${workers}" | xargs docker stop`, { stdio: 'inherit' });
135
+ }
136
+ }
137
+ /**
138
+ * Tear down the compose stack.
139
+ */
140
+ export function stopInfra(clean) {
141
+ const cleanFlag = clean ? '-v' : '';
142
+ execSync(`docker compose -f "${COMPOSE_FILE}" --profile router down ${cleanFlag}`, {
143
+ stdio: 'inherit',
144
+ });
145
+ }
146
+ /**
147
+ * Pull the latest worker image (for `update` command).
148
+ */
149
+ export function pullLatest() {
150
+ console.log(`Pulling ${WORKER_IMAGE}...`);
151
+ execSync(`docker pull "${WORKER_IMAGE}"`, { stdio: 'inherit' });
152
+ }
153
+ /**
154
+ * List running worker containers.
155
+ */
156
+ export function listRunningWorkers() {
157
+ return execOutput('docker ps --filter "name=shannon-worker-" --format "table {{.Names}}\t{{.Status}}\t{{.RunningFor}}"');
158
+ }
159
+ //# sourceMappingURL=docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.js","sourceRoot":"","sources":["../src/docker.ts"],"names":[],"mappings":"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"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Environment variable loading and credential validation.
3
+ *
4
+ * Loads ~/.shannon/.env and validates that at least one authentication
5
+ * method is configured (API key, OAuth, Bedrock, Vertex, or router).
6
+ */
7
+ /**
8
+ * Load ~/.shannon/.env into process.env.
9
+ * Existing env vars take precedence (standard dotenv behavior).
10
+ */
11
+ export declare function loadEnv(): void;
12
+ /**
13
+ * Build `-e KEY=VALUE` flags for docker run, only for set variables.
14
+ */
15
+ export declare function buildEnvFlags(): string[];
16
+ interface CredentialValidation {
17
+ valid: boolean;
18
+ error?: string;
19
+ mode: 'api-key' | 'oauth' | 'bedrock' | 'vertex' | 'router';
20
+ }
21
+ /**
22
+ * Validate that at least one authentication method is configured.
23
+ */
24
+ export declare function validateCredentials(useRouter: boolean): CredentialValidation;
25
+ export {};
26
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyBH;;;GAGG;AACH,wBAAgB,OAAO,IAAI,IAAI,CAE9B;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAWxC;AAED,UAAU,oBAAoB;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;CAC7D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,oBAAoB,CA2D5E"}