emdash-emit 0.0.0-stage → 0.1.2

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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +798 -2
  3. package/dist/bin/emit.d.ts +5 -0
  4. package/dist/bin/emit.d.ts.map +1 -0
  5. package/dist/bin/emit.js +63 -0
  6. package/dist/bin/emit.js.map +1 -0
  7. package/dist/cli/commands/new.d.ts +4 -0
  8. package/dist/cli/commands/new.d.ts.map +1 -0
  9. package/dist/cli/commands/new.js +49 -0
  10. package/dist/cli/commands/new.js.map +1 -0
  11. package/dist/cli/commands/profile.d.ts +3 -0
  12. package/dist/cli/commands/profile.d.ts.map +1 -0
  13. package/dist/cli/commands/profile.js +104 -0
  14. package/dist/cli/commands/profile.js.map +1 -0
  15. package/dist/cli/commands/pull.d.ts +4 -0
  16. package/dist/cli/commands/pull.d.ts.map +1 -0
  17. package/dist/cli/commands/pull.js +157 -0
  18. package/dist/cli/commands/pull.js.map +1 -0
  19. package/dist/cli/commands/push.d.ts +4 -0
  20. package/dist/cli/commands/push.d.ts.map +1 -0
  21. package/dist/cli/commands/push.js +107 -0
  22. package/dist/cli/commands/push.js.map +1 -0
  23. package/dist/cli/commands/status.d.ts +4 -0
  24. package/dist/cli/commands/status.d.ts.map +1 -0
  25. package/dist/cli/commands/status.js +100 -0
  26. package/dist/cli/commands/status.js.map +1 -0
  27. package/dist/cli/context.d.ts +15 -0
  28. package/dist/cli/context.d.ts.map +1 -0
  29. package/dist/cli/context.js +75 -0
  30. package/dist/cli/context.js.map +1 -0
  31. package/dist/client/api.d.ts +19 -0
  32. package/dist/client/api.d.ts.map +1 -0
  33. package/dist/client/api.js +96 -0
  34. package/dist/client/api.js.map +1 -0
  35. package/dist/client/auth.d.ts +48 -0
  36. package/dist/client/auth.d.ts.map +1 -0
  37. package/dist/client/auth.js +165 -0
  38. package/dist/client/auth.js.map +1 -0
  39. package/dist/client/error.d.ts +22 -0
  40. package/dist/client/error.d.ts.map +1 -0
  41. package/dist/client/error.js +57 -0
  42. package/dist/client/error.js.map +1 -0
  43. package/dist/client/http.d.ts +31 -0
  44. package/dist/client/http.d.ts.map +1 -0
  45. package/dist/client/http.js +97 -0
  46. package/dist/client/http.js.map +1 -0
  47. package/dist/client/lock.d.ts +40 -0
  48. package/dist/client/lock.d.ts.map +1 -0
  49. package/dist/client/lock.js +104 -0
  50. package/dist/client/lock.js.map +1 -0
  51. package/dist/client/mapper.d.ts +37 -0
  52. package/dist/client/mapper.d.ts.map +1 -0
  53. package/dist/client/mapper.js +142 -0
  54. package/dist/client/mapper.js.map +1 -0
  55. package/dist/client/portable-text.d.ts +94 -0
  56. package/dist/client/portable-text.d.ts.map +1 -0
  57. package/dist/client/portable-text.js +428 -0
  58. package/dist/client/portable-text.js.map +1 -0
  59. package/dist/client/schemas.d.ts +1928 -0
  60. package/dist/client/schemas.d.ts.map +1 -0
  61. package/dist/client/schemas.js +123 -0
  62. package/dist/client/schemas.js.map +1 -0
  63. package/dist/db/cache.d.ts +60 -0
  64. package/dist/db/cache.d.ts.map +1 -0
  65. package/dist/db/cache.js +303 -0
  66. package/dist/db/cache.js.map +1 -0
  67. package/dist/index.d.ts +24 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +45 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/mcp/context.d.ts +14 -0
  72. package/dist/mcp/context.d.ts.map +1 -0
  73. package/dist/mcp/context.js +23 -0
  74. package/dist/mcp/context.js.map +1 -0
  75. package/dist/mcp/server.d.ts +12 -0
  76. package/dist/mcp/server.d.ts.map +1 -0
  77. package/dist/mcp/server.js +106 -0
  78. package/dist/mcp/server.js.map +1 -0
  79. package/dist/mcp/tools/profile.d.ts +6 -0
  80. package/dist/mcp/tools/profile.d.ts.map +1 -0
  81. package/dist/mcp/tools/profile.js +81 -0
  82. package/dist/mcp/tools/profile.js.map +1 -0
  83. package/dist/mcp/tools/sync-diff.d.ts +4 -0
  84. package/dist/mcp/tools/sync-diff.d.ts.map +1 -0
  85. package/dist/mcp/tools/sync-diff.js +115 -0
  86. package/dist/mcp/tools/sync-diff.js.map +1 -0
  87. package/dist/mcp/tools/sync-new.d.ts +4 -0
  88. package/dist/mcp/tools/sync-new.d.ts.map +1 -0
  89. package/dist/mcp/tools/sync-new.js +54 -0
  90. package/dist/mcp/tools/sync-new.js.map +1 -0
  91. package/dist/mcp/tools/sync-pull.d.ts +4 -0
  92. package/dist/mcp/tools/sync-pull.d.ts.map +1 -0
  93. package/dist/mcp/tools/sync-pull.js +180 -0
  94. package/dist/mcp/tools/sync-pull.js.map +1 -0
  95. package/dist/mcp/tools/sync-push.d.ts +4 -0
  96. package/dist/mcp/tools/sync-push.d.ts.map +1 -0
  97. package/dist/mcp/tools/sync-push.js +105 -0
  98. package/dist/mcp/tools/sync-push.js.map +1 -0
  99. package/dist/mcp/tools/sync-status.d.ts +4 -0
  100. package/dist/mcp/tools/sync-status.d.ts.map +1 -0
  101. package/dist/mcp/tools/sync-status.js +45 -0
  102. package/dist/mcp/tools/sync-status.js.map +1 -0
  103. package/dist/sync/bylines.d.ts +23 -0
  104. package/dist/sync/bylines.d.ts.map +1 -0
  105. package/dist/sync/bylines.js +112 -0
  106. package/dist/sync/bylines.js.map +1 -0
  107. package/dist/sync/diff.d.ts +16 -0
  108. package/dist/sync/diff.d.ts.map +1 -0
  109. package/dist/sync/diff.js +68 -0
  110. package/dist/sync/diff.js.map +1 -0
  111. package/dist/sync/media.d.ts +37 -0
  112. package/dist/sync/media.d.ts.map +1 -0
  113. package/dist/sync/media.js +191 -0
  114. package/dist/sync/media.js.map +1 -0
  115. package/dist/sync/merge.d.ts +36 -0
  116. package/dist/sync/merge.d.ts.map +1 -0
  117. package/dist/sync/merge.js +112 -0
  118. package/dist/sync/merge.js.map +1 -0
  119. package/dist/sync/new.d.ts +24 -0
  120. package/dist/sync/new.d.ts.map +1 -0
  121. package/dist/sync/new.js +75 -0
  122. package/dist/sync/new.js.map +1 -0
  123. package/dist/sync/orchestrator.d.ts +55 -0
  124. package/dist/sync/orchestrator.d.ts.map +1 -0
  125. package/dist/sync/orchestrator.js +222 -0
  126. package/dist/sync/orchestrator.js.map +1 -0
  127. package/dist/sync/preflight.d.ts +25 -0
  128. package/dist/sync/preflight.d.ts.map +1 -0
  129. package/dist/sync/preflight.js +128 -0
  130. package/dist/sync/preflight.js.map +1 -0
  131. package/dist/sync/pull.d.ts +67 -0
  132. package/dist/sync/pull.d.ts.map +1 -0
  133. package/dist/sync/pull.js +405 -0
  134. package/dist/sync/pull.js.map +1 -0
  135. package/dist/sync/push.d.ts +33 -0
  136. package/dist/sync/push.d.ts.map +1 -0
  137. package/dist/sync/push.js +432 -0
  138. package/dist/sync/push.js.map +1 -0
  139. package/dist/sync/status.d.ts +24 -0
  140. package/dist/sync/status.d.ts.map +1 -0
  141. package/dist/sync/status.js +85 -0
  142. package/dist/sync/status.js.map +1 -0
  143. package/dist/sync/taxonomies.d.ts +49 -0
  144. package/dist/sync/taxonomies.d.ts.map +1 -0
  145. package/dist/sync/taxonomies.js +220 -0
  146. package/dist/sync/taxonomies.js.map +1 -0
  147. package/dist/utils/config.d.ts +18 -0
  148. package/dist/utils/config.d.ts.map +1 -0
  149. package/dist/utils/config.js +79 -0
  150. package/dist/utils/config.js.map +1 -0
  151. package/dist/utils/frontmatter.d.ts +115 -0
  152. package/dist/utils/frontmatter.d.ts.map +1 -0
  153. package/dist/utils/frontmatter.js +147 -0
  154. package/dist/utils/frontmatter.js.map +1 -0
  155. package/dist/utils/naming.d.ts +28 -0
  156. package/dist/utils/naming.d.ts.map +1 -0
  157. package/dist/utils/naming.js +94 -0
  158. package/dist/utils/naming.js.map +1 -0
  159. package/dist/utils/profile.d.ts +72 -0
  160. package/dist/utils/profile.d.ts.map +1 -0
  161. package/dist/utils/profile.js +180 -0
  162. package/dist/utils/profile.js.map +1 -0
  163. package/dist/utils/version.d.ts +5 -0
  164. package/dist/utils/version.d.ts.map +1 -0
  165. package/dist/utils/version.js +43 -0
  166. package/dist/utils/version.js.map +1 -0
  167. package/dist/utils/workspace.d.ts +22 -0
  168. package/dist/utils/workspace.d.ts.map +1 -0
  169. package/dist/utils/workspace.js +74 -0
  170. package/dist/utils/workspace.js.map +1 -0
  171. package/package.json +68 -4
