studiograph 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 (101) hide show
  1. package/README.md +18 -0
  2. package/dist/agent/orchestrator.d.ts +69 -0
  3. package/dist/agent/orchestrator.js +211 -0
  4. package/dist/agent/orchestrator.js.map +1 -0
  5. package/dist/agent/tools/graph-tools.d.ts +30 -0
  6. package/dist/agent/tools/graph-tools.js +536 -0
  7. package/dist/agent/tools/graph-tools.js.map +1 -0
  8. package/dist/auth/github.d.ts +53 -0
  9. package/dist/auth/github.js +180 -0
  10. package/dist/auth/github.js.map +1 -0
  11. package/dist/cli/commands/auth.d.ts +10 -0
  12. package/dist/cli/commands/auth.js +63 -0
  13. package/dist/cli/commands/auth.js.map +1 -0
  14. package/dist/cli/commands/init.d.ts +7 -0
  15. package/dist/cli/commands/init.js +299 -0
  16. package/dist/cli/commands/init.js.map +1 -0
  17. package/dist/cli/commands/join.d.ts +14 -0
  18. package/dist/cli/commands/join.js +230 -0
  19. package/dist/cli/commands/join.js.map +1 -0
  20. package/dist/cli/commands/members.d.ts +11 -0
  21. package/dist/cli/commands/members.js +230 -0
  22. package/dist/cli/commands/members.js.map +1 -0
  23. package/dist/cli/commands/serve.d.ts +17 -0
  24. package/dist/cli/commands/serve.js +90 -0
  25. package/dist/cli/commands/serve.js.map +1 -0
  26. package/dist/cli/commands/start.d.ts +7 -0
  27. package/dist/cli/commands/start.js +381 -0
  28. package/dist/cli/commands/start.js.map +1 -0
  29. package/dist/cli/commands/sync.d.ts +10 -0
  30. package/dist/cli/commands/sync.js +121 -0
  31. package/dist/cli/commands/sync.js.map +1 -0
  32. package/dist/cli/index.d.ts +7 -0
  33. package/dist/cli/index.js +31 -0
  34. package/dist/cli/index.js.map +1 -0
  35. package/dist/core/graph.d.ts +169 -0
  36. package/dist/core/graph.js +558 -0
  37. package/dist/core/graph.js.map +1 -0
  38. package/dist/core/types.d.ts +216 -0
  39. package/dist/core/types.js +71 -0
  40. package/dist/core/types.js.map +1 -0
  41. package/dist/core/user-config.d.ts +31 -0
  42. package/dist/core/user-config.js +50 -0
  43. package/dist/core/user-config.js.map +1 -0
  44. package/dist/core/validation.d.ts +2371 -0
  45. package/dist/core/validation.js +432 -0
  46. package/dist/core/validation.js.map +1 -0
  47. package/dist/core/workspace-manager.d.ts +104 -0
  48. package/dist/core/workspace-manager.js +432 -0
  49. package/dist/core/workspace-manager.js.map +1 -0
  50. package/dist/core/workspace.d.ts +103 -0
  51. package/dist/core/workspace.js +306 -0
  52. package/dist/core/workspace.js.map +1 -0
  53. package/dist/server/index.d.ts +25 -0
  54. package/dist/server/index.js +84 -0
  55. package/dist/server/index.js.map +1 -0
  56. package/dist/server/plugin-loader.d.ts +31 -0
  57. package/dist/server/plugin-loader.js +81 -0
  58. package/dist/server/plugin-loader.js.map +1 -0
  59. package/dist/server/routes/chat.d.ts +11 -0
  60. package/dist/server/routes/chat.js +66 -0
  61. package/dist/server/routes/chat.js.map +1 -0
  62. package/dist/server/routes/graph-api.d.ts +9 -0
  63. package/dist/server/routes/graph-api.js +72 -0
  64. package/dist/server/routes/graph-api.js.map +1 -0
  65. package/dist/server/routes/webhook.d.ts +14 -0
  66. package/dist/server/routes/webhook.js +69 -0
  67. package/dist/server/routes/webhook.js.map +1 -0
  68. package/dist/services/assets/base.d.ts +69 -0
  69. package/dist/services/assets/base.js +113 -0
  70. package/dist/services/assets/base.js.map +1 -0
  71. package/dist/services/assets/index.d.ts +36 -0
  72. package/dist/services/assets/index.js +89 -0
  73. package/dist/services/assets/index.js.map +1 -0
  74. package/dist/services/assets/local.d.ts +42 -0
  75. package/dist/services/assets/local.js +161 -0
  76. package/dist/services/assets/local.js.map +1 -0
  77. package/dist/services/assets/r2.d.ts +36 -0
  78. package/dist/services/assets/r2.js +182 -0
  79. package/dist/services/assets/r2.js.map +1 -0
  80. package/dist/services/csv-service.d.ts +36 -0
  81. package/dist/services/csv-service.js +143 -0
  82. package/dist/services/csv-service.js.map +1 -0
  83. package/dist/services/git.d.ts +99 -0
  84. package/dist/services/git.js +306 -0
  85. package/dist/services/git.js.map +1 -0
  86. package/dist/services/github-provisioner.d.ts +30 -0
  87. package/dist/services/github-provisioner.js +89 -0
  88. package/dist/services/github-provisioner.js.map +1 -0
  89. package/dist/services/markdown.d.ts +82 -0
  90. package/dist/services/markdown.js +338 -0
  91. package/dist/services/markdown.js.map +1 -0
  92. package/dist/services/memory-service.d.ts +74 -0
  93. package/dist/services/memory-service.js +183 -0
  94. package/dist/services/memory-service.js.map +1 -0
  95. package/dist/utils/git.d.ts +28 -0
  96. package/dist/utils/git.js +55 -0
  97. package/dist/utils/git.js.map +1 -0
  98. package/dist/utils/preflight.d.ts +44 -0
  99. package/dist/utils/preflight.js +95 -0
  100. package/dist/utils/preflight.js.map +1 -0
  101. package/package.json +55 -0
