@usefactory/factory-darwin-arm64 0.3.0-dev0 → 0.3.0-dev2

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.
package/EULA.md ADDED
@@ -0,0 +1,203 @@
1
+ # Factory — End User Licence Agreement
2
+
3
+ **Version 1.0 · 29 August 2026**
4
+
5
+ This Agreement governs your use of **Factory**, the command-line software distributed as
6
+ `@usefactory/factory` and its platform packages ("the Software"). By installing, activating or using
7
+ the Software you agree to it. If you do not agree, do not install it, and remove any copy you have.
8
+
9
+ The Software is licensed, not sold.
10
+
11
+ ---
12
+
13
+ ## 1. What you may do
14
+
15
+ Subject to your compliance with this Agreement, you are granted a non-exclusive, non-transferable,
16
+ revocable licence to:
17
+
18
+ 1. **Install and run the Software** on the number of machines your plan allows, for the purpose of
19
+ building, maintaining and operating software — your own, your employer's, or your clients'.
20
+ 2. **Keep everything the Software produces.** All source code, documentation, configuration,
21
+ diagrams, test suites and other output generated by a Factory run are **yours**. No licence,
22
+ claim, royalty or attribution is asserted over your work product. This applies to commercial work
23
+ without restriction.
24
+ 3. **Use the Software on private and proprietary codebases.** Nothing in this Agreement requires you
25
+ to disclose, open-source or share your code.
26
+
27
+ Your plan's limits — how many agents may run in parallel, how many machines one key activates, which
28
+ optional capabilities are enabled — are recorded in the signed licence your installation holds and
29
+ are described at `factory upgrade`.
30
+
31
+ ## 2. What you may not do
32
+
33
+ You may not:
34
+
35
+ 1. **Redistribute the Software**, in whole or in part, to anyone else — including by publishing,
36
+ mirroring, bundling, reselling, renting, leasing, sublicensing, or making it available as a
37
+ hosted or managed service.
38
+ 2. **Reverse engineer, decompile, disassemble, decrypt, or otherwise attempt to derive** the
39
+ Software's source form, prompts, agent definitions, orchestration logic, or the contents of its
40
+ sealed payload, except to the minimum extent that applicable law expressly permits and cannot be
41
+ contracted out of.
42
+ 3. **Extract, copy, reproduce or republish the Software's prompts, agent definitions, skills,
43
+ policies or orchestration logic**, whether obtained from the sealed payload, from a running
44
+ process, from memory, from a temporary filesystem, or by asking a model to reproduce them.
45
+ 4. **Circumvent, disable, patch, forge or tamper with licensing or entitlement enforcement**,
46
+ including the signed licence, the pinned issuer key, the seal on the payload, the activation
47
+ process, or any limit your plan imposes. This includes using a licence you were not issued and
48
+ using a modified build of the Software.
49
+ 5. **Share your activation key** with anyone outside your organisation, or use one key to serve more
50
+ machines or people than your plan permits.
51
+ 6. **Remove or obscure** copyright, licence, or attribution notices.
52
+ 7. **Use the Software to build a competing product** by using it as a reference for, or a source of,
53
+ agent prompts or orchestration logic.
54
+
55
+ Sections 2.1 through 2.4 are material terms. A breach of any of them terminates this licence
56
+ immediately under section 9.
57
+
58
+ ## 3. Your Claude subscription, and Anthropic's terms
59
+
60
+ **Factory runs on your own installation of Claude and your own Anthropic credentials.** It never
61
+ handles, stores, transmits, proxies or has access to any Claude or Anthropic credential; it drives
62
+ the Claude installation already authenticated on your machine, and all model usage is billed to you
63
+ by Anthropic under your agreement with them.
64
+
65
+ You are responsible for:
66
+
67
+ 1. Holding a valid Claude subscription or API access, and complying with **Anthropic's own terms of
68
+ service and usage policies**, which govern your model usage and are not superseded by this
69
+ Agreement.
70
+ 2. Any charges Anthropic bills you for usage that Factory initiates on your behalf.
71
+
72
+ **We are not affiliated with, endorsed by, or sponsored by Anthropic.** "Claude" is a trademark of
73
+ Anthropic. If Anthropic changes its terms, its products, or its enforcement in a way that restricts
74
+ or prevents this pattern of use, that is outside our control, and section 7 applies. Your remedy is
75
+ to cancel under section 8.
76
+
77
+ ## 4. Fees, renewal and cancellation
78
+
79
+ 1. **Paid plans are billed monthly in advance** through our payment processor. Prices are shown at
80
+ `factory upgrade` and at the point of purchase. The free plan is free.
81
+ 2. **Subscriptions renew automatically** each period until cancelled.
82
+ 3. **You may cancel at any time**, through `factory upgrade --manage`. Cancellation takes effect at
83
+ the end of the period you have already paid for. **We do not refund partial periods.**
84
+ 4. **When a paid subscription ends** — by cancellation, by non-payment, or by expiry — your
85
+ installation continues to work on the **free plan**. It is not disabled, your work is not locked,
86
+ and nothing you have produced becomes inaccessible. Only the paid plan's limits go away.
87
+ 5. **A licence is valid until it expires.** Licences are short-dated and renew silently while you
88
+ use the Software; a cancellation therefore takes effect at the next expiry rather than
89
+ immediately.
90
+ 6. We may change prices with **30 days' notice** for existing subscribers, effective at your next
91
+ renewal after the notice period.
92
+ 7. Fees exclude taxes. You are responsible for any sales tax, VAT, GST or withholding that applies
93
+ to you.
94
+
95
+ ## 5. Activation, and what leaves your machine
96
+
97
+ To license a machine, the Software sends **an email address, an activation key, and an opaque machine
98
+ identifier** (a hash — never a hardware serial, never a hostname in plain form) to the activation
99
+ service, and receives a signed licence in return. That is the whole of it.
100
+
101
+ The Software does **not** transmit, and the activation service does not receive:
102
+
103
+ - your source code, your prompts, your requests, or anything a Factory run produces;
104
+ - any Claude or Anthropic credential;
105
+ - telemetry, analytics, usage metering, or a record of what you built.
106
+
107
+ **A licensed installation does not need the network.** Once activated, licences verify offline
108
+ against a key inside the binary; a valid licence authorises a run with no network call at all, and
109
+ an expired one has a grace period beyond that. The two commands that do require the network are
110
+ `factory activate` and `factory upgrade`, and neither runs during a build.
111
+
112
+ Email addresses and activation records are held for the purpose of operating your licence and are not
113
+ sold, rented, or shared for marketing.
114
+
115
+ ## 6. Ownership
116
+
117
+ The Software, and every part of it — including its prompts, agent definitions, skills, orchestration
118
+ logic, accumulated learned-rule store, and the design of all of the above — is owned by the licensor
119
+ and protected by copyright and other laws. This Agreement grants you a licence to **use** it and
120
+ transfers no ownership. All rights not expressly granted are reserved.
121
+
122
+ **Your work product is not part of the Software.** See section 1.2.
123
+
124
+ ## 7. No warranty
125
+
126
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
127
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
128
+ NON-INFRINGEMENT.
129
+
130
+ Two disclaimers deserve to be said plainly rather than only in capitals:
131
+
132
+ 1. **The Software directs a large language model to write and modify code, run commands, and change
133
+ files in your repository.** Its output is not guaranteed to be correct, secure, complete, or
134
+ suitable for any purpose. **Review everything it produces before you rely on it, and use version
135
+ control.** You are responsible for what you ship.
136
+ 2. **The Software depends on third-party software and services** — Claude, Anthropic's APIs, and the
137
+ packages it installs — whose availability, behaviour, pricing and terms are outside our control
138
+ and may change or stop without notice.
139
+
140
+ ## 8. Limitation of liability
141
+
142
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE LICENSOR IS NOT LIABLE FOR ANY INDIRECT, INCIDENTAL,
143
+ SPECIAL, CONSEQUENTIAL, EXEMPLARY OR PUNITIVE DAMAGES, OR FOR ANY LOSS OF PROFITS, REVENUE, DATA,
144
+ GOODWILL, OR BUSINESS INTERRUPTION, ARISING OUT OF OR RELATING TO THIS AGREEMENT OR THE SOFTWARE,
145
+ WHETHER IN CONTRACT, TORT, OR ANY OTHER THEORY, AND WHETHER OR NOT ADVISED OF THE POSSIBILITY.
146
+
147
+ THE LICENSOR'S TOTAL AGGREGATE LIABILITY UNDER THIS AGREEMENT IS LIMITED TO **THE GREATER OF (a) THE
148
+ AMOUNT YOU PAID FOR THE SOFTWARE IN THE TWELVE MONTHS BEFORE THE CLAIM AROSE, AND (b) USD 50.**
149
+
150
+ Nothing in this Agreement excludes or limits liability that cannot lawfully be excluded or limited,
151
+ including liability for death or personal injury caused by negligence, or for fraud.
152
+
153
+ Some jurisdictions do not allow certain exclusions or limitations. In those jurisdictions the
154
+ exclusions and limitations above apply to the fullest extent permitted, and the rest of this
155
+ Agreement remains in force.
156
+
157
+ ## 9. Term and termination
158
+
159
+ 1. This Agreement runs until terminated.
160
+ 2. **You may terminate** at any time by cancelling your subscription and removing all copies of the
161
+ Software.
162
+ 3. **We may terminate immediately** if you materially breach this Agreement — in particular any of
163
+ sections 2.1 to 2.4 — with no refund.
164
+ 4. **We may suspend or terminate an account** used to redistribute the Software, to circumvent
165
+ licensing, or to abuse the activation or billing services.
166
+ 5. On termination, the licence in section 1 ends and you must stop using the Software and destroy all
167
+ copies. Sections 2, 6, 7, 8, 10 and 11 survive termination.
168
+ 6. **Your work product survives termination unconditionally.** Nothing here requires you to delete,
169
+ stop using, stop distributing, or stop selling anything the Software produced for you.
170
+
171
+ ## 10. Changes to this Agreement
172
+
173
+ We may update this Agreement for future versions of the Software. Material changes will be noted in
174
+ the release notes and in this file's version line. **The version of this Agreement that ships with
175
+ the copy of the Software you installed is the one that governs your use of that copy.** Continuing to
176
+ use a later version after an update means you accept the Agreement that ships with it.
177
+
178
+ ## 11. General
179
+
180
+ 1. **Governing law.** This Agreement is governed by the laws of the licensor's principal place of
181
+ business, without regard to conflict-of-laws rules. The courts there have exclusive jurisdiction,
182
+ except that either party may seek injunctive relief anywhere to protect intellectual property.
183
+ 2. **Entire agreement.** This is the entire agreement between us about the Software, and supersedes
184
+ any prior understanding, including any statement in the README, the documentation, or marketing
185
+ material. Where they differ, this document governs.
186
+ 3. **Severability.** If any provision is held unenforceable, it is modified to the minimum extent
187
+ needed to be enforceable, or severed, and the rest stands.
188
+ 4. **No waiver.** A failure to enforce a provision is not a waiver of it.
189
+ 5. **Assignment.** You may not assign this Agreement without written consent. We may assign it in
190
+ connection with a merger, acquisition, or sale of assets.
191
+ 6. **Third-party components.** The Software installs and depends on third-party packages, each under
192
+ its own licence. Those licences govern those components; nothing here limits any right you have
193
+ under them.
194
+ 7. **Export.** You must not use or export the Software in violation of applicable export control or
195
+ sanctions law.
196
+
197
+ ---
198
+
199
+ **Questions about this Agreement, or about a licence:** open an issue or contact the address in the
200
+ package's README.
201
+
202
+ `factory doctor` prints the exact version of the Software and the licence installed on a machine, and
203
+ is the fastest way to answer "which terms apply to this install".
package/factory CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usefactory/factory-darwin-arm64",
3
- "version": "0.3.0-dev0",
3
+ "version": "0.3.0-dev2",
4
4
  "description": "The darwin-arm64 build of Factory. Installed automatically by @usefactory/factory; not useful on its own.",