@@ -0,0 +1,100 @@
1
+ /*
2
+ * Copyright (C) 2026 SPORT-SERVICE RS★R
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { getWorkspaceStatus } from '../../sync/status.js';
23
+ export function registerStatusInitCommands(program, resolveContext) {
24
+ // emit status
25
+ program
26
+ .command('status')
27
+ .description('Show sync status of articles in local workspace')
28
+ .option('-c, --collection <collection>', 'Collection to check (default: posts)')
29
+ .option('-p, --profile <name>', 'Explicitly use a specific connection profile')
30
+ .action((options) => {
31
+ const ctx = resolveContext(options.profile);
32
+ const collection = options.collection || ctx.config.defaultCollection;
33
+ const status = getWorkspaceStatus(ctx.root, ctx.cache, collection);
34
+ console.log(`\n--- Workspace Status (${collection} | origin: ${ctx.origin}) ---`);
35
+ for (const item of status.items) {
36
+ let icon = '🟢';
37
+ let label = 'synced ';
38
+ if (item.syncStatus === 'modified') {
39
+ icon = '🟡';
40
+ label = 'modified';
41
+ }
42
+ else if (item.syncStatus === 'untracked') {
43
+ icon = '⚪';
44
+ label = 'untracked';
45
+ }
46
+ const titleDisplay = item.title ? ` (${item.title})` : '';
47
+ const paddedStatus = (item.status || '').padEnd(9, ' ');
48
+ console.log(` ${icon} [${label}] ${paddedStatus} ${item.filePath}${titleDisplay}`);
49
+ }
50
+ console.log(`\nSummary: ${status.summary.total} total (${status.summary.synced} synced, ${status.summary.modified} modified, ${status.summary.untracked} untracked)\n`);
51
+ });
52
+ // emit guide
53
+ program
54
+ .command('guide')
55
+ .description('Display the Golden Path workflow and tips for humans & AI')
56
+ .action(() => {
57
+ console.log(`
58
+ ========================================================================
59
+ Emit - The Golden Path Workflow for Humans & AI
60
+ ========================================================================
61
+
62
+ ■ 4-Step Article Authoring Flow
63
+ 1. Scaffold: emit new <slug> --title "Article Title"
64
+ --> Automatically generates posts/draft/<yyyyMMdd>_<ulid>-<title>.md
65
+ 2. Write & Edit: Freely edit posts/draft/*.md with editor or AI.
66
+ --> No need to write a redundant # Title header in the body.
67
+ --> Reference frontmatter taxonomies for categories and tags.
68
+ 3. Push Draft: emit push <file>
69
+ --> Safely syncs to EmDash remote as staged draft.
70
+ 4. Publish Live: Update frontmatter status to "published", then run:
71
+ emit push <file> --allow-publish
72
+
73
+ ■ Handy Commands
74
+ - emit status ... View local editing status and diff against remote
75
+ - emit pull [id] ... Sync remote content into local workspace window
76
+ - emit mcp ... Launch stdio MCP server for AI agents (Antigravity, Claude Code)
77
+
78
+ ■ Collaboration Rules with AI (AGENTS.md)
79
+ - Strict prohibition against creating throwaway temporary files (e.g. temp.md).
80
+ - Never manually rename (mv) cached files; update the frontmatter slug/status instead.
81
+ ========================================================================
82
+ `);
83
+ });
84
+ // emit init
85
+ program
86
+ .command('init')
87
+ .description('Initialize current directory as an Emit local workspace')
88
+ .option('--origin <url>', 'EmDash instance origin URL')
89
+ .action(async (options) => {
90
+ const root = process.cwd();
91
+ const { initWorkspace } = await import('../../utils/config.js');
92
+ const { getWorkspacePaths } = await import('../../utils/workspace.js');
93
+ initWorkspace(root, options.origin ? { origin: options.origin } : undefined);
94
+ const paths = getWorkspacePaths(root);
95
+ console.log(`✅ Initialized Emit workspace at: ${root}`);
96
+ console.log(` Config: ${paths.configPath}`);
97
+ console.log(` Database: ${paths.dbPath}`);
98
+ });
99
+ }
100
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { CacheDatabase } from '../db/cache.js';
2
+ import { type ResolvedAuth } from '../client/auth.js';
3
+ import { type WorkspacePaths } from '../utils/workspace.js';
4
+ import { type EmitConfig } from '../utils/config.js';
5
+ export interface CliContext {
6
+ root: string;
7
+ paths: WorkspacePaths;
8
+ cache: CacheDatabase;
9
+ config: EmitConfig;
10
+ auth: ResolvedAuth;
11
+ origin: string;
12
+ }
13
+ export type CliContextResolver = (profileName?: string) => CliContext;
14
+ export declare function createCliContextResolver(): CliContextResolver;
15
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGjE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;AAEtE,wBAAgB,wBAAwB,IAAI,kBAAkB,CAiD7D"}
@@ -0,0 +1,75 @@
1
+ /*
2
+ * Copyright (C) 2026 SPORT-SERVICE RS★R
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { CacheDatabase } from '../db/cache.js';
23
+ import { resolveAuth } from '../client/auth.js';
24
+ import { getWorkspacePaths, requireWorkspaceRoot, } from '../utils/workspace.js';
25
+ import { loadConfig } from '../utils/config.js';
26
+ import { loadProfilesFile, AmbiguousProfileError } from '../utils/profile.js';
27
+ export function createCliContextResolver() {
28
+ return (profileName) => {
29
+ let auth;
30
+ try {
31
+ const resolved = resolveAuth({ profile: profileName });
32
+ if (!resolved) {
33
+ console.error('❌ Error: No authentication found.');
34
+ console.error(' Please run "emit profile add <name> --origin <url> --token <token>"');
35
+ console.error(' or set EMDASH_TOKEN environment variable.');
36
+ process.exit(1);
37
+ }
38
+ auth = resolved;
39
+ }
40
+ catch (err) {
41
+ if (err instanceof AmbiguousProfileError) {
42
+ console.error(`\n❌ Error: ${err.message}`);
43
+ console.error(' Please specify a profile with --profile <name>.');
44
+ console.error(` Available profiles: ${err.availableProfiles.join(', ')}\n`);
45
+ process.exit(1);
46
+ }
47
+ throw err;
48
+ }
49
+ const profilesData = loadProfilesFile();
50
+ const activeProf = profileName ? profilesData.profiles[profileName] : undefined;
51
+ const origin = activeProf?.origin || auth.origin || 'https://example.com';
52
+ let workspaceRoot;
53
+ try {
54
+ workspaceRoot =
55
+ activeProf?.workspace || process.env.EMDASH_WORKSPACE || requireWorkspaceRoot();
56
+ }
57
+ catch {
58
+ console.error('❌ Error: Current directory is not inside an Emit workspace.');
59
+ console.error(' Run "emit init" to initialize this directory, or "cd" into a workspace.');
60
+ process.exit(1);
61
+ }
62
+ const paths = getWorkspacePaths(workspaceRoot);
63
+ const cache = new CacheDatabase(paths.dbPath);
64
+ const config = loadConfig(paths.configPath);
65
+ return {
66
+ root: workspaceRoot,
67
+ paths,
68
+ cache,
69
+ config,
70
+ auth,
71
+ origin,
72
+ };
73
+ };
74
+ }
75
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAqB,MAAM,mBAAmB,CAAC;AACnE,OAAO,EACL,iBAAiB,EACjB,oBAAoB,GAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAmB,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAa9E,MAAM,UAAU,wBAAwB;IACtC,OAAO,CAAC,WAAoB,EAAc,EAAE;QAC1C,IAAI,IAAkB,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;YACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;gBACnD,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;gBACxF,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;gBAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,IAAI,GAAG,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;gBACzC,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC3C,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;gBACpE,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,MAAM,YAAY,GAAG,gBAAgB,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChF,MAAM,MAAM,GAAG,UAAU,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,qBAAqB,CAAC;QAE1E,IAAI,aAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,aAAa;gBACX,UAAU,EAAE,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,oBAAoB,EAAE,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;YAC7E,OAAO,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAC;YAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,KAAK,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAE5C,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,KAAK;YACL,KAAK;YACL,MAAM;YACN,IAAI;YACJ,MAAM;SACP,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ export interface UnwrappedEnvelope<T = Record<string, unknown>> {
2
+ data: T;
3
+ rev: string;
4
+ }
5
+ /**
6
+ * Validates and safely extracts the primary data object from an API response envelope.
7
+ * Handles { success: true, data: T } or plain T responses.
8
+ * Note: If raw itself has an `id` field (already an item), do not unwrap `raw.data` (which is content data).
9
+ */
10
+ export declare function unwrapEnvelope<T = Record<string, unknown>>(raw: unknown): T;
11
+ /**
12
+ * Validates and safely extracts the item from a response or nested envelope ({ item: T }, { data: { item: T } } or T).
13
+ */
14
+ export declare function unwrapItem<T = Record<string, unknown>>(raw: unknown): T;
15
+ /**
16
+ * Extracts revision string from an API response, prioritizing data._rev over item._rev, rev, version.
17
+ */
18
+ export declare function extractRev(raw: unknown, fallback?: string): string;
19
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/client/api.ts"],"names":[],"mappings":"AAiCA,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5D,IAAI,EAAE,CAAC,CAAC;IACR,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,CAAC,CAiB3E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,CAAC,CA6BvE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,SAAM,GAAG,MAAM,CAmB/D"}
@@ -0,0 +1,96 @@
1
+ /*
2
+ * Copyright (C) 2026 SPORT-SERVICE RS★R
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ /**
23
+ * Safe unwrap utilities for EmDash API response envelopes and revision extraction.
24
+ */
25
+ import { ContentEnvelopeSchema, ContentItemSchema, } from './schemas.js';
26
+ /**
27
+ * Validates and safely extracts the primary data object from an API response envelope.
28
+ * Handles { success: true, data: T } or plain T responses.
29
+ * Note: If raw itself has an `id` field (already an item), do not unwrap `raw.data` (which is content data).
30
+ */
31
+ export function unwrapEnvelope(raw) {
32
+ if (!raw || typeof raw !== 'object') {
33
+ return {};
34
+ }
35
+ // Parse against envelope schema if possible
36
+ const parsedEnvelope = ContentEnvelopeSchema.safeParse(raw);
37
+ const obj = (parsedEnvelope.success ? parsedEnvelope.data : raw);
38
+ if ('data' in obj && obj.data && typeof obj.data === 'object' && !Array.isArray(obj.data)) {
39
+ // If obj already has top-level `id` or `slug`, obj is already the content item, not an API envelope!
40
+ if ('id' in obj || 'slug' in obj) {
41
+ return obj;
42
+ }
43
+ return obj.data;
44
+ }
45
+ return obj;
46
+ }
47
+ /**
48
+ * Validates and safely extracts the item from a response or nested envelope ({ item: T }, { data: { item: T } } or T).
49
+ */
50
+ export function unwrapItem(raw) {
51
+ if (!raw || typeof raw !== 'object') {
52
+ return {};
53
+ }
54
+ const parsedEnvelope = ContentEnvelopeSchema.safeParse(raw);
55
+ const root = (parsedEnvelope.success ? parsedEnvelope.data : raw);
56
+ // If root has data.item
57
+ if (root.data && typeof root.data === 'object' && !Array.isArray(root.data)) {
58
+ const dataObj = root.data;
59
+ if (dataObj.item && typeof dataObj.item === 'object') {
60
+ const parsedItem = ContentItemSchema.safeParse(dataObj.item);
61
+ return (parsedItem.success ? parsedItem.data : dataObj.item);
62
+ }
63
+ if (dataObj.id) {
64
+ const parsedItem = ContentItemSchema.safeParse(dataObj);
65
+ return (parsedItem.success ? parsedItem.data : dataObj);
66
+ }
67
+ }
68
+ // If root has item
69
+ if (root.item && typeof root.item === 'object') {
70
+ const parsedItem = ContentItemSchema.safeParse(root.item);
71
+ return (parsedItem.success ? parsedItem.data : root.item);
72
+ }
73
+ const parsedItem = ContentItemSchema.safeParse(root);
74
+ return (parsedItem.success ? parsedItem.data : root);
75
+ }
76
+ /**
77
+ * Extracts revision string from an API response, prioritizing data._rev over item._rev, rev, version.
78
+ */
79
+ export function extractRev(raw, fallback = '1') {
80
+ if (!raw || typeof raw !== 'object') {
81
+ return fallback;
82
+ }
83
+ const root = raw;
84
+ let envelopeRev = '';
85
+ if (root.data && typeof root.data === 'object' && !Array.isArray(root.data)) {
86
+ const dataObj = root.data;
87
+ if (dataObj._rev)
88
+ envelopeRev = String(dataObj._rev);
89
+ else if (dataObj.rev)
90
+ envelopeRev = String(dataObj.rev);
91
+ }
92
+ const item = unwrapItem(raw);
93
+ const rev = item._rev || envelopeRev || root._rev || item.rev || root.rev || item.version || root.version;
94
+ return rev ? String(rev) : fallback;
95
+ }
96
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/client/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;GAEG;AAEH,OAAO,EACL,qBAAqB,EACrB,iBAAiB,GAGlB,MAAM,cAAc,CAAC;AAOtB;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAA8B,GAAY;IACtE,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,EAAO,CAAC;IACjB,CAAC;IAED,4CAA4C;IAC5C,MAAM,cAAc,GAAG,qBAAqB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAA4B,CAAC;IAE5F,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1F,qGAAqG;QACrG,IAAI,IAAI,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YACjC,OAAO,GAAQ,CAAC;QAClB,CAAC;QACD,OAAO,GAAG,CAAC,IAAS,CAAC;IACvB,CAAC;IACD,OAAO,GAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAA8B,GAAY;IAClE,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,EAAO,CAAC;IACjB,CAAC;IAED,MAAM,cAAc,GAAG,qBAAqB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAA4B,CAAC;IAE7F,wBAAwB;IACxB,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,IAA+B,CAAC;QACrD,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7D,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAM,CAAC;QACpE,CAAC;QACD,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACxD,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAM,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC/C,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAM,CAAC;IACjE,CAAC;IAED,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrD,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAM,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAY,EAAE,QAAQ,GAAG,GAAG;IACrD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,GAA8B,CAAC;IAC5C,IAAI,WAAW,GAAG,EAAE,CAAC;IAErB,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,IAA+B,CAAC;QACrD,IAAI,OAAO,CAAC,IAAI;YAAE,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;aAChD,IAAI,OAAO,CAAC,GAAG;YAAE,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,CAA0B,GAAG,CAAC,CAAC;IACtD,MAAM,GAAG,GACP,IAAI,CAAC,IAAI,IAAI,WAAW,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;IAEhG,OAAO,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AACtC,CAAC"}
@@ -0,0 +1,48 @@
1
+ export interface EmDashAuthData {
2
+ origin?: string;
3
+ access_token: string;
4
+ refresh_token?: string;
5
+ tokenScopes?: string[];
6
+ expires_at?: number;
7
+ }
8
+ export interface ResolvedAuth {
9
+ source: 'env' | 'profile' | 'emdash-cli' | 'emit-config';
10
+ token: string;
11
+ origin?: string;
12
+ refreshToken?: string;
13
+ scopes?: string[];
14
+ profileName?: string;
15
+ workspace?: string;
16
+ }
17
+ export interface AuthOptions {
18
+ profile?: string;
19
+ cwd?: string;
20
+ customProfilesPath?: string;
21
+ customConfigPath?: string;
22
+ emdashAuthPath?: string;
23
+ }
24
+ /**
25
+ * Resolves default path for EmDash CLI auth storage (~/.config/emdash/auth.json).
26
+ */
27
+ export declare function getDefaultEmDashAuthPath(): string;
28
+ /**
29
+ * Resolves default path for Emit custom credentials (~/.config/emit/credentials.json).
30
+ */
31
+ export declare function getDefaultEmitCredentialsPath(): string;
32
+ /**
33
+ * Resolves authentication credentials with prioritized fallback:
34
+ * 1. Environment variables (EMDASH_TOKEN or EMDASH_API_TOKEN) -> Top priority for CI / one-off overrides
35
+ * 2. Profile from ~/.config/emit/profiles.yaml (explicit profile, or workspace directory match, or single site)
36
+ * 3. EmDash CLI credentials (~/.config/emdash/auth.json)
37
+ * 4. Emit custom credentials (~/.config/emit/credentials.json)
38
+ */
39
+ export declare function resolveAuth(options?: AuthOptions): ResolvedAuth | null;
40
+ /**
41
+ * Validates whether the token has the required scope.
42
+ */
43
+ export declare function hasRequiredScope(scopes: string[] | undefined, requiredScope: string): boolean;
44
+ /**
45
+ * Refreshes an expired OAuth access token using its refresh_token.
46
+ */
47
+ export declare function refreshAccessToken(auth: ResolvedAuth, authFilePath?: string, fetchFn?: typeof fetch): Promise<ResolvedAuth>;
48
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,KAAK,GAAG,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CAEtD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG,IAAI,CAqEtE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAM7F;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,YAAY,EAClB,YAAY,GAAE,MAAmC,EACjD,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,YAAY,CAAC,CAkDvB"}
@@ -0,0 +1,165 @@
1
+ /*
2
+ * Copyright (C) 2026 SPORT-SERVICE RS★R
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import fs from 'node:fs';
23
+ import os from 'node:os';
24
+ import path from 'node:path';
25
+ import { resolveTargetProfile } from '../utils/profile.js';
26
+ /**
27
+ * Resolves default path for EmDash CLI auth storage (~/.config/emdash/auth.json).
28
+ */
29
+ export function getDefaultEmDashAuthPath() {
30
+ return path.join(os.homedir(), '.config', 'emdash', 'auth.json');
31
+ }
32
+ /**
33
+ * Resolves default path for Emit custom credentials (~/.config/emit/credentials.json).
34
+ */
35
+ export function getDefaultEmitCredentialsPath() {
36
+ return path.join(os.homedir(), '.config', 'emit', 'credentials.json');
37
+ }
38
+ /**
39
+ * Resolves authentication credentials with prioritized fallback:
40
+ * 1. Environment variables (EMDASH_TOKEN or EMDASH_API_TOKEN) -> Top priority for CI / one-off overrides
41
+ * 2. Profile from ~/.config/emit/profiles.yaml (explicit profile, or workspace directory match, or single site)
42
+ * 3. EmDash CLI credentials (~/.config/emdash/auth.json)
43
+ * 4. Emit custom credentials (~/.config/emit/credentials.json)
44
+ */
45
+ export function resolveAuth(options) {
46
+ // 1. Environment variables (highest priority for overrides/CI)
47
+ const envToken = process.env.EMDASH_TOKEN || process.env.EMDASH_API_TOKEN;
48
+ if (envToken) {
49
+ return {
50
+ source: 'env',
51
+ token: envToken,
52
+ origin: process.env.EMDASH_ORIGIN,
53
+ };
54
+ }
55
+ // 2. Profile from ~/.config/emit/profiles.yaml (may throw AmbiguousProfileError if multiple sites)
56
+ const profileRes = resolveTargetProfile({
57
+ profile: options?.profile,
58
+ cwd: options?.cwd,
59
+ customPath: options?.customProfilesPath,
60
+ });
61
+ if (profileRes && profileRes.config.token) {
62
+ return {
63
+ source: 'profile',
64
+ token: profileRes.config.token,
65
+ origin: profileRes.config.origin,
66
+ profileName: profileRes.name,
67
+ workspace: profileRes.config.workspace,
68
+ };
69
+ }
70
+ // 3. EmDash CLI auth.json
71
+ const emdashPath = options?.emdashAuthPath || getDefaultEmDashAuthPath();
72
+ if (fs.existsSync(emdashPath)) {
73
+ try {
74
+ const raw = fs.readFileSync(emdashPath, 'utf8');
75
+ const data = JSON.parse(raw);
76
+ if (data.access_token) {
77
+ return {
78
+ source: 'emdash-cli',
79
+ token: data.access_token,
80
+ origin: data.origin,
81
+ refreshToken: data.refresh_token,
82
+ scopes: data.tokenScopes,
83
+ };
84
+ }
85
+ }
86
+ catch {
87
+ // Ignore parse/read failure, try next tier
88
+ }
89
+ }
90
+ // 4. Emit credentials.json
91
+ const emitPath = options?.customConfigPath || getDefaultEmitCredentialsPath();
92
+ if (fs.existsSync(emitPath)) {
93
+ try {
94
+ const raw = fs.readFileSync(emitPath, 'utf8');
95
+ const data = JSON.parse(raw);
96
+ if (data.access_token) {
97
+ return {
98
+ source: 'emit-config',
99
+ token: data.access_token,
100
+ origin: data.origin,
101
+ refreshToken: data.refresh_token,
102
+ scopes: data.tokenScopes,
103
+ };
104
+ }
105
+ }
106
+ catch {
107
+ // Ignore parse/read failure
108
+ }
109
+ }
110
+ return null;
111
+ }
112
+ /**
113
+ * Validates whether the token has the required scope.
114
+ */
115
+ export function hasRequiredScope(scopes, requiredScope) {
116
+ if (!scopes || scopes.length === 0) {
117
+ // If scopes are not declared, assume allowed until API returns 403
118
+ return true;
119
+ }
120
+ return scopes.includes(requiredScope) || scopes.includes('*') || scopes.includes('admin');
121
+ }
122
+ /**
123
+ * Refreshes an expired OAuth access token using its refresh_token.
124
+ */
125
+ export async function refreshAccessToken(auth, authFilePath = getDefaultEmDashAuthPath(), fetchFn = fetch) {
126
+ if (!auth.refreshToken || !auth.origin) {
127
+ throw new Error('Cannot refresh token: missing refresh_token or origin. Please run "emdash login" again.');
128
+ }
129
+ const tokenUrl = new URL('/_emdash/api/auth/token', auth.origin).toString();
130
+ const res = await fetchFn(tokenUrl, {
131
+ method: 'POST',
132
+ headers: { 'Content-Type': 'application/json' },
133
+ body: JSON.stringify({
134
+ grant_type: 'refresh_token',
135
+ refresh_token: auth.refreshToken,
136
+ }),
137
+ });
138
+ if (!res.ok) {
139
+ throw new Error(`Token refresh failed with status ${res.status}. Please run "emdash login" to re-authenticate.`);
140
+ }
141
+ const json = (await res.json());
142
+ const updatedAuth = {
143
+ ...auth,
144
+ token: json.access_token,
145
+ refreshToken: json.refresh_token || auth.refreshToken,
146
+ scopes: json.tokenScopes || auth.scopes,
147
+ };
148
+ // Persist updated token to auth file if it originated from emdash-cli
149
+ if (auth.source === 'emdash-cli' && fs.existsSync(authFilePath)) {
150
+ try {
151
+ const current = JSON.parse(fs.readFileSync(authFilePath, 'utf8'));
152
+ current.access_token = updatedAuth.token;
153
+ if (json.refresh_token)
154
+ current.refresh_token = json.refresh_token;
155
+ if (json.tokenScopes)
156
+ current.tokenScopes = json.tokenScopes;
157
+ fs.writeFileSync(authFilePath, JSON.stringify(current, null, 2), 'utf8');
158
+ }
159
+ catch {
160
+ // Failed to persist, continue with in-memory token
161
+ }
162
+ }
163
+ return updatedAuth;
164
+ }
165
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Structured API Error class representing failed EmDash API operations.
3
+ * Carries HTTP status, internal error code, and actionable suggestions for user or AI recovery (G8).
4
+ */
5
+ export declare class ApiError extends Error {
6
+ readonly code: string;
7
+ readonly status?: number;
8
+ readonly suggestion?: string;
9
+ readonly endpoint?: string;
10
+ constructor(options: {
11
+ message: string;
12
+ code: string;
13
+ status?: number;
14
+ suggestion?: string;
15
+ endpoint?: string;
16
+ });
17
+ /**
18
+ * Formats the error into an actionable message suitable for console or MCP tool output.
19
+ */
20
+ toActionableString(): string;
21
+ }
22
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/client/error.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChC,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpC,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElC,YAAY,OAAO,EAAE;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,EAYA;IAED;;OAEG;IACI,kBAAkB,IAAI,MAAM,CAMlC;CACF"}
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright (C) 2026 SPORT-SERVICE RS★R
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ /**
23
+ * Structured API Error class representing failed EmDash API operations.
24
+ * Carries HTTP status, internal error code, and actionable suggestions for user or AI recovery (G8).
25
+ */
26
+ export class ApiError extends Error {
27
+ code;
28
+ status;
29
+ suggestion;
30
+ endpoint;
31
+ constructor(options) {
32
+ super(options.message);
33
+ this.name = 'ApiError';
34
+ this.code = options.code;
35
+ this.status = options.status;
36
+ this.suggestion = options.suggestion;
37
+ this.endpoint = options.endpoint;
38
+ // Maintains proper stack trace in V8 / Node.js
39
+ if (Error.captureStackTrace) {
40
+ Error.captureStackTrace(this, ApiError);
41
+ }
42
+ }
43
+ /**
44
+ * Formats the error into an actionable message suitable for console or MCP tool output.
45
+ */
46
+ toActionableString() {
47
+ const lines = [`❌ [${this.code}] ${this.message}`];
48
+ if (this.status)
49
+ lines.push(` Status: HTTP ${this.status}`);
50
+ if (this.endpoint)
51
+ lines.push(` Endpoint: ${this.endpoint}`);
52
+ if (this.suggestion)
53
+ lines.push(` 💡 Suggestion: ${this.suggestion}`);
54
+ return lines.join('\n');
55
+ }
56
+ }
57
+ //# sourceMappingURL=error.js.map