@treeseed/cli 0.10.5 → 0.10.6
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.
|
@@ -4,6 +4,7 @@ import { resolve } from "node:path";
|
|
|
4
4
|
import { resolveCapacityProviderLaunchEnvironment } from "@treeseed/sdk/capacity-provider";
|
|
5
5
|
import { resolveMarketProfile } from "@treeseed/sdk/market-client";
|
|
6
6
|
import { findNearestTreeseedRoot, findNearestTreeseedWorkspaceRoot } from "@treeseed/sdk/workflow-support";
|
|
7
|
+
import { createMarketClientForInvocation } from "./market-utils.js";
|
|
7
8
|
import { fail, guidedResult } from "./utils.js";
|
|
8
9
|
const ENTRYPOINT_RELATIVE_PATH = ["dist", "provider", "entrypoint.js"];
|
|
9
10
|
const COMPOSE_FILE_NAME = "compose.capacity-provider.yml";
|
|
@@ -11,6 +12,7 @@ const DEFAULT_PROJECT_NAME = "treeseed-capacity-provider";
|
|
|
11
12
|
const DEFAULT_HOST_DATA_DIR = ".treeseed/local-capacity-provider/data";
|
|
12
13
|
const PROVIDER_LIFECYCLE_ACTIONS = /* @__PURE__ */ new Set(["build", "up", "down", "restart", "logs", "status", "test-local"]);
|
|
13
14
|
const PROVIDER_ENTRYPOINT_ACTIONS = /* @__PURE__ */ new Set(["doctor", "register", "plan"]);
|
|
15
|
+
const MARKET_CAPACITY_ACTIONS = /* @__PURE__ */ new Set(["migrate"]);
|
|
14
16
|
function stringArg(invocation, name) {
|
|
15
17
|
const value = invocation.args[name];
|
|
16
18
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
@@ -18,6 +20,24 @@ function stringArg(invocation, name) {
|
|
|
18
20
|
function boolArg(invocation, name) {
|
|
19
21
|
return invocation.args[name] === true;
|
|
20
22
|
}
|
|
23
|
+
function numberArg(invocation, name) {
|
|
24
|
+
const value = invocation.args[name];
|
|
25
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
26
|
+
if (typeof value === "string" && value.trim().length > 0 && Number.isFinite(Number(value))) return Number(value);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
function formatNumber(value, digits = 2) {
|
|
30
|
+
if (value === null || value === void 0 || value === "") return "n/a";
|
|
31
|
+
const numeric = Number(value);
|
|
32
|
+
if (!Number.isFinite(numeric)) return String(value);
|
|
33
|
+
return numeric.toLocaleString("en-US", { maximumFractionDigits: digits });
|
|
34
|
+
}
|
|
35
|
+
function recordValue(record, key) {
|
|
36
|
+
return record && typeof record === "object" && key in record ? record[key] : void 0;
|
|
37
|
+
}
|
|
38
|
+
function marketRequest(client, path, options = {}) {
|
|
39
|
+
return client.request(path, options);
|
|
40
|
+
}
|
|
21
41
|
function readPackageName(packageRoot) {
|
|
22
42
|
const packageJsonPath = resolve(packageRoot, "package.json");
|
|
23
43
|
if (!existsSync(packageJsonPath)) return null;
|
|
@@ -108,6 +128,212 @@ function composeCommandArgs(composeFilePath, projectName, action) {
|
|
|
108
128
|
return base;
|
|
109
129
|
}
|
|
110
130
|
}
|
|
131
|
+
function nativeBudgetSummaryLines(report) {
|
|
132
|
+
const budgets = recordValue(report, "budgets");
|
|
133
|
+
const nativeCapacity = recordValue(budgets, "nativeCapacity") ?? recordValue(budgets, "native_capacity");
|
|
134
|
+
const executionProviders = recordValue(nativeCapacity, "executionProviders") ?? recordValue(nativeCapacity, "execution_providers");
|
|
135
|
+
if (!Array.isArray(executionProviders)) return [];
|
|
136
|
+
return executionProviders.flatMap((provider) => {
|
|
137
|
+
const name = recordValue(provider, "name") ?? recordValue(provider, "id") ?? "execution provider";
|
|
138
|
+
const kind = recordValue(provider, "kind") ?? "custom";
|
|
139
|
+
const nativeUnit = recordValue(provider, "nativeUnit") ?? recordValue(provider, "native_unit") ?? "native unit";
|
|
140
|
+
const workers = recordValue(provider, "maxConcurrentWorkers") ?? recordValue(provider, "max_concurrent_workers");
|
|
141
|
+
const limits = recordValue(provider, "nativeLimits") ?? recordValue(provider, "native_limits");
|
|
142
|
+
const lines = [`${name}: ${kind}, ${nativeUnit}${workers ? `, workers ${workers}` : ""}`];
|
|
143
|
+
if (Array.isArray(limits)) {
|
|
144
|
+
for (const limit of limits) {
|
|
145
|
+
lines.push(` ${recordValue(limit, "scope") ?? recordValue(limit, "limitScope") ?? "limit"}: ${formatNumber(recordValue(limit, "limitAmount") ?? recordValue(limit, "limit_amount"))} ${recordValue(limit, "nativeUnit") ?? nativeUnit}, reserve ${formatNumber(recordValue(limit, "reserveBufferPercent") ?? recordValue(limit, "reserve_buffer_percent"))}%`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return lines;
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function derivedCapacityLines(plan) {
|
|
152
|
+
const derivedCapacity = recordValue(plan, "derivedCapacity");
|
|
153
|
+
const entries = recordValue(derivedCapacity, "entries");
|
|
154
|
+
if (!Array.isArray(entries) || entries.length === 0) {
|
|
155
|
+
return ["No derived native capacity entries are available yet."];
|
|
156
|
+
}
|
|
157
|
+
return entries.map((entry) => [
|
|
158
|
+
`${recordValue(entry, "executionProviderKind") ?? "provider"}:${recordValue(entry, "nativeUnit") ?? "native"}`,
|
|
159
|
+
`limit ${formatNumber(recordValue(entry, "configuredNativeLimit"))}`,
|
|
160
|
+
`observed ${formatNumber(recordValue(entry, "observedNativeRemaining"))}`,
|
|
161
|
+
`reserved ${formatNumber(recordValue(entry, "activeReservedNativeAmount"))}`,
|
|
162
|
+
`reserve ${formatNumber(recordValue(entry, "reserveBufferPercent"))}%`,
|
|
163
|
+
`conversion ${formatNumber(recordValue(entry, "nativeUnitsPerCredit"))} native/credit`,
|
|
164
|
+
`derived ${formatNumber(recordValue(entry, "derivedAvailableCredits"))} credits`,
|
|
165
|
+
`confidence ${recordValue(entry, "confidence") ?? "unknown"}`
|
|
166
|
+
].join(" | "));
|
|
167
|
+
}
|
|
168
|
+
function grantAllocationLines(plan) {
|
|
169
|
+
const grants = recordValue(plan, "grants");
|
|
170
|
+
if (!Array.isArray(grants) || grants.length === 0) return [];
|
|
171
|
+
return grants.map((grant) => [
|
|
172
|
+
`${recordValue(grant, "grantScope") ?? "grant"} ${recordValue(grant, "environment") ?? "all"}`,
|
|
173
|
+
`allocation ${formatNumber(recordValue(grant, "portfolioAllocationPercent"))}%`,
|
|
174
|
+
`reserve pool ${formatNumber(recordValue(grant, "reservePoolPercent"))}%`,
|
|
175
|
+
`max daily project credits ${formatNumber(recordValue(grant, "maxDailyProjectCredits"))}`,
|
|
176
|
+
`overflow ${recordValue(grant, "overflowPolicy") ?? "soft_grant"}`,
|
|
177
|
+
`emergency ${recordValue(grant, "emergencyOverride") === true ? "on" : "off"}`
|
|
178
|
+
].join(" | "));
|
|
179
|
+
}
|
|
180
|
+
async function runProjectCapacityPlan(invocation, context) {
|
|
181
|
+
const projectId = stringArg(invocation, "project");
|
|
182
|
+
if (!projectId) return fail("Missing --project. Use `trsd capacity plan --project <project-id> --environment local`.");
|
|
183
|
+
const { profile, client } = createMarketClientForInvocation(invocation, context, { requireAuth: true });
|
|
184
|
+
const environment = environmentSelector(invocation);
|
|
185
|
+
const response = await marketRequest(
|
|
186
|
+
client,
|
|
187
|
+
`/v1/projects/${encodeURIComponent(projectId)}/capacity-plan?environment=${encodeURIComponent(environment)}`,
|
|
188
|
+
{ requireAuth: true }
|
|
189
|
+
);
|
|
190
|
+
const plan = response.payload;
|
|
191
|
+
return guidedResult({
|
|
192
|
+
command: "capacity plan",
|
|
193
|
+
summary: `Capacity plan for project ${projectId} in ${environment}.`,
|
|
194
|
+
facts: [
|
|
195
|
+
{ label: "Market", value: `${profile.id} (${profile.baseUrl})` },
|
|
196
|
+
{ label: "Project", value: projectId },
|
|
197
|
+
{ label: "Environment", value: environment },
|
|
198
|
+
{ label: "Derived credits", value: formatNumber(recordValue(recordValue(plan, "derivedCapacity"), "totalDerivedAvailableCredits")) }
|
|
199
|
+
],
|
|
200
|
+
sections: [
|
|
201
|
+
{ title: "Native projection", lines: derivedCapacityLines(plan) },
|
|
202
|
+
{ title: "Allocation grants", lines: grantAllocationLines(plan) }
|
|
203
|
+
],
|
|
204
|
+
report: { action: "plan", projectId, environment, market: { id: profile.id, baseUrl: profile.baseUrl }, plan }
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
function providerMatcher(selector) {
|
|
208
|
+
return (provider) => {
|
|
209
|
+
const id = String(recordValue(provider, "id") ?? "");
|
|
210
|
+
const name = String(recordValue(provider, "name") ?? "");
|
|
211
|
+
return id === selector || name === selector;
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function migrationMissingFields(invocation) {
|
|
215
|
+
const missing = [];
|
|
216
|
+
if (!stringArg(invocation, "team")) missing.push("--team");
|
|
217
|
+
if (!stringArg(invocation, "provider")) missing.push("--provider");
|
|
218
|
+
if (!stringArg(invocation, "kind")) missing.push("--kind");
|
|
219
|
+
if (!stringArg(invocation, "nativeUnit")) missing.push("--native-unit");
|
|
220
|
+
if (numberArg(invocation, "limit") === null) missing.push("--limit");
|
|
221
|
+
return missing;
|
|
222
|
+
}
|
|
223
|
+
async function runMigrateToDerived(invocation, context) {
|
|
224
|
+
if (!boolArg(invocation, "toDerived")) {
|
|
225
|
+
return fail("Missing --to-derived. Phase 8 supports `trsd capacity migrate --to-derived`.");
|
|
226
|
+
}
|
|
227
|
+
const missing = migrationMissingFields(invocation);
|
|
228
|
+
const example = "trsd capacity migrate --to-derived --team team_123 --provider provider_123 --kind codex_subscription --native-unit wall_minute --limit 480 --scope daily --reset-cadence daily --quota-visibility opaque --reserve-buffer-percent 20 --max-concurrent-workers 4 --project project_123 --portfolio-allocation-percent 100 --dry-run";
|
|
229
|
+
if (missing.length > 0) {
|
|
230
|
+
return fail(`Missing native capacity facts: ${missing.join(", ")}.
|
|
231
|
+
Example: ${example}`);
|
|
232
|
+
}
|
|
233
|
+
const teamId = stringArg(invocation, "team");
|
|
234
|
+
const providerSelectorValue = stringArg(invocation, "provider");
|
|
235
|
+
const kind = stringArg(invocation, "kind");
|
|
236
|
+
const nativeUnit = stringArg(invocation, "nativeUnit");
|
|
237
|
+
const limitAmount = numberArg(invocation, "limit");
|
|
238
|
+
const scope = stringArg(invocation, "scope") ?? "daily";
|
|
239
|
+
const resetCadence = stringArg(invocation, "resetCadence") ?? "daily";
|
|
240
|
+
const quotaVisibility = stringArg(invocation, "quotaVisibility") ?? "opaque";
|
|
241
|
+
const reserveBufferPercent = numberArg(invocation, "reserveBufferPercent") ?? 20;
|
|
242
|
+
const maxConcurrentWorkers = Math.max(1, Math.floor(numberArg(invocation, "maxConcurrentWorkers") ?? 1));
|
|
243
|
+
const environment = environmentSelector(invocation);
|
|
244
|
+
const projectId = stringArg(invocation, "project");
|
|
245
|
+
const allocationPercent = numberArg(invocation, "portfolioAllocationPercent");
|
|
246
|
+
const dryRun = boolArg(invocation, "dryRun");
|
|
247
|
+
const { profile, client } = createMarketClientForInvocation(invocation, context, { requireAuth: !dryRun });
|
|
248
|
+
const providerList = dryRun ? { payload: [{ id: providerSelectorValue, name: providerSelectorValue }] } : await marketRequest(
|
|
249
|
+
client,
|
|
250
|
+
`/v1/teams/${encodeURIComponent(teamId)}/capacity-providers`,
|
|
251
|
+
{ requireAuth: true }
|
|
252
|
+
);
|
|
253
|
+
const provider = providerList.payload.find(providerMatcher(providerSelectorValue));
|
|
254
|
+
if (!provider) return fail(`Capacity provider "${providerSelectorValue}" was not found in team ${teamId}.`);
|
|
255
|
+
const providerId = String(recordValue(provider, "id"));
|
|
256
|
+
const executionProvider = {
|
|
257
|
+
name: `${kind.replace(/_/gu, " ")} ${nativeUnit}`,
|
|
258
|
+
kind,
|
|
259
|
+
nativeUnit,
|
|
260
|
+
quotaVisibility,
|
|
261
|
+
maxConcurrentWorkers,
|
|
262
|
+
resetCadence,
|
|
263
|
+
nativeLimits: [{
|
|
264
|
+
scope,
|
|
265
|
+
nativeUnit,
|
|
266
|
+
limitAmount,
|
|
267
|
+
reserveBufferPercent,
|
|
268
|
+
resetCadence,
|
|
269
|
+
confidence: "estimated",
|
|
270
|
+
source: "operator_migration"
|
|
271
|
+
}],
|
|
272
|
+
metadata: {
|
|
273
|
+
source: "trsd capacity migrate --to-derived",
|
|
274
|
+
staticCreditBudgetsPreservedAs: "hybrid_fallback_cap"
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
const grant = allocationPercent === null ? null : {
|
|
278
|
+
capacityProviderId: providerId,
|
|
279
|
+
teamId,
|
|
280
|
+
projectId,
|
|
281
|
+
environment,
|
|
282
|
+
grantScope: projectId ? "project" : "team",
|
|
283
|
+
portfolioAllocationPercent: allocationPercent,
|
|
284
|
+
overflowPolicy: "soft_grant",
|
|
285
|
+
metadata: {
|
|
286
|
+
source: "trsd capacity migrate --to-derived"
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
if (!dryRun) {
|
|
290
|
+
await marketRequest(client, `/v1/teams/${encodeURIComponent(teamId)}/capacity-providers/${encodeURIComponent(providerId)}`, {
|
|
291
|
+
method: "PATCH",
|
|
292
|
+
body: {
|
|
293
|
+
name: String(recordValue(provider, "name") ?? providerId),
|
|
294
|
+
creditBudgetMode: "hybrid"
|
|
295
|
+
},
|
|
296
|
+
requireAuth: true
|
|
297
|
+
});
|
|
298
|
+
await marketRequest(client, `/v1/teams/${encodeURIComponent(teamId)}/capacity-providers/${encodeURIComponent(providerId)}/execution-providers`, {
|
|
299
|
+
method: "POST",
|
|
300
|
+
body: executionProvider,
|
|
301
|
+
requireAuth: true
|
|
302
|
+
});
|
|
303
|
+
if (grant) {
|
|
304
|
+
await marketRequest(client, `/v1/teams/${encodeURIComponent(teamId)}/capacity-grants`, {
|
|
305
|
+
method: "POST",
|
|
306
|
+
body: grant,
|
|
307
|
+
requireAuth: true
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return guidedResult({
|
|
312
|
+
command: "capacity migrate",
|
|
313
|
+
summary: dryRun ? "Dry run: derived native capacity migration plan." : "Derived native capacity migration applied.",
|
|
314
|
+
facts: [
|
|
315
|
+
{ label: "Market", value: `${profile.id} (${profile.baseUrl})` },
|
|
316
|
+
{ label: "Team", value: teamId },
|
|
317
|
+
{ label: "Provider", value: providerId },
|
|
318
|
+
{ label: "Native limit", value: `${formatNumber(limitAmount)} ${nativeUnit} / ${scope}` },
|
|
319
|
+
{ label: "Reserve buffer", value: `${formatNumber(reserveBufferPercent)}%` },
|
|
320
|
+
{ label: "Allocation percent", value: allocationPercent === null ? null : `${formatNumber(allocationPercent)}%` },
|
|
321
|
+
{ label: "Dry run", value: dryRun }
|
|
322
|
+
],
|
|
323
|
+
sections: [
|
|
324
|
+
{ title: "Execution provider", lines: [`${executionProvider.name}: ${kind}, ${nativeUnit}, ${maxConcurrentWorkers} workers, ${quotaVisibility} quota visibility`] },
|
|
325
|
+
...grant ? [{ title: "Allocation grant", lines: [`${grant.grantScope} ${projectId ?? teamId} in ${environment}: ${formatNumber(allocationPercent)}%`] }] : []
|
|
326
|
+
],
|
|
327
|
+
report: {
|
|
328
|
+
action: "migrate",
|
|
329
|
+
dryRun,
|
|
330
|
+
teamId,
|
|
331
|
+
providerId,
|
|
332
|
+
executionProvider,
|
|
333
|
+
grant
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
}
|
|
111
337
|
function lifecycleActionRequiresConnection(action) {
|
|
112
338
|
return action === "up" || action === "restart";
|
|
113
339
|
}
|
|
@@ -256,6 +482,7 @@ function invokeProviderEntrypoint(action, invocation, context) {
|
|
|
256
482
|
],
|
|
257
483
|
sections: [
|
|
258
484
|
{ title: "Output", lines: stdout ? stdout.split(/\r?\n/u) : [] },
|
|
485
|
+
{ title: "Native budget file", lines: nativeBudgetSummaryLines(report) },
|
|
259
486
|
{ title: "Errors", lines: stderr ? stderr.split(/\r?\n/u) : [] }
|
|
260
487
|
],
|
|
261
488
|
exitCode: result.status ?? 1,
|
|
@@ -268,6 +495,21 @@ function invokeProviderEntrypoint(action, invocation, context) {
|
|
|
268
495
|
}
|
|
269
496
|
const handleCapacity = (invocation, context) => {
|
|
270
497
|
const action = invocation.positionals[0] ?? "doctor";
|
|
498
|
+
if (action === "plan" && stringArg(invocation, "project")) {
|
|
499
|
+
try {
|
|
500
|
+
return runProjectCapacityPlan(invocation, context);
|
|
501
|
+
} catch (error) {
|
|
502
|
+
return fail(error instanceof Error ? error.message : String(error));
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if (MARKET_CAPACITY_ACTIONS.has(action)) {
|
|
506
|
+
try {
|
|
507
|
+
if (action === "migrate") return runMigrateToDerived(invocation, context);
|
|
508
|
+
return fail(`Unknown capacity action "${action}".`);
|
|
509
|
+
} catch (error) {
|
|
510
|
+
return fail(error instanceof Error ? error.message : String(error));
|
|
511
|
+
}
|
|
512
|
+
}
|
|
271
513
|
if (PROVIDER_LIFECYCLE_ACTIONS.has(action)) {
|
|
272
514
|
try {
|
|
273
515
|
return runLifecycleAction(action, invocation, context);
|
|
@@ -282,7 +524,7 @@ const handleCapacity = (invocation, context) => {
|
|
|
282
524
|
return fail(error instanceof Error ? error.message : String(error));
|
|
283
525
|
}
|
|
284
526
|
}
|
|
285
|
-
return fail(`Unknown capacity action "${action}". Use doctor, register, plan, build, up, down, restart, logs, status, or test-local.`);
|
|
527
|
+
return fail(`Unknown capacity action "${action}". Use doctor, register, plan, migrate, build, up, down, restart, logs, status, or test-local.`);
|
|
286
528
|
};
|
|
287
529
|
export {
|
|
288
530
|
handleCapacity
|
|
@@ -1523,16 +1523,28 @@ const CLI_ONLY_OPERATION_SPECS = [
|
|
|
1523
1523
|
name: "capacity",
|
|
1524
1524
|
aliases: [],
|
|
1525
1525
|
group: "Utilities",
|
|
1526
|
-
summary: "
|
|
1527
|
-
description: "
|
|
1526
|
+
summary: "Inspect capacity plans and operate the package-owned capacity provider runtime.",
|
|
1527
|
+
description: "Read Market capacity plans, migrate static providers to derived native capacity, and run provider diagnostics through the built @treeseed/agent entrypoint.",
|
|
1528
1528
|
provider: "default",
|
|
1529
1529
|
related: ["teams", "projects", "agents"],
|
|
1530
|
-
usage: "treeseed capacity [doctor|register|plan|up|down|restart|logs|status|build|test-local]",
|
|
1530
|
+
usage: "treeseed capacity [doctor|register|plan|migrate|up|down|restart|logs|status|build|test-local]",
|
|
1531
1531
|
arguments: [{ name: "action", description: "Capacity action.", required: false }],
|
|
1532
1532
|
options: [
|
|
1533
1533
|
{ name: "market", flags: "--market <id-or-url>", description: "Select a configured market id or direct market API URL.", kind: "string" },
|
|
1534
1534
|
{ name: "provider", flags: "--provider <provider-id>", description: "Provider id or local provider selector for diagnostics.", kind: "string" },
|
|
1535
|
+
{ name: "team", flags: "--team <team-id>", description: "Team id for Market capacity migration.", kind: "string" },
|
|
1536
|
+
{ name: "project", flags: "--project <project-id>", description: "Project id for Market capacity plan or allocation migration.", kind: "string" },
|
|
1535
1537
|
{ name: "environment", flags: "--environment <scope>", description: "Treeseed config scope used when resolving encrypted provider launch values.", kind: "enum", values: ["local", "staging", "prod"] },
|
|
1538
|
+
{ name: "toDerived", flags: "--to-derived", description: "Migrate a static provider to derived native capacity facts.", kind: "boolean" },
|
|
1539
|
+
{ name: "kind", flags: "--kind <provider-kind>", description: "Execution provider kind such as codex_subscription or openrouter.", kind: "string" },
|
|
1540
|
+
{ name: "nativeUnit", flags: "--native-unit <unit>", description: "Native unit humans can forecast, such as wall_minute, usd, or billable_token.", kind: "string" },
|
|
1541
|
+
{ name: "limit", flags: "--limit <amount>", description: "Native limit amount for the selected scope.", kind: "string" },
|
|
1542
|
+
{ name: "scope", flags: "--scope <scope>", description: "Native limit scope, usually daily or monthly.", kind: "string" },
|
|
1543
|
+
{ name: "resetCadence", flags: "--reset-cadence <cadence>", description: "Native limit reset cadence.", kind: "string" },
|
|
1544
|
+
{ name: "quotaVisibility", flags: "--quota-visibility <mode>", description: "Whether quota remaining is visible, sampled, or opaque.", kind: "string" },
|
|
1545
|
+
{ name: "reserveBufferPercent", flags: "--reserve-buffer-percent <percent>", description: "Native reserve buffer percentage.", kind: "string" },
|
|
1546
|
+
{ name: "maxConcurrentWorkers", flags: "--max-concurrent-workers <count>", description: "Maximum workers this execution provider can run concurrently.", kind: "string" },
|
|
1547
|
+
{ name: "portfolioAllocationPercent", flags: "--portfolio-allocation-percent <percent>", description: "Optional project/team allocation percent to create during migration.", kind: "string" },
|
|
1536
1548
|
{ name: "dataDir", flags: "--data-dir <path>", description: "Host data directory mounted into the provider container at /data.", kind: "string" },
|
|
1537
1549
|
{ name: "agentPackageRoot", flags: "--agent-package-root <path>", description: "Path to a built @treeseed/agent package root.", kind: "string" },
|
|
1538
1550
|
{ name: "diagnostic", flags: "--diagnostic", description: "Start lifecycle commands without live Market registration or provider credentials.", kind: "boolean" },
|
|
@@ -1541,8 +1553,10 @@ const CLI_ONLY_OPERATION_SPECS = [
|
|
|
1541
1553
|
],
|
|
1542
1554
|
examples: [
|
|
1543
1555
|
"treeseed capacity doctor --market local --provider local",
|
|
1556
|
+
"treeseed capacity plan --market local --project project_123 --environment local",
|
|
1544
1557
|
"treeseed capacity register --market local --provider local --dry-run --json",
|
|
1545
1558
|
"treeseed capacity plan --market local --provider local --dry-run --json",
|
|
1559
|
+
"treeseed capacity migrate --to-derived --market local --team team_123 --provider provider_123 --kind codex_subscription --native-unit wall_minute --limit 480 --scope daily --dry-run",
|
|
1546
1560
|
"treeseed capacity build",
|
|
1547
1561
|
"treeseed capacity up --market local --provider local",
|
|
1548
1562
|
"treeseed capacity up --market local --provider local --diagnostic",
|
|
@@ -1552,8 +1566,8 @@ const CLI_ONLY_OPERATION_SPECS = [
|
|
|
1552
1566
|
"treeseed capacity test-local"
|
|
1553
1567
|
],
|
|
1554
1568
|
help: {
|
|
1555
|
-
longSummary: ["Capacity invokes the package-owned @treeseed/agent provider runtime for local diagnostics
|
|
1556
|
-
whenToUse: ["Use this when validating a self-hosted capacity provider install, checking provider runtime output, or running the local provider stack."],
|
|
1569
|
+
longSummary: ["Capacity reads Market project capacity plans, migrates provider setup toward derived native facts, and invokes the package-owned @treeseed/agent provider runtime for local diagnostics and Docker/Compose lifecycle commands."],
|
|
1570
|
+
whenToUse: ["Use this when inspecting native-to-credit projection, validating a self-hosted capacity provider install, checking provider runtime output, or running the local provider stack."],
|
|
1557
1571
|
beforeYouRun: ["Build @treeseed/agent first, or pass --agent-package-root to a built package. Use `trsd config` for encrypted provider values; capacity commands do not write plaintext env files."],
|
|
1558
1572
|
automationNotes: ["Use `--json` for stable provider runtime output. `up` runs live local provider mode by default; pass `--diagnostic` or use `test-local` for diagnostics without provider secrets."]
|
|
1559
1573
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treeseed/cli",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.6",
|
|
4
4
|
"description": "Operator-facing Treeseed CLI package.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"release:publish": "node ./scripts/run-ts.mjs ./scripts/publish-package.ts"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@treeseed/sdk": "github:treeseed-ai/sdk#0.10.
|
|
48
|
+
"@treeseed/sdk": "github:treeseed-ai/sdk#0.10.12",
|
|
49
49
|
"ink": "^7.0.0",
|
|
50
50
|
"react": "^19.2.5"
|
|
51
51
|
},
|