5
5
  "license": "UNLICENSED",
6
6
  "os": [
@@ -26,6 +26,15 @@ const rpc = new Rpc(process.stdin, process.stdout);
26
26
  let activeAbort = null;
27
27
  let aborting = false;
28
28
 
29
+ // The live Query handle.
30
+ //
31
+ // `query()` returns an async generator that ALSO carries the control requests — getContextUsage,
32
+ // supportedModels, setModel. The first version of this file consumed the generator in a `for await`
33
+ // and never kept the handle, so none of them could be reached and the CLI had no way to ask the
34
+ // session anything about itself. Keeping it is the whole of the change; the loop is unaffected.
35
+ /** @type {any} */
36
+ let activeQuery = null;
37
+
29
38
  function log(level, message) {
30
39
  rpc.notify('log', { level, message: String(message) });
31
40
  }
@@ -168,7 +177,8 @@ rpc.handle('run', async (spec) => {
168
177
  const summary = { ok: false, sessionId: null, result: null, error: null, aborted: false };
169
178
 
170
179
  try {
171
- for await (const msg of query({ prompt: spec.prompt, options })) {
180
+ activeQuery = query({ prompt: spec.prompt, options });
181
+ for await (const msg of activeQuery) {
172
182
  if (msg.type === 'system' && msg.subtype === 'init') summary.sessionId = msg.session_id ?? null;
173
183
  if (msg.type === 'result') summary.result = msg;
174
184
  // Forwarded raw. Go filters; a lossy projection here would have to be revisited by every
@@ -181,6 +191,7 @@ rpc.handle('run', async (spec) => {
181
191
  summary.error = String(err?.message ?? err);
182
192
  } finally {
183
193
  activeAbort = null;
194
+ activeQuery = null;
184
195
  }
185
196
  if (aborting) {
186
197
  summary.ok = false;
@@ -189,6 +200,113 @@ rpc.handle('run', async (spec) => {
189
200
  return summary;
190
201
  });
191
202
 
203
+ /**
204
+ * What the session knows about itself: context window occupancy and the plan's rate-limit windows.
205
+ *
206
+ * BOTH CALLS ARE OPTIONAL AND BOTH ARE ALLOWED TO FAIL. The usage one is marked EXPERIMENTAL in the
207
+ * SDK's own types — "may change or be removed in any release without notice", and the method name
208
+ * is promised to change when it stabilizes — so it is reached by feature detection rather than by
209
+ * name at the call site, and a failure returns nulls instead of raising. An indicator that stops
210
+ * appearing is a cosmetic regression; a run that dies because a status bar could not be drawn is
211
+ * not acceptable.
212
+ *
213
+ * Measured before this was written: with a plain string prompt (not streaming input), both calls
214
+ * succeed against a real session.
215
+ */
216
+ rpc.handle('metrics', async () => {
217
+ const q = activeQuery;
218
+ const out = { context: null, limits: null, subscription: null, available: false };
219
+ if (!q) return out;
220
+
221
+ try {
222
+ if (typeof q.getContextUsage === 'function') {
223
+ const c = await q.getContextUsage();
224
+ if (c) {
225
+ out.context = {
226
+ percentage: c.percentage ?? null,
227
+ totalTokens: c.totalTokens ?? null,
228
+ maxTokens: c.maxTokens ?? null,
229
+ model: c.model ?? null,
230
+ };
231
+ }
232
+ }
233
+ } catch (err) {
234
+ log('debug', `context usage unavailable: ${err?.message ?? err}`);
235
+ }
236
+
237
+ try {
238
+ // Found by prefix, not by its full name: the SDK promises the name will change when the API
239
+ // stabilizes, and a hardcoded call site would then silently stop reporting.
240
+ //
241
+ // getOwnPropertyNames, NOT Object.keys. Class methods live on the prototype and are
242
+ // NON-ENUMERABLE, so Object.keys returns none of them — the first version of this found
243
+ // nothing, every sample came back with the context filled in and the limits null, and the bar
244
+ // silently showed half of what it was built to show. The direct check comes first so the
245
+ // common case does not depend on reflection at all.
246
+ let key = null;
247
+ if (typeof q.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET === 'function') {
248
+ key = 'usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET';
249
+ } else {
250
+ const names = new Set();
251
+ for (let o = q; o && o !== Object.prototype; o = Object.getPrototypeOf(o)) {
252
+ for (const n of Object.getOwnPropertyNames(o)) names.add(n);
253
+ }
254
+ key = [...names].find((k) => k === 'usage' || k.startsWith('usage_EXPERIMENTAL')) ?? null;
255
+ }
256
+ if (key && typeof q[key] === 'function') {
257
+ const u = await q[key]();
258
+ out.subscription = u?.subscription_type ?? null;
259
+ out.available = u?.rate_limits_available === true;
260
+ out.limits = u?.rate_limits ?? null;
261
+ }
262
+ } catch (err) {
263
+ log('debug', `rate limits unavailable: ${err?.message ?? err}`);
264
+ }
265
+ return out;
266
+ });
267
+
268
+ /**
269
+ * The models this Claude Code offers, for the switcher. Returns [] rather than failing.
270
+ */
271
+ rpc.handle('models', async () => {
272
+ const q = activeQuery;
273
+ if (!q || typeof q.supportedModels !== 'function') return { models: [] };
274
+ try {
275
+ const list = await q.supportedModels();
276
+ return {
277
+ models: (list ?? []).map((m) => ({
278
+ value: m.value,
279
+ displayName: m.displayName ?? m.value,
280
+ description: m.description ?? '',
281
+ })),
282
+ };
283
+ } catch (err) {
284
+ log('debug', `model list unavailable: ${err?.message ?? err}`);
285
+ return { models: [] };
286
+ }
287
+ });
288
+
289
+ /**
290
+ * Switch the model for what the session does NEXT.
291
+ *
292
+ * The factory is one long query in which the orchestrator dispatches subagents, so there is no
293
+ * session boundary to wait for — but there is still no way to change the model of a turn already in
294
+ * flight. The SDK's own wording is "the model used for subsequent responses", and that is exactly
295
+ * what the CLI tells the user.
296
+ */
297
+ rpc.handle('setModel', async (params) => {
298
+ const q = activeQuery;
299
+ if (!q || typeof q.setModel !== 'function') {
300
+ return { ok: false, error: 'no live session' };
301
+ }
302
+ try {
303
+ await q.setModel(params?.model || undefined);
304
+ return { ok: true };
305
+ } catch (err) {
306
+ return { ok: false, error: String(err?.message ?? err) };
307
+ }
308
+ });
309
+
192
310
  rpc.handle('cancel', async (params) => {
193
311
  abortRun(params?.reason ?? 'cancelled by the CLI');
194
312
  return { cancelled: true };