@schoolai/shipyard 0.1.0 → 0.5.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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ROUTES
4
- } from "./chunk-HOG3H5HO.js";
4
+ } from "./chunk-CQBP5B4G.js";
5
5
  import {
6
6
  print,
7
7
  printError
@@ -10,13 +10,15 @@ import {
10
10
  getConfigPath,
11
11
  readConfig,
12
12
  writeConfig
13
- } from "./chunk-4KTYP247.js";
13
+ } from "./chunk-H3TM7MVJ.js";
14
14
  import {
15
- external_exports
16
- } from "./chunk-WB5DGKI3.js";
15
+ external_exports,
16
+ isDevMode
17
+ } from "./chunk-6S523TH3.js";
17
18
 
18
19
  // src/commands/login.ts
19
20
  var DEFAULT_SIGNALING_URL = "https://shipyard-session-server.jacob-191.workers.dev";
21
+ var DEFAULT_DEV_SIGNALING_URL = "http://localhost:4444";
20
22
  var DeviceStartResponseSchema = external_exports.object({
21
23
  deviceCode: external_exports.string(),
22
24
  userCode: external_exports.string(),
@@ -39,7 +41,7 @@ async function loginCommand(options) {
39
41
  if (options.check) {
40
42
  return checkLogin();
41
43
  }
42
- const signalingUrl = process.env.SHIPYARD_SIGNALING_URL ?? DEFAULT_SIGNALING_URL;
44
+ const signalingUrl = process.env.SHIPYARD_SIGNALING_URL ?? (isDevMode() ? DEFAULT_DEV_SIGNALING_URL : DEFAULT_SIGNALING_URL);
43
45
  const startData = await startDeviceFlow(signalingUrl);
44
46
  print(` Open this URL in your browser:
45
47
  `);
@@ -145,4 +147,4 @@ async function checkLogin() {
145
147
  export {
146
148
  loginCommand
147
149
  };
148
- //# sourceMappingURL=login-YE3CJW2C.js.map
150
+ //# sourceMappingURL=login-625HP2EN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/login.ts"],"sourcesContent":["import { ROUTES } from '@shipyard/session';\nimport { z } from 'zod';\nimport { getConfigPath, readConfig, type ShipyardConfig, writeConfig } from '../auth.js';\nimport { isDevMode } from '../env.js';\nimport { print, printError } from './output.js';\n\nconst DEFAULT_SIGNALING_URL = 'https://shipyard-session-server.jacob-191.workers.dev';\nconst DEFAULT_DEV_SIGNALING_URL = 'http://localhost:4444';\n\nconst DeviceStartResponseSchema = z.object({\n deviceCode: z.string(),\n userCode: z.string(),\n verificationUri: z.string(),\n expiresIn: z.number(),\n interval: z.number(),\n});\n\nconst DevicePollResponseSchema = z.object({\n token: z.string(),\n user: z.object({\n id: z.string(),\n displayName: z.string(),\n providers: z.array(z.string()),\n }),\n});\n\nconst DevicePollErrorSchema = z.object({\n error: z.string(),\n});\n\nexport async function loginCommand(options: { check?: boolean }): Promise<void> {\n if (options.check) {\n return checkLogin();\n }\n\n const signalingUrl =\n process.env.SHIPYARD_SIGNALING_URL ??\n (isDevMode() ? DEFAULT_DEV_SIGNALING_URL : DEFAULT_SIGNALING_URL);\n const startData = await startDeviceFlow(signalingUrl);\n\n print(` Open this URL in your browser:\\n`);\n print(` ${startData.verificationUri}\\n`);\n print(` Your code: ${startData.userCode}\\n`);\n print(' Waiting for authorization...');\n\n const interval = (startData.interval ?? 5) * 1000;\n const deadline = Date.now() + startData.expiresIn * 1000;\n\n while (Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, interval));\n\n const pollRes = await fetch(`${signalingUrl}${ROUTES.AUTH_DEVICE_POLL}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ deviceCode: startData.deviceCode }),\n });\n\n if (pollRes.ok) {\n await handleSuccessfulPoll(pollRes, signalingUrl);\n return;\n }\n\n await handlePollError(pollRes, interval);\n }\n\n printError('\\n Authorization timed out. Run `shipyard login` again.');\n process.exit(1);\n}\n\nasync function startDeviceFlow(signalingUrl: string) {\n print('Starting device authorization...\\n');\n\n let startRes: Response;\n try {\n startRes = await fetch(`${signalingUrl}${ROUTES.AUTH_DEVICE_START}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n });\n } catch {\n printError(`Could not reach signaling server at ${signalingUrl}`);\n printError('Check your internet connection or set SHIPYARD_SIGNALING_URL.');\n process.exit(1);\n }\n\n if (!startRes.ok) {\n printError(`Failed to start device flow: ${startRes.status}`);\n process.exit(1);\n }\n\n return DeviceStartResponseSchema.parse(await startRes.json());\n}\n\nfunction extractTokenExpiry(token: string): number {\n const fallback = Date.now() + 30 * 24 * 60 * 60 * 1000;\n try {\n const payloadB64 = token.split('.')[1];\n if (!payloadB64) return fallback;\n const payload: unknown = JSON.parse(Buffer.from(payloadB64, 'base64url').toString());\n const exp = z.object({ exp: z.number() }).safeParse(payload);\n return exp.success ? exp.data.exp * 1000 : fallback;\n } catch {\n return fallback;\n }\n}\n\nasync function handleSuccessfulPoll(pollRes: Response, signalingUrl: string): Promise<void> {\n const pollData = DevicePollResponseSchema.parse(await pollRes.json());\n const expiresAt = extractTokenExpiry(pollData.token);\n\n const config: ShipyardConfig = {\n auth: {\n token: pollData.token,\n userId: pollData.user.id,\n displayName: pollData.user.displayName,\n providers: pollData.user.providers,\n expiresAt,\n signalingUrl,\n },\n };\n\n await writeConfig(config);\n\n print(`\\n Logged in as ${pollData.user.displayName} (${pollData.user.providers.join(', ')})`);\n print(` Token saved to ${getConfigPath()}`);\n}\n\nasync function handlePollError(pollRes: Response, interval: number): Promise<void> {\n try {\n const errorData = DevicePollErrorSchema.parse(await pollRes.json());\n\n if (errorData.error === 'expired_token') {\n printError('\\n Authorization expired. Run `shipyard login` again.');\n process.exit(1);\n }\n\n if (errorData.error === 'slow_down') {\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n } catch {}\n}\n\nasync function checkLogin(): Promise<void> {\n const config = await readConfig();\n\n if (!config?.auth?.token) {\n print('Not logged in. Run `shipyard login` to authenticate.');\n process.exit(1);\n }\n\n if (config.auth.expiresAt < Date.now()) {\n print('Token expired. Run `shipyard login` to re-authenticate.');\n process.exit(1);\n }\n\n const daysLeft = Math.ceil((config.auth.expiresAt - Date.now()) / (24 * 60 * 60 * 1000));\n print(`Logged in as ${config.auth.displayName} (${config.auth.providers.join(', ')})`);\n print(`Token expires in ${daysLeft} days`);\n}\n"],"mappings":"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","names":[]}
@@ -5,8 +5,8 @@ import {
5
5
  import {
6
6
  deleteConfig,
7
7
  getConfigPath
8
- } from "./chunk-4KTYP247.js";
9
- import "./chunk-WB5DGKI3.js";
8
+ } from "./chunk-H3TM7MVJ.js";
9
+ import "./chunk-6S523TH3.js";
10
10
 
11
11
  // src/commands/logout.ts
12
12
  async function logoutCommand() {
@@ -20,4 +20,4 @@ async function logoutCommand() {
20
20
  export {
21
21
  logoutCommand
22
22
  };
23
- //# sourceMappingURL=logout-5JRAQEQC.js.map
23
+ //# sourceMappingURL=logout-L6EMSGQU.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schoolai/shipyard",
3
- "version": "0.1.0",
3
+ "version": "0.5.0",
4
4
  "description": "Shipyard daemon - Claude Agent SDK + Loro CRDT sync",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/login.ts"],"sourcesContent":["import { ROUTES } from '@shipyard/session';\nimport { z } from 'zod';\nimport { getConfigPath, readConfig, type ShipyardConfig, writeConfig } from '../auth.js';\nimport { print, printError } from './output.js';\n\nconst DEFAULT_SIGNALING_URL = 'https://shipyard-session-server.jacob-191.workers.dev';\n\nconst DeviceStartResponseSchema = z.object({\n deviceCode: z.string(),\n userCode: z.string(),\n verificationUri: z.string(),\n expiresIn: z.number(),\n interval: z.number(),\n});\n\nconst DevicePollResponseSchema = z.object({\n token: z.string(),\n user: z.object({\n id: z.string(),\n displayName: z.string(),\n providers: z.array(z.string()),\n }),\n});\n\nconst DevicePollErrorSchema = z.object({\n error: z.string(),\n});\n\nexport async function loginCommand(options: { check?: boolean }): Promise<void> {\n if (options.check) {\n return checkLogin();\n }\n\n const signalingUrl = process.env.SHIPYARD_SIGNALING_URL ?? DEFAULT_SIGNALING_URL;\n const startData = await startDeviceFlow(signalingUrl);\n\n print(` Open this URL in your browser:\\n`);\n print(` ${startData.verificationUri}\\n`);\n print(` Your code: ${startData.userCode}\\n`);\n print(' Waiting for authorization...');\n\n const interval = (startData.interval ?? 5) * 1000;\n const deadline = Date.now() + startData.expiresIn * 1000;\n\n while (Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, interval));\n\n const pollRes = await fetch(`${signalingUrl}${ROUTES.AUTH_DEVICE_POLL}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ deviceCode: startData.deviceCode }),\n });\n\n if (pollRes.ok) {\n await handleSuccessfulPoll(pollRes, signalingUrl);\n return;\n }\n\n await handlePollError(pollRes, interval);\n }\n\n printError('\\n Authorization timed out. Run `shipyard login` again.');\n process.exit(1);\n}\n\nasync function startDeviceFlow(signalingUrl: string) {\n print('Starting device authorization...\\n');\n\n let startRes: Response;\n try {\n startRes = await fetch(`${signalingUrl}${ROUTES.AUTH_DEVICE_START}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n });\n } catch {\n printError(`Could not reach signaling server at ${signalingUrl}`);\n printError('Check your internet connection or set SHIPYARD_SIGNALING_URL.');\n process.exit(1);\n }\n\n if (!startRes.ok) {\n printError(`Failed to start device flow: ${startRes.status}`);\n process.exit(1);\n }\n\n return DeviceStartResponseSchema.parse(await startRes.json());\n}\n\nfunction extractTokenExpiry(token: string): number {\n const fallback = Date.now() + 30 * 24 * 60 * 60 * 1000;\n try {\n const payloadB64 = token.split('.')[1];\n if (!payloadB64) return fallback;\n const payload: unknown = JSON.parse(Buffer.from(payloadB64, 'base64url').toString());\n const exp = z.object({ exp: z.number() }).safeParse(payload);\n return exp.success ? exp.data.exp * 1000 : fallback;\n } catch {\n return fallback;\n }\n}\n\nasync function handleSuccessfulPoll(pollRes: Response, signalingUrl: string): Promise<void> {\n const pollData = DevicePollResponseSchema.parse(await pollRes.json());\n const expiresAt = extractTokenExpiry(pollData.token);\n\n const config: ShipyardConfig = {\n auth: {\n token: pollData.token,\n userId: pollData.user.id,\n displayName: pollData.user.displayName,\n providers: pollData.user.providers,\n expiresAt,\n signalingUrl,\n },\n };\n\n await writeConfig(config);\n\n print(`\\n Logged in as ${pollData.user.displayName} (${pollData.user.providers.join(', ')})`);\n print(` Token saved to ${getConfigPath()}`);\n}\n\nasync function handlePollError(pollRes: Response, interval: number): Promise<void> {\n try {\n const errorData = DevicePollErrorSchema.parse(await pollRes.json());\n\n if (errorData.error === 'expired_token') {\n printError('\\n Authorization expired. Run `shipyard login` again.');\n process.exit(1);\n }\n\n if (errorData.error === 'slow_down') {\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n } catch {\n /* non-JSON response — keep polling */\n }\n}\n\nasync function checkLogin(): Promise<void> {\n const config = await readConfig();\n\n if (!config?.auth?.token) {\n print('Not logged in. Run `shipyard login` to authenticate.');\n process.exit(1);\n }\n\n if (config.auth.expiresAt < Date.now()) {\n print('Token expired. Run `shipyard login` to re-authenticate.');\n process.exit(1);\n }\n\n const daysLeft = Math.ceil((config.auth.expiresAt - Date.now()) / (24 * 60 * 60 * 1000));\n print(`Logged in as ${config.auth.displayName} (${config.auth.providers.join(', ')})`);\n print(`Token expires in ${daysLeft} days`);\n}\n"],"mappings":"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","names":[]}