@tickernelz/paperclip-pro-adapter-claude-local 2026.925.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 (206) hide show
  1. package/LICENSE +22 -0
  2. package/dist/cli/format-event.d.ts +2 -0
  3. package/dist/cli/format-event.d.ts.map +1 -0
  4. package/dist/cli/format-event.js +141 -0
  5. package/dist/cli/format-event.js.map +1 -0
  6. package/dist/cli/index.d.ts +2 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +2 -0
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/cli/quota-probe.d.ts +3 -0
  11. package/dist/cli/quota-probe.d.ts.map +1 -0
  12. package/dist/cli/quota-probe.js +106 -0
  13. package/dist/cli/quota-probe.js.map +1 -0
  14. package/dist/index.d.ts +13 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +90 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/index.test.d.ts +2 -0
  19. package/dist/index.test.d.ts.map +1 -0
  20. package/dist/index.test.js +35 -0
  21. package/dist/index.test.js.map +1 -0
  22. package/dist/server/acp.auth.test.d.ts +2 -0
  23. package/dist/server/acp.auth.test.d.ts.map +1 -0
  24. package/dist/server/acp.auth.test.js +581 -0
  25. package/dist/server/acp.auth.test.js.map +1 -0
  26. package/dist/server/acp.d.ts +68 -0
  27. package/dist/server/acp.d.ts.map +1 -0
  28. package/dist/server/acp.js +779 -0
  29. package/dist/server/acp.js.map +1 -0
  30. package/dist/server/acp.quota.test.d.ts +2 -0
  31. package/dist/server/acp.quota.test.d.ts.map +1 -0
  32. package/dist/server/acp.quota.test.js +114 -0
  33. package/dist/server/acp.quota.test.js.map +1 -0
  34. package/dist/server/acp.test.d.ts +2 -0
  35. package/dist/server/acp.test.d.ts.map +1 -0
  36. package/dist/server/acp.test.js +1153 -0
  37. package/dist/server/acp.test.js.map +1 -0
  38. package/dist/server/auth-check.d.ts +8 -0
  39. package/dist/server/auth-check.d.ts.map +1 -0
  40. package/dist/server/auth-check.js +8 -0
  41. package/dist/server/auth-check.js.map +1 -0
  42. package/dist/server/claude-config.d.ts +49 -0
  43. package/dist/server/claude-config.d.ts.map +1 -0
  44. package/dist/server/claude-config.js +279 -0
  45. package/dist/server/claude-config.js.map +1 -0
  46. package/dist/server/claude-config.test.d.ts +2 -0
  47. package/dist/server/claude-config.test.d.ts.map +1 -0
  48. package/dist/server/claude-config.test.js +197 -0
  49. package/dist/server/claude-config.test.js.map +1 -0
  50. package/dist/server/cli-capabilities.d.ts +26 -0
  51. package/dist/server/cli-capabilities.d.ts.map +1 -0
  52. package/dist/server/cli-capabilities.js +115 -0
  53. package/dist/server/cli-capabilities.js.map +1 -0
  54. package/dist/server/config-schema.d.ts +3 -0
  55. package/dist/server/config-schema.d.ts.map +1 -0
  56. package/dist/server/config-schema.js +67 -0
  57. package/dist/server/config-schema.js.map +1 -0
  58. package/dist/server/engine-availability.test.d.ts +2 -0
  59. package/dist/server/engine-availability.test.d.ts.map +1 -0
  60. package/dist/server/engine-availability.test.js +41 -0
  61. package/dist/server/engine-availability.test.js.map +1 -0
  62. package/dist/server/execute.acp-fallback.test.d.ts +2 -0
  63. package/dist/server/execute.acp-fallback.test.d.ts.map +1 -0
  64. package/dist/server/execute.acp-fallback.test.js +104 -0
  65. package/dist/server/execute.acp-fallback.test.js.map +1 -0
  66. package/dist/server/execute.d.ts +23 -0
  67. package/dist/server/execute.d.ts.map +1 -0
  68. package/dist/server/execute.js +1089 -0
  69. package/dist/server/execute.js.map +1 -0
  70. package/dist/server/execute.remote.test.d.ts +2 -0
  71. package/dist/server/execute.remote.test.d.ts.map +1 -0
  72. package/dist/server/execute.remote.test.js +484 -0
  73. package/dist/server/execute.remote.test.js.map +1 -0
  74. package/dist/server/index.d.ts +16 -0
  75. package/dist/server/index.d.ts.map +1 -0
  76. package/dist/server/index.js +84 -0
  77. package/dist/server/index.js.map +1 -0
  78. package/dist/server/models.d.ts +13 -0
  79. package/dist/server/models.d.ts.map +1 -0
  80. package/dist/server/models.js +153 -0
  81. package/dist/server/models.js.map +1 -0
  82. package/dist/server/parse.d.ts +58 -0
  83. package/dist/server/parse.d.ts.map +1 -0
  84. package/dist/server/parse.js +459 -0
  85. package/dist/server/parse.js.map +1 -0
  86. package/dist/server/parse.test.d.ts +2 -0
  87. package/dist/server/parse.test.d.ts.map +1 -0
  88. package/dist/server/parse.test.js +419 -0
  89. package/dist/server/parse.test.js.map +1 -0
  90. package/dist/server/permissions.d.ts +14 -0
  91. package/dist/server/permissions.d.ts.map +1 -0
  92. package/dist/server/permissions.js +13 -0
  93. package/dist/server/permissions.js.map +1 -0
  94. package/dist/server/permissions.test.d.ts +2 -0
  95. package/dist/server/permissions.test.d.ts.map +1 -0
  96. package/dist/server/permissions.test.js +22 -0
  97. package/dist/server/permissions.test.js.map +1 -0
  98. package/dist/server/probe-diagnostics.d.ts +102 -0
  99. package/dist/server/probe-diagnostics.d.ts.map +1 -0
  100. package/dist/server/probe-diagnostics.js +140 -0
  101. package/dist/server/probe-diagnostics.js.map +1 -0
  102. package/dist/server/probe-diagnostics.test.d.ts +2 -0
  103. package/dist/server/probe-diagnostics.test.d.ts.map +1 -0
  104. package/dist/server/probe-diagnostics.test.js +114 -0
  105. package/dist/server/probe-diagnostics.test.js.map +1 -0
  106. package/dist/server/probe-env.d.ts +42 -0
  107. package/dist/server/probe-env.d.ts.map +1 -0
  108. package/dist/server/probe-env.js +149 -0
  109. package/dist/server/probe-env.js.map +1 -0
  110. package/dist/server/probe-env.test.d.ts +2 -0
  111. package/dist/server/probe-env.test.d.ts.map +1 -0
  112. package/dist/server/probe-env.test.js +135 -0
  113. package/dist/server/probe-env.test.js.map +1 -0
  114. package/dist/server/probe-redaction.test.d.ts +2 -0
  115. package/dist/server/probe-redaction.test.d.ts.map +1 -0
  116. package/dist/server/probe-redaction.test.js +86 -0
  117. package/dist/server/probe-redaction.test.js.map +1 -0
  118. package/dist/server/prompt-cache.d.ts +17 -0
  119. package/dist/server/prompt-cache.d.ts.map +1 -0
  120. package/dist/server/prompt-cache.js +126 -0
  121. package/dist/server/prompt-cache.js.map +1 -0
  122. package/dist/server/quota-keychain.test.d.ts +2 -0
  123. package/dist/server/quota-keychain.test.d.ts.map +1 -0
  124. package/dist/server/quota-keychain.test.js +83 -0
  125. package/dist/server/quota-keychain.test.js.map +1 -0
  126. package/dist/server/quota.d.ts +30 -0
  127. package/dist/server/quota.d.ts.map +1 -0
  128. package/dist/server/quota.js +543 -0
  129. package/dist/server/quota.js.map +1 -0
  130. package/dist/server/setup-token-characterization.test.d.ts +2 -0
  131. package/dist/server/setup-token-characterization.test.d.ts.map +1 -0
  132. package/dist/server/setup-token-characterization.test.js +123 -0
  133. package/dist/server/setup-token-characterization.test.js.map +1 -0
  134. package/dist/server/setup-token-parse.d.ts +47 -0
  135. package/dist/server/setup-token-parse.d.ts.map +1 -0
  136. package/dist/server/setup-token-parse.js +506 -0
  137. package/dist/server/setup-token-parse.js.map +1 -0
  138. package/dist/server/setup-token-parse.test.d.ts +2 -0
  139. package/dist/server/setup-token-parse.test.d.ts.map +1 -0
  140. package/dist/server/setup-token-parse.test.js +587 -0
  141. package/dist/server/setup-token-parse.test.js.map +1 -0
  142. package/dist/server/setup-token-runner.d.ts +115 -0
  143. package/dist/server/setup-token-runner.d.ts.map +1 -0
  144. package/dist/server/setup-token-runner.js +317 -0
  145. package/dist/server/setup-token-runner.js.map +1 -0
  146. package/dist/server/setup-token-runner.test.d.ts +2 -0
  147. package/dist/server/setup-token-runner.test.d.ts.map +1 -0
  148. package/dist/server/setup-token-runner.test.js +336 -0
  149. package/dist/server/setup-token-runner.test.js.map +1 -0
  150. package/dist/server/skills.d.ts +8 -0
  151. package/dist/server/skills.d.ts.map +1 -0
  152. package/dist/server/skills.js +42 -0
  153. package/dist/server/skills.js.map +1 -0
  154. package/dist/server/test.d.ts +3 -0
  155. package/dist/server/test.d.ts.map +1 -0
  156. package/dist/server/test.js +434 -0
  157. package/dist/server/test.js.map +1 -0
  158. package/dist/server/test.probe.test.d.ts +2 -0
  159. package/dist/server/test.probe.test.d.ts.map +1 -0
  160. package/dist/server/test.probe.test.js +608 -0
  161. package/dist/server/test.probe.test.js.map +1 -0
  162. package/dist/server/test.remote.test.d.ts +2 -0
  163. package/dist/server/test.remote.test.d.ts.map +1 -0
  164. package/dist/server/test.remote.test.js +149 -0
  165. package/dist/server/test.remote.test.js.map +1 -0
  166. package/dist/ui/build-config.d.ts +3 -0
  167. package/dist/ui/build-config.d.ts.map +1 -0
  168. package/dist/ui/build-config.js +76 -0
  169. package/dist/ui/build-config.js.map +1 -0
  170. package/dist/ui/build-config.test.d.ts +2 -0
  171. package/dist/ui/build-config.test.d.ts.map +1 -0
  172. package/dist/ui/build-config.test.js +68 -0
  173. package/dist/ui/build-config.test.js.map +1 -0
  174. package/dist/ui/index.d.ts +3 -0
  175. package/dist/ui/index.d.ts.map +1 -0
  176. package/dist/ui/index.js +3 -0
  177. package/dist/ui/index.js.map +1 -0
  178. package/dist/ui/parse-stdout.d.ts +3 -0
  179. package/dist/ui/parse-stdout.d.ts.map +1 -0
  180. package/dist/ui/parse-stdout.js +153 -0
  181. package/dist/ui/parse-stdout.js.map +1 -0
  182. package/package.json +63 -0
  183. package/skills/agentmail/SKILL.md +70 -0
  184. package/skills/paperclip/SKILL.md +712 -0
  185. package/skills/paperclip/references/api-reference.md +1675 -0
  186. package/skills/paperclip/references/artifacts.md +158 -0
  187. package/skills/paperclip/references/cases.md +295 -0
  188. package/skills/paperclip/references/company-skills.md +266 -0
  189. package/skills/paperclip/references/issue-workspaces.md +80 -0
  190. package/skills/paperclip/references/routines.md +231 -0
  191. package/skills/paperclip/references/workflows.md +141 -0
  192. package/skills/paperclip/scripts/paperclip-upload-artifact.sh +592 -0
  193. package/skills/paperclip-board/SKILL.md +619 -0
  194. package/skills/paperclip-converting-plans-to-tasks/SKILL.md +60 -0
  195. package/skills/paperclip-create-agent/SKILL.md +179 -0
  196. package/skills/paperclip-create-agent/references/agent-instruction-templates.md +123 -0
  197. package/skills/paperclip-create-agent/references/agents/coder.md +64 -0
  198. package/skills/paperclip-create-agent/references/agents/qa.md +88 -0
  199. package/skills/paperclip-create-agent/references/agents/securityengineer.md +135 -0
  200. package/skills/paperclip-create-agent/references/agents/uxdesigner.md +115 -0
  201. package/skills/paperclip-create-agent/references/api-reference.md +110 -0
  202. package/skills/paperclip-create-agent/references/baseline-role-guide.md +168 -0
  203. package/skills/paperclip-create-agent/references/draft-review-checklist.md +95 -0
  204. package/skills/para-memory-files/SKILL.md +100 -0
  205. package/skills/para-memory-files/references/schemas.md +35 -0
  206. package/skills/slack/SKILL.md +65 -0