@@ -0,0 +1,180 @@
1
+ /**
2
+ * GitHub authentication for Studiograph
3
+ *
4
+ * Uses GitHub Device Flow — designed for CLI tools.
5
+ * No redirect URI or local HTTP server required.
6
+ * Token stored globally at ~/.studiograph/auth.json
7
+ */
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { homedir } from 'os';
11
+ import { Octokit } from '@octokit/rest';
12
+ // OAuth App client_id for Device Flow. Safe to commit — Device Flow has no client_secret
13
+ // and client_ids are public by design (see: github.com/cli/cli source).
14
+ // Registered under the studiographai org as "Studiograph CLI".
15
+ export const GITHUB_CLIENT_ID = process.env.STUDIOGRAPH_GITHUB_CLIENT_ID ?? 'Ov23lipHzDbTRqhz4Zqe';
16
+ const SCOPES = 'repo read:org user:email';
17
+ const DEVICE_CODE_URL = 'https://github.com/login/device/code';
18
+ const ACCESS_TOKEN_URL = 'https://github.com/login/oauth/access_token';
19
+ /**
20
+ * Run GitHub Device Flow to get an access token.
21
+ * Displays a user_code and verification URL, polls until user completes auth.
22
+ */
23
+ export async function runDeviceFlow() {
24
+ // Step 1: Request device and user codes
25
+ const codeResponse = await fetch(DEVICE_CODE_URL, {
26
+ method: 'POST',
27
+ headers: {
28
+ 'Content-Type': 'application/json',
29
+ Accept: 'application/json',
30
+ },
31
+ body: JSON.stringify({
32
+ client_id: GITHUB_CLIENT_ID,
33
+ scope: SCOPES,
34
+ }),
35
+ });
36
+ if (!codeResponse.ok) {
37
+ throw new Error(`Failed to start device flow: ${codeResponse.statusText}`);
38
+ }
39
+ const codeData = await codeResponse.json();
40
+ const { device_code, user_code, verification_uri, expires_in, interval } = codeData;
41
+ // Step 2: Display instructions to user
42
+ console.log(`\nGo to ${verification_uri} and enter: ${user_code}\n`);
43
+ // Step 3: Poll for token
44
+ const pollIntervalMs = (interval ?? 5) * 1000;
45
+ const expiresAt = Date.now() + (expires_in ?? 900) * 1000;
46
+ while (Date.now() < expiresAt) {
47
+ await sleep(pollIntervalMs);
48
+ const tokenResponse = await fetch(ACCESS_TOKEN_URL, {
49
+ method: 'POST',
50
+ headers: {
51
+ 'Content-Type': 'application/json',
52
+ Accept: 'application/json',
53
+ },
54
+ body: JSON.stringify({
55
+ client_id: GITHUB_CLIENT_ID,
56
+ device_code,
57
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
58
+ }),
59
+ });
60
+ if (!tokenResponse.ok) {
61
+ throw new Error(`Token poll failed: ${tokenResponse.statusText}`);
62
+ }
63
+ const tokenData = await tokenResponse.json();
64
+ if (tokenData.access_token) {
65
+ return tokenData.access_token;
66
+ }
67
+ if (tokenData.error === 'authorization_pending') {
68
+ // Still waiting — continue polling
69
+ continue;
70
+ }
71
+ if (tokenData.error === 'slow_down') {
72
+ // Back off by an extra 5 seconds
73
+ await sleep(5000);
74
+ continue;
75
+ }
76
+ if (tokenData.error === 'expired_token') {
77
+ throw new Error('Device code expired. Please try again.');
78
+ }
79
+ if (tokenData.error === 'access_denied') {
80
+ throw new Error('Authorization was denied.');
81
+ }
82
+ throw new Error(`Unexpected error: ${tokenData.error ?? 'unknown'}`);
83
+ }
84
+ throw new Error('Device code expired before authorization completed.');
85
+ }
86
+ /**
87
+ * Get the path to the global auth file (~/.studiograph/auth.json)
88
+ */
89
+ function getAuthFilePath() {
90
+ return join(homedir(), '.studiograph', 'auth.json');
91
+ }
92
+ /**
93
+ * Store token and user info at ~/.studiograph/auth.json
94
+ */
95
+ export function storeToken(token, user) {
96
+ const dir = join(homedir(), '.studiograph');
97
+ mkdirSync(dir, { recursive: true });
98
+ const data = { token, user };
99
+ writeFileSync(getAuthFilePath(), JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600 });
100
+ }
101
+ /**
102
+ * Load stored token and user from ~/.studiograph/auth.json
103
+ * Returns null if not found or invalid.
104
+ */
105
+ export function loadToken() {
106
+ const authPath = getAuthFilePath();
107
+ if (!existsSync(authPath))
108
+ return null;
109
+ try {
110
+ const data = JSON.parse(readFileSync(authPath, 'utf-8'));
111
+ if (!data.token || !data.user?.login)
112
+ return null;
113
+ return data;
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ }
119
+ /**
120
+ * Remove stored token from ~/.studiograph/auth.json
121
+ */
122
+ export function clearToken() {
123
+ const authPath = getAuthFilePath();
124
+ if (existsSync(authPath)) {
125
+ writeFileSync(authPath, JSON.stringify({}, null, 2), 'utf-8');
126
+ }
127
+ }
128
+ /**
129
+ * Create an authenticated Octokit instance
130
+ */
131
+ export function getAuthenticatedOctokit(token) {
132
+ return new Octokit({ auth: token });
133
+ }
134
+ /**
135
+ * Fetch the authenticated GitHub user's profile
136
+ */
137
+ export async function getGitHubUser(token) {
138
+ const octokit = getAuthenticatedOctokit(token);
139
+ const { data: userInfo } = await octokit.rest.users.getAuthenticated();
140
+ // Fetch primary email if not public
141
+ let email = userInfo.email ?? '';
142
+ if (!email) {
143
+ const { data: emails } = await octokit.rest.users.listEmailsForAuthenticatedUser();
144
+ const primary = emails.find(e => e.primary && e.verified);
145
+ email = primary?.email ?? '';
146
+ }
147
+ return {
148
+ login: userInfo.login,
149
+ name: userInfo.name ?? userInfo.login,
150
+ email,
151
+ };
152
+ }
153
+ /**
154
+ * Check if the authenticated user is a member of the given GitHub org
155
+ */
156
+ export async function verifyOrgMembership(octokit, org) {
157
+ try {
158
+ await octokit.rest.orgs.getMembershipForAuthenticatedUser({ org });
159
+ return true;
160
+ }
161
+ catch {
162
+ return false;
163
+ }
164
+ }
165
+ /**
166
+ * Get the names of teams the authenticated user belongs to within an org
167
+ */
168
+ export async function getUserOrgTeams(octokit, org) {
169
+ try {
170
+ const { data: teams } = await octokit.rest.teams.listForAuthenticatedUser({ org });
171
+ return teams.map(t => t.slug);
172
+ }
173
+ catch {
174
+ return [];
175
+ }
176
+ }
177
+ function sleep(ms) {
178
+ return new Promise(resolve => setTimeout(resolve, ms));
179
+ }
180
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/auth/github.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,yFAAyF;AACzF,wEAAwE;AACxE,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,sBAAsB,CAAC;AAEnG,MAAM,MAAM,GAAG,0BAA0B,CAAC;AAC1C,MAAM,eAAe,GAAG,sCAAsC,CAAC;AAC/D,MAAM,gBAAgB,GAAG,6CAA6C,CAAC;AAavE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,wCAAwC;IACxC,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE;QAChD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,MAAM,EAAE,kBAAkB;SAC3B;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,SAAS,EAAE,gBAAgB;YAC3B,KAAK,EAAE,MAAM;SACd,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,gCAAgC,YAAY,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,EAMvC,CAAC;IAEF,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;IAEpF,uCAAuC;IACvC,OAAO,CAAC,GAAG,CAAC,WAAW,gBAAgB,eAAe,SAAS,IAAI,CAAC,CAAC;IAErE,yBAAyB;IACzB,MAAM,cAAc,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC;IAE1D,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,cAAc,CAAC,CAAC;QAE5B,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,gBAAgB,EAAE;YAClD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,MAAM,EAAE,kBAAkB;aAC3B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,SAAS,EAAE,gBAAgB;gBAC3B,WAAW;gBACX,UAAU,EAAE,8CAA8C;aAC3D,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,sBAAsB,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,EAIzC,CAAC;QAEF,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC;YAC3B,OAAO,SAAS,CAAC,YAAY,CAAC;QAChC,CAAC;QAED,IAAI,SAAS,CAAC,KAAK,KAAK,uBAAuB,EAAE,CAAC;YAChD,mCAAmC;YACnC,SAAS;QACX,CAAC;QAED,IAAI,SAAS,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YACpC,iCAAiC;YACjC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QAED,IAAI,SAAS,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,SAAS,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,qBAAqB,SAAS,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;AACzE,CAAC;AAED;;GAEG;AACH,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,IAAgB;IACxD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;IAC5C,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,IAAI,GAAe,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzC,aAAa,CAAC,eAAe,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACtG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAe,CAAC;QACvE,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK;YAAE,OAAO,IAAI,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,IAAI,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa;IAC/C,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;IAEvE,oCAAoC;IACpC,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC;QACnF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC1D,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,KAAK;QACrC,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAgB,EAAE,GAAW;IACrE,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,iCAAiC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAgB,EAAE,GAAW;IACjE,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACnF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * studiograph auth command
3
+ *
4
+ * Subcommands:
5
+ * studiograph auth github — authenticate via GitHub Device Flow
6
+ * studiograph auth status — show current auth status
7
+ * studiograph auth logout — clear stored token
8
+ */
9
+ import { Command } from 'commander';
10
+ export declare const authCommand: Command;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * studiograph auth command
3
+ *
4
+ * Subcommands:
5
+ * studiograph auth github — authenticate via GitHub Device Flow
6
+ * studiograph auth status — show current auth status
7
+ * studiograph auth logout — clear stored token
8
+ */
9
+ import { Command } from 'commander';
10
+ import { intro, outro, spinner, log } from '@clack/prompts';
11
+ import { runDeviceFlow, storeToken, loadToken, clearToken, getGitHubUser, } from '../../auth/github.js';
12
+ const authGithubCommand = new Command('github')
13
+ .description('Authenticate with GitHub using Device Flow')
14
+ .action(async () => {
15
+ intro('GitHub Authentication');
16
+ try {
17
+ log.info('Starting Device Flow...');
18
+ // runDeviceFlow prints the user_code + URL itself
19
+ const token = await runDeviceFlow();
20
+ const s = spinner();
21
+ s.start('Fetching your GitHub identity...');
22
+ const user = await getGitHubUser(token);
23
+ s.stop('Authenticated');
24
+ storeToken(token, user);
25
+ outro(`✨ Authenticated as ${user.login} (${user.name})`);
26
+ }
27
+ catch (error) {
28
+ log.error(`Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
29
+ outro('❌ Could not authenticate with GitHub.');
30
+ process.exit(1);
31
+ }
32
+ });
33
+ const authStatusCommand = new Command('status')
34
+ .description('Show current GitHub authentication status')
35
+ .action(() => {
36
+ const stored = loadToken();
37
+ if (stored) {
38
+ console.log(`Authenticated as ${stored.user.login} (${stored.user.name})`);
39
+ if (stored.user.email) {
40
+ console.log(`Email: ${stored.user.email}`);
41
+ }
42
+ }
43
+ else {
44
+ console.log('Not authenticated. Run `studiograph auth github` to authenticate.');
45
+ }
46
+ });
47
+ const authLogoutCommand = new Command('logout')
48
+ .description('Clear stored GitHub token')
49
+ .action(() => {
50
+ const stored = loadToken();
51
+ if (!stored) {
52
+ console.log('Not currently authenticated.');
53
+ return;
54
+ }
55
+ clearToken();
56
+ console.log(`Logged out (was authenticated as ${stored.user.login}).`);
57
+ });
58
+ export const authCommand = new Command('auth')
59
+ .description('Manage GitHub authentication')
60
+ .addCommand(authGithubCommand)
61
+ .addCommand(authStatusCommand)
62
+ .addCommand(authLogoutCommand);
63
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/cli/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * studiograph init command
3
+ *
4
+ * Initializes a new Studiograph workspace in the current directory
5
+ */
6
+ import { Command } from 'commander';
7
+ export declare const initCommand: Command;
@@ -0,0 +1,299 @@
1
+ /**
2
+ * studiograph init command
3
+ *
4
+ * Initializes a new Studiograph workspace in the current directory
5
+ */
6
+ import { Command } from 'commander';
7
+ import { intro, text, select, confirm, outro, spinner, log } from '@clack/prompts';
8
+ import { Workspace } from '../../core/workspace.js';
9
+ import { RepoType } from '../../core/types.js';
10
+ import { loadToken, runDeviceFlow, storeToken, getGitHubUser, getAuthenticatedOctokit } from '../../auth/github.js';
11
+ import { provisionWorkspace } from '../../services/github-provisioner.js';
12
+ import { runPreflight } from '../../utils/preflight.js';
13
+ // Industry templates configuration
14
+ const INDUSTRY_TEMPLATES = {
15
+ 'design-studio': {
16
+ name: 'Design & production studio',
17
+ description: 'Product design teams, UX/UI agencies, design consultancies',
18
+ pattern: 'client-centric',
19
+ functionRepos: [
20
+ { name: 'new-business', description: 'Proposals, pitches, and business development' },
21
+ { name: 'accounting', description: 'Financials, billing, and budgets (restricted)' },
22
+ { name: 'operations', description: 'Team capacity, processes, and policies' },
23
+ ],
24
+ sharedRepos: [
25
+ { name: 'templates', description: 'Proposal templates, processes, and standards' },
26
+ { name: 'design-systems', description: 'Reusable components, patterns, and tokens' },
27
+ { name: 'research', description: 'Design references, techniques, and inspiration' },
28
+ ],
29
+ },
30
+ 'marketing-agency': {
31
+ name: 'Marketing & communications agency',
32
+ description: 'Advertising, digital marketing, social, content, PR',
33
+ pattern: 'project-centric',
34
+ functionRepos: [
35
+ { name: 'pitches', description: 'New business pitches and campaign proposals' },
36
+ { name: 'media-planning', description: 'Media budgets, buys, and performance tracking' },
37
+ { name: 'finance', description: 'Project budgets and billing (restricted)' },
38
+ ],
39
+ sharedRepos: [
40
+ { name: 'brand-guidelines', description: 'Client brand standards and messaging' },
41
+ { name: 'creative-library', description: 'Stock assets, campaign references, and tools' },
42
+ { name: 'production-resources', description: 'Vendor database and production resources' },
43
+ ],
44
+ },
45
+ 'content-shop': {
46
+ name: 'Content & storytelling shop',
47
+ description: 'Film/video production, editorial, podcast studios',
48
+ pattern: 'project-centric',
49
+ functionRepos: [
50
+ { name: 'pitches', description: 'Content proposals and treatments' },
51
+ { name: 'production-ops', description: 'Crew database, equipment, and schedules' },
52
+ { name: 'finance', description: 'Production budgets and freelance rates (restricted)' },
53
+ ],
54
+ sharedRepos: [
55
+ { name: 'editorial-guidelines', description: 'Voice, tone, and editorial standards' },
56
+ { name: 'content-library', description: 'Stock footage, music, and graphics templates' },
57
+ { name: 'reference-library', description: 'Film references and storytelling techniques' },
58
+ ],
59
+ },
60
+ 'experiential-firm': {
61
+ name: 'Experiential & environmental firm',
62
+ description: 'Event/experiential agencies, exhibition design, installations',
63
+ pattern: 'client-centric',
64
+ functionRepos: [
65
+ { name: 'business-development', description: 'Event proposals and exhibition pitches' },
66
+ { name: 'production-management', description: 'Vendor coordination and installation planning' },
67
+ { name: 'finance', description: 'Project budgets and vendor payments (restricted)' },
68
+ ],
69
+ sharedRepos: [
70
+ { name: 'installation-library', description: 'Past installations and technical specs' },
71
+ { name: 'vendor-database', description: 'Fabricators, AV vendors, and specialists' },
72
+ { name: 'reference-library', description: 'Experiential examples and spatial design' },
73
+ ],
74
+ },
75
+ 'digital-studio': {
76
+ name: 'Digital product & technology studio',
77
+ description: 'Web/app studios, product design + engineering firms',
78
+ pattern: 'project-centric',
79
+ functionRepos: [
80
+ { name: 'proposals', description: 'SOWs, estimates, and technical proposals' },
81
+ { name: 'operations', description: 'Capacity planning and sprint tracking' },
82
+ { name: 'finance', description: 'Project budgets and contractor rates (restricted)' },
83
+ ],
84
+ sharedRepos: [
85
+ { name: 'architecture', description: 'System design patterns and tech standards' },
86
+ { name: 'codebase', description: 'Reusable components and integrations' },
87
+ { name: 'product-references', description: 'Competitor analysis and UX patterns' },
88
+ ],
89
+ },
90
+ 'consulting-firm': {
91
+ name: 'Strategy, consulting & innovation firm',
92
+ description: 'Brand/innovation consultancies, service design firms',
93
+ pattern: 'client-centric',
94
+ functionRepos: [
95
+ { name: 'proposals', description: 'Strategic proposals and workshop proposals' },
96
+ { name: 'research-ops', description: 'Research methodologies and participant recruiting' },
97
+ { name: 'finance', description: 'Engagement budgets and billing (restricted)' },
98
+ ],
99
+ sharedRepos: [
100
+ { name: 'frameworks', description: 'Strategy frameworks and innovation toolkits' },
101
+ { name: 'research-library', description: 'Market research and competitive intelligence' },
102
+ { name: 'case-studies', description: 'Past engagements and outcomes' },
103
+ ],
104
+ },
105
+ 'architecture-studio': {
106
+ name: 'Architecture studio',
107
+ description: 'Architectural design practices',
108
+ pattern: 'client-centric',
109
+ functionRepos: [
110
+ { name: 'proposals', description: 'RFPs, competition entries, and fee proposals' },
111
+ { name: 'project-management', description: 'Construction admin and permitting' },
112
+ { name: 'finance', description: 'Project budgets and consultant fees (restricted)' },
113
+ ],
114
+ sharedRepos: [
115
+ { name: 'standards', description: 'Building codes and accessibility standards' },
116
+ { name: 'details-library', description: 'Construction details and material specs' },
117
+ { name: 'precedent-studies', description: 'Architectural references and site analyses' },
118
+ ],
119
+ },
120
+ 'creative-tech': {
121
+ name: 'Creative technology firm',
122
+ description: 'Interactive/immersive studios, creative R&D labs',
123
+ pattern: 'project-centric',
124
+ functionRepos: [
125
+ { name: 'proposals', description: 'R&D proposals and prototyping scopes' },
126
+ { name: 'lab-operations', description: 'Equipment inventory and prototyping resources' },
127
+ { name: 'finance', description: 'Project budgets and hardware costs (restricted)' },
128
+ ],
129
+ sharedRepos: [
130
+ { name: 'technical-library', description: 'Code patterns and hardware specs' },
131
+ { name: 'prototype-archive', description: 'Past experiments and learnings' },
132
+ { name: 'tech-references', description: 'Emerging tech and academic papers' },
133
+ ],
134
+ },
135
+ };
136
+ export const initCommand = new Command('init')
137
+ .description('Initialize a new Studiograph workspace in the current directory')
138
+ .option('--bare', 'Create minimal workspace without scaffolding')
139
+ .option('--github', 'Automatically create GitHub repos after init')
140
+ .option('--github-org <org>', 'GitHub org to create repos in (implies --github)')
141
+ .action(async (options) => {
142
+ intro('Studiograph Workspace Setup');
143
+ const ready = runPreflight();
144
+ if (!ready) {
145
+ process.exit(1);
146
+ return;
147
+ }
148
+ const workspace = new Workspace();
149
+ // Check if already initialized
150
+ if (workspace.isWorkspace()) {
151
+ outro('❌ Already a Studiograph workspace');
152
+ process.exit(1);
153
+ }
154
+ let selectedTemplate = null;
155
+ // Skip template selection if --bare flag is used
156
+ if (!options.bare) {
157
+ // Ask which type of creative firm
158
+ const firmType = await select({
159
+ message: 'What type of creative firm are you?',
160
+ options: [
161
+ { value: 'design-studio', label: 'Design & production studio', hint: 'Product design, UX/UI, branding' },
162
+ { value: 'marketing-agency', label: 'Marketing & communications agency', hint: 'Advertising, digital marketing, PR' },
163
+ { value: 'content-shop', label: 'Content & storytelling shop', hint: 'Film/video production, editorial' },
164
+ { value: 'experiential-firm', label: 'Experiential & environmental firm', hint: 'Events, exhibitions, installations' },
165
+ { value: 'digital-studio', label: 'Digital product & technology studio', hint: 'Web/app studios, product teams' },
166
+ { value: 'consulting-firm', label: 'Strategy, consulting & innovation firm', hint: 'Brand consultancies, service design' },
167
+ { value: 'architecture-studio', label: 'Architecture studio', hint: 'Architectural design practices' },
168
+ { value: 'creative-tech', label: 'Creative technology firm', hint: 'Interactive, immersive, R&D labs' },
169
+ { value: 'bare', label: 'Bare (custom setup)', hint: 'No scaffolding, build your own' },
170
+ ],
171
+ });
172
+ if (typeof firmType === 'symbol' || !firmType) {
173
+ outro('Cancelled');
174
+ process.exit(0);
175
+ }
176
+ selectedTemplate = firmType === 'bare' ? null : firmType;
177
+ }
178
+ // Get team name
179
+ const teamName = await text({
180
+ message: 'What is your team name?',
181
+ placeholder: 'Acme Studios',
182
+ validate: (value) => {
183
+ if (!value)
184
+ return 'Team name is required';
185
+ },
186
+ });
187
+ if (typeof teamName !== 'string') {
188
+ outro('Cancelled');
189
+ process.exit(0);
190
+ }
191
+ // Initialize workspace
192
+ const s = spinner();
193
+ s.start('Creating workspace...');
194
+ try {
195
+ workspace.init(teamName);
196
+ s.stop('Workspace created');
197
+ // If template selected, create repos
198
+ if (selectedTemplate && INDUSTRY_TEMPLATES[selectedTemplate]) {
199
+ const template = INDUSTRY_TEMPLATES[selectedTemplate];
200
+ s.start(`Setting up ${template.name} repos...`);
201
+ // Create function repos
202
+ for (const repo of template.functionRepos) {
203
+ workspace.registerRepo({
204
+ name: repo.name,
205
+ type: RepoType.FUNCTION,
206
+ description: repo.description,
207
+ });
208
+ }
209
+ // Create shared resource repos
210
+ for (const repo of template.sharedRepos) {
211
+ workspace.registerRepo({
212
+ name: repo.name,
213
+ type: RepoType.SHARED_RESOURCE,
214
+ description: repo.description,
215
+ });
216
+ }
217
+ s.stop(`Created ${template.functionRepos.length + template.sharedRepos.length} repos`);
218
+ }
219
+ // --- GitHub provisioning ---
220
+ const wantsGitHub = options.githubOrg || options.github;
221
+ let shouldProvision = wantsGitHub;
222
+ if (!wantsGitHub) {
223
+ const answer = await confirm({
224
+ message: 'Would you like to create these repos on GitHub?',
225
+ initialValue: false,
226
+ });
227
+ shouldProvision = answer === true;
228
+ }
229
+ if (shouldProvision) {
230
+ // Ensure we have a token
231
+ let stored = loadToken();
232
+ if (!stored) {
233
+ log.info('No GitHub token found. Starting authentication...');
234
+ const token = await runDeviceFlow();
235
+ const user = await getGitHubUser(token);
236
+ storeToken(token, user);
237
+ stored = { token, user };
238
+ log.success(`Authenticated as ${user.login}`);
239
+ }
240
+ // Determine org
241
+ let githubOrg = options.githubOrg;
242
+ if (!githubOrg) {
243
+ const orgInput = await text({
244
+ message: 'GitHub org name to create repos in:',
245
+ placeholder: 'my-org',
246
+ validate: (v) => { if (!v)
247
+ return 'Org name is required'; },
248
+ });
249
+ if (typeof orgInput !== 'string') {
250
+ outro('Cancelled');
251
+ process.exit(0);
252
+ }
253
+ githubOrg = orgInput;
254
+ }
255
+ const octokit = getAuthenticatedOctokit(stored.token);
256
+ const currentConfig = workspace.loadConfig();
257
+ const provisionSpinner = spinner();
258
+ provisionSpinner.start('Creating GitHub repos...');
259
+ try {
260
+ const updatedConfig = await provisionWorkspace({
261
+ octokit,
262
+ org: githubOrg,
263
+ workspacePath: workspace.getWorkspacePath(),
264
+ config: currentConfig,
265
+ onProgress: (msg) => provisionSpinner.message(msg),
266
+ });
267
+ // Write back updated config with github_urls + org
268
+ updatedConfig.github = { org: githubOrg };
269
+ workspace.writeConfig(updatedConfig);
270
+ provisionSpinner.stop('GitHub repos created');
271
+ const label = selectedTemplate && INDUSTRY_TEMPLATES[selectedTemplate]
272
+ ? INDUSTRY_TEMPLATES[selectedTemplate].name
273
+ : null;
274
+ outro(label
275
+ ? `✨ ${label} workspace initialized with GitHub repos!`
276
+ : '✨ Workspace initialized with GitHub repos!');
277
+ }
278
+ catch (provisionError) {
279
+ provisionSpinner.stop('Failed to provision GitHub repos');
280
+ log.error(`GitHub provisioning failed: ${provisionError instanceof Error ? provisionError.message : 'Unknown error'}`);
281
+ outro('Workspace created locally. Fix the error above and re-run provisioning manually.');
282
+ }
283
+ }
284
+ else {
285
+ const label = selectedTemplate && INDUSTRY_TEMPLATES[selectedTemplate]
286
+ ? INDUSTRY_TEMPLATES[selectedTemplate].name
287
+ : null;
288
+ outro(label
289
+ ? `✨ ${label} workspace initialized!`
290
+ : '✨ Workspace initialized!');
291
+ }
292
+ }
293
+ catch (error) {
294
+ s.stop('Failed');
295
+ outro(`❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
296
+ process.exit(1);
297
+ }
298
+ });
299
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * studiograph join command
3
+ *
4
+ * Joins an existing Studiograph workspace by cloning the .studiograph
5
+ * config repo, detecting the user's role, and cloning all accessible repos.
6
+ */
7
+ import { Command } from 'commander';
8
+ import { TeamMember } from '../../core/workspace.js';
9
+ /**
10
+ * Attempt to identify a workspace member using the stored GitHub token.
11
+ * Returns the matching TeamMember, or undefined if not identified.
12
+ */
13
+ export declare function resolveIdentityFromToken(members: TeamMember[]): Promise<TeamMember | undefined>;
14
+ export declare const joinCommand: Command;