@@ -0,0 +1,336 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { SETUP_TOKEN_PROMPT } from "./setup-token-parse.js";
3
+ import { CLAUDE_SETUP_TOKEN_COMMAND, CLAUDE_SETUP_TOKEN_MAX_BUFFER_CHARS, CODE_SUBMISSION_TERMINATOR, runSetupTokenLogin, } from "./setup-token-runner.js";
4
+ // A well-formed authorization URL. The query keys match the contract exactly.
5
+ // The values are synthetic; no real value is present.
6
+ const VALID_URL = "https://claude.com/cai/oauth/authorize?client_id=cid&code=abcdefgh&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&redirect_uri=https%3A%2F%2Fplatform.claude.com%2Foauth%2Fcode%2Fcallback&response_type=code&scope=user&state=0123456789abcdef";
7
+ // The rendered login output. The preamble line, the URL line, and the dedicated
8
+ // prompt line match the Phase 2 parser contract.
9
+ const PROMPT_OUTPUT = [
10
+ "Welcome to Claude Code",
11
+ "Opening browser to sign in…",
12
+ "Browser didn't open? Use the url below to sign in (c to copy)",
13
+ VALID_URL,
14
+ "Paste code here if prompted >",
15
+ "",
16
+ ].join("\n");
17
+ // A synthetic browser code. No test log, result, error, or metadata field may
18
+ // contain this value.
19
+ const BROWSER_CODE = "SENTINEL-CODE-9182";
20
+ // A synthetic OAuth token, wrapped across two physical lines the way the
21
+ // terminal wraps a real token. No real token is present.
22
+ const TOKEN_FRAGMENT_A = "sk-ant-oat01-AAAABBBBCCCCDDDDEEEE1111";
23
+ const TOKEN_FRAGMENT_B = "2222FFFFGGGG_HHHH-IIII";
24
+ const FULL_TOKEN = `${TOKEN_FRAGMENT_A}${TOKEN_FRAGMENT_B}`;
25
+ // The rendered success screen. The anchor lines bracket the wrapped token, the
26
+ // same way the Phase 6a success record records them.
27
+ const SUCCESS_OUTPUT = [
28
+ "✓ Long-lived authentication token created successfully!",
29
+ "",
30
+ "Your OAuth token (valid for 1 year):",
31
+ "",
32
+ TOKEN_FRAGMENT_A,
33
+ TOKEN_FRAGMENT_B,
34
+ "",
35
+ "Store this token securely. You won't be able to see it again.",
36
+ "",
37
+ ].join("\n");
38
+ function createFakeDriver(options = {}) {
39
+ const writes = [];
40
+ const stops = { count: 0 };
41
+ const disposes = { count: 0 };
42
+ let resolveExit = () => { };
43
+ const exitPromise = new Promise((resolve) => {
44
+ resolveExit = resolve;
45
+ });
46
+ const driver = {
47
+ async start(_command, onData) {
48
+ if (options.startError)
49
+ throw options.startError;
50
+ for (const chunk of options.chunks ?? []) {
51
+ onData(chunk);
52
+ }
53
+ if (options.exitCode !== undefined) {
54
+ return { exitCode: options.exitCode };
55
+ }
56
+ return exitPromise;
57
+ },
58
+ write(input) {
59
+ writes.push(input);
60
+ },
61
+ stop() {
62
+ stops.count += 1;
63
+ },
64
+ async dispose() {
65
+ disposes.count += 1;
66
+ },
67
+ };
68
+ return { driver, writes, stops, disposes, resolveExit: (code) => resolveExit({ exitCode: code }) };
69
+ }
70
+ // Lets the pending microtasks run, so the code-input routine writes to the PTY.
71
+ async function flush() {
72
+ await new Promise((resolve) => setTimeout(resolve, 0));
73
+ }
74
+ describe("runSetupTokenLogin", () => {
75
+ it("sends one login URL through onPrompt", async () => {
76
+ // A success stream and a resolving sink, so the run reports success after the
77
+ // runner delivers the credential.
78
+ const fake = createFakeDriver({ chunks: [PROMPT_OUTPUT, SUCCESS_OUTPUT], exitCode: 0 });
79
+ const onPrompt = vi.fn();
80
+ const result = await runSetupTokenLogin(fake.driver, {
81
+ onPrompt,
82
+ provideCode: async () => BROWSER_CODE,
83
+ onCredential: async () => { },
84
+ timeoutMs: 1000,
85
+ });
86
+ expect(result.outcome).toBe("success");
87
+ expect(result.promptSurfaced).toBe(true);
88
+ expect(onPrompt).toHaveBeenCalledTimes(1);
89
+ expect(onPrompt).toHaveBeenCalledWith({ url: VALID_URL, prompt: SETUP_TOKEN_PROMPT });
90
+ });
91
+ it("accepts one browser code and sends it to the prompt", async () => {
92
+ // The stream carries the prompt and the success record. The runner submits the
93
+ // code, then it delivers the credential and reports success after the sink.
94
+ const fake = createFakeDriver({ chunks: [PROMPT_OUTPUT, SUCCESS_OUTPUT] });
95
+ const onPrompt = vi.fn();
96
+ const provideCode = vi.fn(async () => BROWSER_CODE);
97
+ const promise = runSetupTokenLogin(fake.driver, {
98
+ onPrompt,
99
+ provideCode,
100
+ onCredential: async () => { },
101
+ timeoutMs: 1000,
102
+ codeSubmitSettleMs: 0,
103
+ });
104
+ await flush();
105
+ // The runner writes the code once, only after it matches the prompt. It writes
106
+ // the code and the terminator as two separate writes, so the terminator reads
107
+ // as a distinct Return key against an Ink paste field.
108
+ expect(provideCode).toHaveBeenCalledTimes(1);
109
+ expect(fake.writes).toEqual([BROWSER_CODE, CODE_SUBMISSION_TERMINATOR]);
110
+ fake.resolveExit(0);
111
+ const result = await promise;
112
+ expect(result.outcome).toBe("success");
113
+ expect(result.codeSubmitted).toBe(true);
114
+ });
115
+ it("never writes the code before it matches the prompt", async () => {
116
+ // The driver streams noise with no prompt, then exits. The runner must never
117
+ // send the code, because it never matched the prompt.
118
+ const fake = createFakeDriver({ chunks: ["unrelated output\n"], exitCode: 0 });
119
+ const provideCode = vi.fn(async () => BROWSER_CODE);
120
+ const result = await runSetupTokenLogin(fake.driver, {
121
+ onPrompt: () => { },
122
+ provideCode,
123
+ timeoutMs: 1000,
124
+ });
125
+ expect(result.promptSurfaced).toBe(false);
126
+ expect(result.codeSubmitted).toBe(false);
127
+ expect(provideCode).not.toHaveBeenCalled();
128
+ expect(fake.writes).toEqual([]);
129
+ });
130
+ it("stops the process on a timeout", async () => {
131
+ const fake = createFakeDriver();
132
+ const result = await runSetupTokenLogin(fake.driver, {
133
+ onPrompt: () => { },
134
+ provideCode: async () => BROWSER_CODE,
135
+ timeoutMs: 20,
136
+ });
137
+ expect(result.outcome).toBe("timeout");
138
+ expect(fake.stops.count).toBe(1);
139
+ expect(fake.disposes.count).toBe(1);
140
+ });
141
+ it("stops the process on a cancellation", async () => {
142
+ const fake = createFakeDriver();
143
+ const controller = new AbortController();
144
+ const promise = runSetupTokenLogin(fake.driver, {
145
+ onPrompt: () => { },
146
+ provideCode: async () => BROWSER_CODE,
147
+ timeoutMs: 5000,
148
+ signal: controller.signal,
149
+ });
150
+ controller.abort();
151
+ const result = await promise;
152
+ expect(result.outcome).toBe("cancelled");
153
+ expect(fake.stops.count).toBe(1);
154
+ expect(fake.disposes.count).toBe(1);
155
+ });
156
+ it("stops the process on a nonzero exit", async () => {
157
+ const fake = createFakeDriver({ exitCode: 7 });
158
+ const result = await runSetupTokenLogin(fake.driver, {
159
+ onPrompt: () => { },
160
+ provideCode: async () => BROWSER_CODE,
161
+ timeoutMs: 1000,
162
+ });
163
+ expect(result.outcome).toBe("failure");
164
+ expect(result.exitCode).toBe(7);
165
+ expect(fake.stops.count).toBe(1);
166
+ expect(fake.disposes.count).toBe(1);
167
+ });
168
+ it("keeps the code out of every log, result, and error field", async () => {
169
+ const logs = [];
170
+ const fake = createFakeDriver({ chunks: [PROMPT_OUTPUT], exitCode: 0 });
171
+ const result = await runSetupTokenLogin(fake.driver, {
172
+ onPrompt: () => { },
173
+ provideCode: async () => BROWSER_CODE,
174
+ timeoutMs: 1000,
175
+ log: (line) => {
176
+ logs.push(line);
177
+ },
178
+ });
179
+ const haystack = `${logs.join("\n")}\n${JSON.stringify(result)}`;
180
+ expect(haystack).not.toContain(BROWSER_CODE);
181
+ expect(haystack).not.toContain(VALID_URL);
182
+ });
183
+ it("keeps the code out of the thrown error on a stream failure", async () => {
184
+ const fake = createFakeDriver({
185
+ startError: new Error(`stream failure with ${VALID_URL} ${BROWSER_CODE}`),
186
+ });
187
+ let caught;
188
+ try {
189
+ await runSetupTokenLogin(fake.driver, {
190
+ onPrompt: () => { },
191
+ provideCode: async () => BROWSER_CODE,
192
+ timeoutMs: 1000,
193
+ });
194
+ }
195
+ catch (error) {
196
+ caught = error;
197
+ }
198
+ expect(caught).toBeInstanceOf(Error);
199
+ const message = caught.message;
200
+ expect(message).not.toContain(VALID_URL);
201
+ expect(message).not.toContain(BROWSER_CODE);
202
+ expect(fake.stops.count).toBe(1);
203
+ expect(fake.disposes.count).toBe(1);
204
+ });
205
+ it("parses an early prompt inside one large chunk before truncation", async () => {
206
+ // One chunk holds the prompt at its start and a large volume of output after
207
+ // it. The chunk is larger than the retained-buffer limit. The runner parses
208
+ // the whole chunk before it trims the retained window, so it still finds the
209
+ // early prompt and never drops it.
210
+ const trailingNoise = "unrelated output line\n".repeat(Math.ceil(CLAUDE_SETUP_TOKEN_MAX_BUFFER_CHARS / 10));
211
+ const fake = createFakeDriver({ chunks: [`${PROMPT_OUTPUT}${trailingNoise}`], exitCode: 0 });
212
+ const onPrompt = vi.fn();
213
+ const result = await runSetupTokenLogin(fake.driver, {
214
+ onPrompt,
215
+ provideCode: async () => BROWSER_CODE,
216
+ timeoutMs: 1000,
217
+ });
218
+ expect(result.promptSurfaced).toBe(true);
219
+ expect(onPrompt).toHaveBeenCalledTimes(1);
220
+ expect(onPrompt).toHaveBeenCalledWith({ url: VALID_URL, prompt: SETUP_TOKEN_PROMPT });
221
+ });
222
+ it("fails when a clean exit has no token block, even with a sink present", async () => {
223
+ // The stream holds only the prompt, so the token parser binds nothing. The
224
+ // runner treats a clean exit with no bound token as a failure. It never calls
225
+ // the sink and never reports success.
226
+ const fake = createFakeDriver({ chunks: [PROMPT_OUTPUT], exitCode: 0 });
227
+ const onCredential = vi.fn(async () => { });
228
+ const result = await runSetupTokenLogin(fake.driver, {
229
+ onPrompt: () => { },
230
+ provideCode: async () => BROWSER_CODE,
231
+ onCredential,
232
+ timeoutMs: 1000,
233
+ });
234
+ expect(result.outcome).toBe("failure");
235
+ expect(onCredential).not.toHaveBeenCalled();
236
+ expect(result.credentialDelivered).toBe(false);
237
+ expect(result).not.toHaveProperty("token");
238
+ expect(result).not.toHaveProperty("credential");
239
+ });
240
+ it("delivers the de-wrapped token once through onCredential and zeros it after", async () => {
241
+ const fake = createFakeDriver({ chunks: [PROMPT_OUTPUT, SUCCESS_OUTPUT], exitCode: 0 });
242
+ // The sink copies the token value, because the runner zeros the buffer after
243
+ // the delivery. The test reads the copy for the value and the original for the
244
+ // zeroing proof.
245
+ let received = null;
246
+ const onCredential = vi.fn(async (bytes) => {
247
+ received = bytes.toString("utf8");
248
+ });
249
+ const result = await runSetupTokenLogin(fake.driver, {
250
+ onPrompt: () => { },
251
+ provideCode: async () => BROWSER_CODE,
252
+ onCredential,
253
+ timeoutMs: 1000,
254
+ });
255
+ expect(result.outcome).toBe("success");
256
+ expect(result.credentialDelivered).toBe(true);
257
+ expect(onCredential).toHaveBeenCalledTimes(1);
258
+ expect(received).toBe(FULL_TOKEN);
259
+ // The runner zeros the token bytes after a successful delivery.
260
+ const bytes = onCredential.mock.calls[0][0];
261
+ expect(Buffer.isBuffer(bytes)).toBe(true);
262
+ expect(bytes.every((byte) => byte === 0)).toBe(true);
263
+ });
264
+ it("keeps the token out of every log, result, and error field", async () => {
265
+ const logs = [];
266
+ const fake = createFakeDriver({ chunks: [PROMPT_OUTPUT, SUCCESS_OUTPUT], exitCode: 0 });
267
+ const result = await runSetupTokenLogin(fake.driver, {
268
+ onPrompt: () => { },
269
+ provideCode: async () => BROWSER_CODE,
270
+ onCredential: async () => { },
271
+ timeoutMs: 1000,
272
+ log: (line) => {
273
+ logs.push(line);
274
+ },
275
+ });
276
+ const haystack = `${logs.join("\n")}\n${JSON.stringify(result)}`;
277
+ expect(haystack).not.toContain(FULL_TOKEN);
278
+ expect(haystack).not.toContain(TOKEN_FRAGMENT_A);
279
+ expect(result.credentialDelivered).toBe(true);
280
+ });
281
+ it("fails closed when no onCredential sink is present, even on a success stream", async () => {
282
+ // The sink is mandatory for a successful run. With no sink the runner never
283
+ // scans for the token and treats the clean exit as a failure, even when the
284
+ // success block is present.
285
+ const fake = createFakeDriver({ chunks: [PROMPT_OUTPUT, SUCCESS_OUTPUT], exitCode: 0 });
286
+ const result = await runSetupTokenLogin(fake.driver, {
287
+ onPrompt: () => { },
288
+ provideCode: async () => BROWSER_CODE,
289
+ timeoutMs: 1000,
290
+ });
291
+ expect(result.outcome).toBe("failure");
292
+ expect(result.credentialDelivered).toBe(false);
293
+ });
294
+ it("fails and zeros the token when the sink throws synchronously", async () => {
295
+ const fake = createFakeDriver({ chunks: [PROMPT_OUTPUT, SUCCESS_OUTPUT], exitCode: 0 });
296
+ let seen = null;
297
+ const result = await runSetupTokenLogin(fake.driver, {
298
+ onPrompt: () => { },
299
+ provideCode: async () => BROWSER_CODE,
300
+ // A synchronous throw. The runner catches it, fails closed, and never
301
+ // reports success.
302
+ onCredential: (bytes) => {
303
+ seen = bytes;
304
+ throw new Error("synchronous sink failure");
305
+ },
306
+ timeoutMs: 1000,
307
+ });
308
+ expect(result.outcome).toBe("failure");
309
+ expect(result.credentialDelivered).toBe(false);
310
+ expect(seen).not.toBeNull();
311
+ expect(seen.every((byte) => byte === 0)).toBe(true);
312
+ });
313
+ it("fails and zeros the token when the sink rejects asynchronously", async () => {
314
+ const fake = createFakeDriver({ chunks: [PROMPT_OUTPUT, SUCCESS_OUTPUT], exitCode: 0 });
315
+ let seen = null;
316
+ const result = await runSetupTokenLogin(fake.driver, {
317
+ onPrompt: () => { },
318
+ provideCode: async () => BROWSER_CODE,
319
+ // An asynchronous rejection. The runner does not swallow it: it maps the
320
+ // rejection to a failure and never reports success.
321
+ onCredential: async (bytes) => {
322
+ seen = bytes;
323
+ throw new Error("asynchronous sink failure");
324
+ },
325
+ timeoutMs: 1000,
326
+ });
327
+ expect(result.outcome).toBe("failure");
328
+ expect(result.credentialDelivered).toBe(false);
329
+ expect(seen).not.toBeNull();
330
+ expect(seen.every((byte) => byte === 0)).toBe(true);
331
+ });
332
+ it("exposes the fixed setup-token command", () => {
333
+ expect(CLAUDE_SETUP_TOKEN_COMMAND).toBe("claude setup-token");
334
+ });
335
+ });
336
+ //# sourceMappingURL=setup-token-runner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-token-runner.test.js","sourceRoot":"","sources":["../../src/server/setup-token-runner.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { AdapterSkillContext, AdapterSkillSnapshot } from "@tickernelz/paperclip-pro-adapter-utils";
2
+ export declare function listClaudeSkills(ctx: AdapterSkillContext): Promise<AdapterSkillSnapshot>;
3
+ export declare function syncClaudeSkills(ctx: AdapterSkillContext, _desiredSkills: string[]): Promise<AdapterSkillSnapshot>;
4
+ export declare function resolveClaudeDesiredSkillNames(config: Record<string, unknown>, availableEntries: Array<{
5
+ key: string;
6
+ required?: boolean;
7
+ }>): string[];
8
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/server/skills.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,yCAAyC,CAAC;AAyCjD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAE9F;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,mBAAmB,EACxB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,gBAAgB,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,YAG7D"}
@@ -0,0 +1,42 @@
1
+ import os from "node:os";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { buildRuntimeMountedSkillSnapshot, readPaperclipRuntimeSkillEntries, readInstalledSkillTargets, resolveLegacyPaperclipDesiredSkillNames, } from "@tickernelz/paperclip-pro-adapter-utils/server-utils";
5
+ const __moduleDir = path.dirname(fileURLToPath(import.meta.url));
6
+ function asString(value) {
7
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
8
+ }
9
+ function resolveClaudeSkillsHome(config) {
10
+ const env = typeof config.env === "object" && config.env !== null && !Array.isArray(config.env)
11
+ ? config.env
12
+ : {};
13
+ const configuredHome = asString(env.HOME);
14
+ const home = configuredHome ? path.resolve(configuredHome) : os.homedir();
15
+ return path.join(home, ".claude", "skills");
16
+ }
17
+ async function buildClaudeSkillSnapshot(config) {
18
+ const availableEntries = await readPaperclipRuntimeSkillEntries(config, __moduleDir);
19
+ const desiredSkills = resolveLegacyPaperclipDesiredSkillNames(config, availableEntries);
20
+ const skillsHome = resolveClaudeSkillsHome(config);
21
+ const installed = await readInstalledSkillTargets(skillsHome);
22
+ return buildRuntimeMountedSkillSnapshot({
23
+ adapterType: "claude_local",
24
+ availableEntries,
25
+ desiredSkills,
26
+ configuredDetail: "Will be materialized into the stable Paperclip-managed Claude prompt bundle on the next run.",
27
+ externalInstalled: installed,
28
+ externalLocationLabel: "~/.claude/skills",
29
+ externalDetail: "Installed outside Paperclip management in the Claude skills home.",
30
+ skillsHome,
31
+ });
32
+ }
33
+ export async function listClaudeSkills(ctx) {
34
+ return buildClaudeSkillSnapshot(ctx.config);
35
+ }
36
+ export async function syncClaudeSkills(ctx, _desiredSkills) {
37
+ return buildClaudeSkillSnapshot(ctx.config);
38
+ }
39
+ export function resolveClaudeDesiredSkillNames(config, availableEntries) {
40
+ return resolveLegacyPaperclipDesiredSkillNames(config, availableEntries);
41
+ }
42
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/server/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAKzC,OAAO,EACL,gCAAgC,EAChC,gCAAgC,EAChC,yBAAyB,EACzB,uCAAuC,GACxC,MAAM,sDAAsD,CAAC;AAE9D,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEjE,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpF,CAAC;AAED,SAAS,uBAAuB,CAAC,MAA+B;IAC9D,MAAM,GAAG,GACP,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;QACjF,CAAC,CAAE,MAAM,CAAC,GAA+B;QACzC,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1E,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,MAA+B;IACrE,MAAM,gBAAgB,GAAG,MAAM,gCAAgC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrF,MAAM,aAAa,GAAG,uCAAuC,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACxF,MAAM,UAAU,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,MAAM,yBAAyB,CAAC,UAAU,CAAC,CAAC;IAC9D,OAAO,gCAAgC,CAAC;QACtC,WAAW,EAAE,cAAc;QAC3B,gBAAgB;QAChB,aAAa;QACb,gBAAgB,EAAE,8FAA8F;QAChH,iBAAiB,EAAE,SAAS;QAC5B,qBAAqB,EAAE,kBAAkB;QACzC,cAAc,EAAE,mEAAmE;QACnF,UAAU;KACX,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAwB;IAC7D,OAAO,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAwB,EACxB,cAAwB;IAExB,OAAO,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,MAA+B,EAC/B,gBAA4D;IAE5D,OAAO,uCAAuC,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AdapterEnvironmentTestContext, AdapterEnvironmentTestResult } from "@tickernelz/paperclip-pro-adapter-utils";
2
+ export declare function testEnvironment(ctx: AdapterEnvironmentTestContext): Promise<AdapterEnvironmentTestResult>;
3
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/server/test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,6BAA6B,EAC7B,4BAA4B,EAC7B,MAAM,yCAAyC,CAAC;AA4DjD,wBAAsB,eAAe,CACnC,GAAG,EAAE,6BAA6B,GACjC,OAAO,CAAC,4BAA4B,CAAC,CAicvC"}