@rosthq/cli 0.7.18 → 0.7.20
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-manifest.d.ts","sourceRoot":"","sources":["../../src/generated/command-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,gBAAgB,EAAE,SAAS,oBAAoB,
|
|
1
|
+
{"version":3,"file":"command-manifest.d.ts","sourceRoot":"","sources":["../../src/generated/command-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,gBAAgB,EAAE,SAAS,oBAAoB,EAqN3D,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -37741,7 +37741,7 @@ var dryRunTranscriptSchema = external_exports.object({
|
|
|
37741
37741
|
}).strict();
|
|
37742
37742
|
|
|
37743
37743
|
// ../../packages/protocol/src/scrub.ts
|
|
37744
|
-
var SECRET_SHAPED_VALUE = /(sk-ant-|sk-proj-|sk-live-|BEGIN [A-Z ]*PRIVATE KEY|api[_-]?key\s*=|secret\s*=|password\s*=|authorization:\s*bearer\s+|x-api-key\s*:|api[-_ ]?key\s*:\s*\S{3,}|secret\s*:\s*\S{3,}|password\s*:\s*\S{3,}|token\s*:\s*\S{3,})/i;
|
|
37744
|
+
var SECRET_SHAPED_VALUE = /(sk-ant-|sk-proj-|sk-live-|sk-[A-Za-z0-9_-]{12,}|ghp_[A-Za-z0-9_]{12,}|github_pat_[A-Za-z0-9_]{20,}|xox[baprs]-[A-Za-z0-9-]{10,}|BEGIN [A-Z ]*PRIVATE KEY|api[_-]?key\s*=|secret\s*=|password\s*=|authorization:\s*bearer\s+|x-api-key\s*:|api[-_ ]?key\s*:\s*\S{3,}|secret\s*:\s*\S{3,}|password\s*:\s*\S{3,}|token\s*:\s*\S{3,})/i;
|
|
37745
37745
|
var SECRET_KEY = /(api[_-]?key|secret|password|token|authorization|credential|private[_-]?key)/i;
|
|
37746
37746
|
function hasSecretShapedContent(value) {
|
|
37747
37747
|
if (typeof value === "string") {
|
|
@@ -38735,6 +38735,16 @@ var agentTurnExecutionBrainSchema = external_exports.enum([
|
|
|
38735
38735
|
"claude-cli",
|
|
38736
38736
|
"codex-cli"
|
|
38737
38737
|
]);
|
|
38738
|
+
var aicosCloudBrainPreferenceSchema = external_exports.enum(["managed", "byok"]);
|
|
38739
|
+
var aicosRunnerBrainPreferenceSchema = external_exports.enum(["claude-cli", "codex-cli"]);
|
|
38740
|
+
var aicosAnswerBrainSchema = external_exports.enum(["managed", "byok", "claude-cli", "codex-cli", "mcp-client"]);
|
|
38741
|
+
var aicosBrainSelectionSchema = external_exports.object({
|
|
38742
|
+
cloud: aicosCloudBrainPreferenceSchema.default("managed"),
|
|
38743
|
+
runner: aicosRunnerBrainPreferenceSchema.default("claude-cli"),
|
|
38744
|
+
mcp: external_exports.literal("mcp-client").default("mcp-client"),
|
|
38745
|
+
effective: aicosAnswerBrainSchema.default("managed"),
|
|
38746
|
+
label: external_exports.string().min(1).max(80).default("Managed cloud")
|
|
38747
|
+
}).strict();
|
|
38738
38748
|
var agentTurnExecutionLaneSchema = external_exports.enum(["cloud", "mcp_session", "runner"]);
|
|
38739
38749
|
var agentTurnExecutionSchema = external_exports.object({
|
|
38740
38750
|
id: uuidSchema4,
|
|
@@ -38754,6 +38764,17 @@ var agentTurnExecutionSchema = external_exports.object({
|
|
|
38754
38764
|
createdAt: external_exports.string().datetime({ offset: true }),
|
|
38755
38765
|
updatedAt: external_exports.string().datetime({ offset: true })
|
|
38756
38766
|
}).strict();
|
|
38767
|
+
var aicosPendingTurnSchema = external_exports.object({
|
|
38768
|
+
id: uuidSchema4,
|
|
38769
|
+
userMessageId: uuidSchema4,
|
|
38770
|
+
assistantMessageId: uuidSchema4.nullable(),
|
|
38771
|
+
lane: agentTurnExecutionLaneSchema,
|
|
38772
|
+
brain: agentTurnExecutionBrainSchema,
|
|
38773
|
+
status: agentTurnExecutionStatusSchema,
|
|
38774
|
+
linkedRunId: uuidSchema4.nullable(),
|
|
38775
|
+
interactiveDeadline: external_exports.string().datetime({ offset: true }),
|
|
38776
|
+
updatedAt: external_exports.string().datetime({ offset: true })
|
|
38777
|
+
}).strict();
|
|
38757
38778
|
var aicosMessageRoleSchema = external_exports.enum(["user", "assistant", "tool", "system"]);
|
|
38758
38779
|
var aicosActorKindSchema = external_exports.enum(["user", "agent", "system"]);
|
|
38759
38780
|
var aicosSourceKindSchema = external_exports.enum([
|
|
@@ -38829,12 +38850,40 @@ var aicosCapabilitySnapshotSchema = external_exports.object({
|
|
|
38829
38850
|
runnerReady: external_exports.boolean().default(false),
|
|
38830
38851
|
laneReadiness: aicosLaneReadinessSchema.default(defaultLaneReadiness),
|
|
38831
38852
|
model: aicosModelSelectionSchema,
|
|
38853
|
+
brainSelection: aicosBrainSelectionSchema.default({
|
|
38854
|
+
cloud: "managed",
|
|
38855
|
+
runner: "claude-cli",
|
|
38856
|
+
mcp: "mcp-client",
|
|
38857
|
+
effective: "managed",
|
|
38858
|
+
label: "Managed cloud"
|
|
38859
|
+
}),
|
|
38832
38860
|
// Null/absent in company/general mode; set only for an authorized seat-scoped session.
|
|
38833
38861
|
seatScope: aicosSeatScopeSchema.nullable().optional()
|
|
38834
38862
|
}).strict();
|
|
38835
38863
|
var aicosLaneSettingsRequestSchema = external_exports.object({
|
|
38836
|
-
lane: aicosLaneSchema
|
|
38864
|
+
lane: aicosLaneSchema,
|
|
38865
|
+
cloudBrain: aicosCloudBrainPreferenceSchema.optional(),
|
|
38866
|
+
runnerBrain: aicosRunnerBrainPreferenceSchema.optional()
|
|
38837
38867
|
}).strict();
|
|
38868
|
+
var aicosBrainSettingsSchema = external_exports.object({
|
|
38869
|
+
lane: aicosLaneSchema,
|
|
38870
|
+
cloud_brain: aicosCloudBrainPreferenceSchema,
|
|
38871
|
+
runner_brain: aicosRunnerBrainPreferenceSchema,
|
|
38872
|
+
effective_brain: aicosAnswerBrainSchema,
|
|
38873
|
+
label: external_exports.string().min(1).max(80)
|
|
38874
|
+
}).strict();
|
|
38875
|
+
var aicosBrainSettingsGetInputSchema = external_exports.object({}).strict();
|
|
38876
|
+
var aicosBrainSettingsGetOutputSchema = external_exports.object({
|
|
38877
|
+
aicos: aicosBrainSettingsSchema
|
|
38878
|
+
}).strict();
|
|
38879
|
+
var aicosBrainSettingsUpdateInputSchema = external_exports.object({
|
|
38880
|
+
lane: aicosLaneSchema.optional(),
|
|
38881
|
+
cloud_brain: aicosCloudBrainPreferenceSchema.optional(),
|
|
38882
|
+
runner_brain: aicosRunnerBrainPreferenceSchema.optional()
|
|
38883
|
+
}).strict().refine(
|
|
38884
|
+
(value) => value.lane !== void 0 || value.cloud_brain !== void 0 || value.runner_brain !== void 0,
|
|
38885
|
+
"At least one AICOS lane or brain setting must be provided."
|
|
38886
|
+
);
|
|
38838
38887
|
var aicosSessionSchema = external_exports.object({
|
|
38839
38888
|
id: uuidSchema4,
|
|
38840
38889
|
title: external_exports.string().min(1),
|
|
@@ -38854,6 +38903,7 @@ var aicosMessageSchema = external_exports.object({
|
|
|
38854
38903
|
contentText: external_exports.string(),
|
|
38855
38904
|
routeContext: jsonObjectSchema,
|
|
38856
38905
|
onboardingContext: jsonObjectSchema,
|
|
38906
|
+
metadata: jsonObjectSchema.default({}),
|
|
38857
38907
|
linkedRunId: uuidSchema4.nullable(),
|
|
38858
38908
|
linkedWorkOrderId: uuidSchema4.nullable(),
|
|
38859
38909
|
sourceCount: external_exports.number().int().nonnegative().default(0),
|
|
@@ -38876,12 +38926,19 @@ var aicosTurnRequestSchema = external_exports.object({
|
|
|
38876
38926
|
routeContext: aicosRouteContextSchema,
|
|
38877
38927
|
model: aicosModelRequestSchema.optional()
|
|
38878
38928
|
}).strict();
|
|
38929
|
+
var aicosNavigationTargetSchema = external_exports.object({
|
|
38930
|
+
href: external_exports.string().trim().min(1).max(500),
|
|
38931
|
+
label: external_exports.string().trim().min(1).max(180),
|
|
38932
|
+
consentRequired: external_exports.literal(true)
|
|
38933
|
+
}).strict();
|
|
38879
38934
|
var aicosTurnResultSchema = external_exports.object({
|
|
38880
38935
|
session: aicosSessionSchema,
|
|
38881
38936
|
messages: external_exports.array(aicosMessageSchema),
|
|
38882
38937
|
sources: external_exports.array(aicosSourceSchema).default([]),
|
|
38883
38938
|
executionBackend: aicosLaneSchema,
|
|
38884
38939
|
status: aicosTurnStatusSchema,
|
|
38940
|
+
pendingTurn: aicosPendingTurnSchema.nullable().default(null),
|
|
38941
|
+
navigation: aicosNavigationTargetSchema.nullable().default(null),
|
|
38885
38942
|
userVisibleNextStep: external_exports.string().min(1),
|
|
38886
38943
|
capabilitySnapshot: aicosCapabilitySnapshotSchema,
|
|
38887
38944
|
context: aicosContextSummarySchema.optional()
|
|
@@ -42165,19 +42222,35 @@ var softwareProjectSummarySchema = external_exports.object({
|
|
|
42165
42222
|
base_branch: external_exports.string().min(1),
|
|
42166
42223
|
repo_ref: external_exports.string().nullable()
|
|
42167
42224
|
});
|
|
42225
|
+
var softwareProjectCreateInputSchema = external_exports.object({
|
|
42226
|
+
name: external_exports.string().trim().min(1).max(200).refine((value) => !hasSecretShapedValue(value), {
|
|
42227
|
+
message: "project name must not contain raw secret material"
|
|
42228
|
+
}),
|
|
42229
|
+
slug: external_exports.string().trim().regex(/^[a-z0-9][a-z0-9-]{0,62}$/).refine((value) => !hasSecretShapedValue(value), {
|
|
42230
|
+
message: "slug must not contain raw secret material"
|
|
42231
|
+
}).optional(),
|
|
42232
|
+
base_branch: external_exports.string().trim().min(1).max(255).refine((value) => !hasSecretShapedValue(value), {
|
|
42233
|
+
message: "base_branch must not contain raw secret material"
|
|
42234
|
+
}).default("main"),
|
|
42235
|
+
repo_ref: external_exports.string().trim().min(1).max(255).refine((value) => !hasSecretShapedValue(value), {
|
|
42236
|
+
message: "repo_ref must be repository metadata, never raw secret material"
|
|
42237
|
+
}).optional()
|
|
42238
|
+
}).strict();
|
|
42239
|
+
var softwareProjectCreateOutputSchema = external_exports.object({
|
|
42240
|
+
project: softwareProjectSummarySchema
|
|
42241
|
+
});
|
|
42168
42242
|
var softwareProjectListInputSchema = external_exports.object({}).strict();
|
|
42169
42243
|
var softwareProjectListOutputSchema = external_exports.object({
|
|
42170
42244
|
projects: external_exports.array(softwareProjectSummarySchema)
|
|
42171
42245
|
});
|
|
42172
42246
|
var VAULT_REF_PROVIDER = /^(?:infisical|doppler|local-dev):\/\/\S+$/;
|
|
42173
|
-
var
|
|
42174
|
-
var softwareVaultRefSchema = external_exports.string().min(1).max(500).regex(VAULT_REF_PROVIDER, "vault_ref must be a provider URI, e.g. infisical://path, doppler://path, or local-dev://path").refine((value) => !RAW_SECRET_SUBSTRING.test(value), {
|
|
42247
|
+
var softwareVaultRefSchema = external_exports.string().min(1).max(500).regex(VAULT_REF_PROVIDER, "vault_ref must be a provider URI, e.g. infisical://path, doppler://path, or local-dev://path").refine((value) => !hasSecretShapedValue(value), {
|
|
42175
42248
|
message: "vault_ref must be a pointer, never raw secret material"
|
|
42176
42249
|
});
|
|
42177
|
-
var softwareSecretKeyNameSchema = external_exports.string().trim().min(1).max(200).refine((value) => !
|
|
42250
|
+
var softwareSecretKeyNameSchema = external_exports.string().trim().min(1).max(200).refine((value) => !hasSecretShapedValue(value), {
|
|
42178
42251
|
message: "key_name must be a config key name, never raw secret material"
|
|
42179
42252
|
});
|
|
42180
|
-
var softwareSecretActionSchema = external_exports.string().trim().min(1).max(120).refine((value) => !
|
|
42253
|
+
var softwareSecretActionSchema = external_exports.string().trim().min(1).max(120).refine((value) => !hasSecretShapedValue(value), {
|
|
42181
42254
|
message: "action must be an action verb, never raw secret material"
|
|
42182
42255
|
});
|
|
42183
42256
|
var softwareTerminationBoundSchema = external_exports.object({
|
|
@@ -42419,7 +42492,7 @@ var softwareConfigSetInputSchema = external_exports.object({
|
|
|
42419
42492
|
if (!value.plain_value || value.vault_ref !== void 0) {
|
|
42420
42493
|
context.addIssue({ code: "custom", message: "plain config requires plain_value and no vault_ref" });
|
|
42421
42494
|
}
|
|
42422
|
-
if (value.plain_value &&
|
|
42495
|
+
if (value.plain_value && hasSecretShapedValue(value.plain_value)) {
|
|
42423
42496
|
context.addIssue({ code: "custom", message: "plain_value must never contain secret material" });
|
|
42424
42497
|
}
|
|
42425
42498
|
}
|
|
@@ -43460,11 +43533,11 @@ The Compass is drafted, then activated by a human through supersession.
|
|
|
43460
43533
|
order: 15,
|
|
43461
43534
|
title: "AICOS chat guide",
|
|
43462
43535
|
summary: "How the AI Chief of Staff chat works in the authenticated app shell and what it can safely do today.",
|
|
43463
|
-
version: "2026-07-04.
|
|
43536
|
+
version: "2026-07-04.10",
|
|
43464
43537
|
public: true,
|
|
43465
43538
|
audiences: ["human", "in_app_agent"],
|
|
43466
43539
|
stages: ["company_setup", "operating_rhythm"],
|
|
43467
|
-
relatedCommandIds: ["confirmation.approve", "onboarding.status", "graph.get", "seat.get", "mcp_token.list", "runner.list"],
|
|
43540
|
+
relatedCommandIds: ["confirmation.approve", "onboarding.status", "graph.get", "seat.get", "mcp_token.list", "runner.list", "aicos.brain_settings.get", "aicos.brain_settings.update"],
|
|
43468
43541
|
legal: {
|
|
43469
43542
|
publicRisk: "low",
|
|
43470
43543
|
notes: [
|
|
@@ -43514,15 +43587,19 @@ Each turn carries server-normalized page context: route template, current path,
|
|
|
43514
43587
|
|
|
43515
43588
|
The current chat harness shows the effective lane and model. Cloud is the default and remains the enforced lane during onboarding, even if a post-onboarding lane has been selected. After onboarding, an owner or admin can select cloud, runner, or MCP only when the server says that lane is ready. Lane changes update the governed AICOS agent seat and write an append-only audit event; the browser never decides tenant authority or runner/MCP readiness.
|
|
43516
43589
|
|
|
43590
|
+
AICOS also has an explicit brain selection. Cloud can use the included managed allowance or a tenant Anthropic key (BYOK). Runner can target the paired machine's Claude subscription or Codex subscription. MCP is labeled as the MCP client. Read this selection with \`aicos.brain_settings.get\`; owners can update it with \`aicos.brain_settings.update\` (CLI flags: \`--lane\`, \`--cloud-brain managed|byok\`, \`--runner-brain claude-cli|codex-cli\`). BYOK requires an active tenant Anthropic key. Runner and MCP answers are labeled in the transcript and do not consume the managed cloud allowance.
|
|
43591
|
+
|
|
43517
43592
|
Runner mode uses the same AICOS sessions and transcript. Interactive chat turns are tracked separately from scheduled work orders: each user message has one user-owned turn execution with a short deadline, so two users' chat messages cannot collapse into the same scheduled-work slot. Scheduled and Forge runner work still use work orders. Runner claim packets carry ids and execution metadata, not the user's free-text request. After claim, the local runner calls the governed AICOS context-load tool, which re-checks seat scope and returns the bounded transcript, session summary, route context, tenant clock, grounding text, and source counts authorized for that turn. The runner treats that loaded tenant clock and context as authoritative instead of substituting its own runtime clock or local files. A runner must be paired, execute-ready, and backed by the live AICOS agent before it can be selected.
|
|
43518
43593
|
|
|
43519
|
-
When a runner claims an interactive AICOS turn, the runner reports start and final result back to {{brand}}. The server appends exactly one assistant transcript message for the result, links that message to run evidence, and treats duplicate or late result reports as idempotent. If a queued, claimed, or running interactive turn passes its short deadline before a runner writes back, the turn is marked offline and the transcript receives a terminal assistant message instead of leaving a permanent "queued" placeholder.
|
|
43594
|
+
When a runner claims an interactive AICOS turn, the runner reports start and final result back to {{brand}}. The server appends exactly one assistant transcript message for the result, links that message to run evidence, and treats duplicate or late result reports as idempotent. If the runner answer includes a validated in-app link, the web panel can surface the same consent-required navigation suggestion once polling sees that the pending turn is terminal. If a queued, claimed, or running interactive turn passes its short deadline before a runner writes back, the turn is marked offline and the transcript receives a terminal assistant message instead of leaving a permanent "queued" placeholder.
|
|
43595
|
+
|
|
43596
|
+
While a runner turn is queued, claimed, or running, the chat panel keeps showing the pending state and polls the session until the answer or terminal status arrives. The composer, model picker, and lane picker are disabled during that active turn so a second browser tab or direct API call cannot overlap another runner turn in the same thread. Terminal runner statuses such as failed, offline, or canceled stay visible only while they are still the latest user turn; if the user continues the conversation in another lane, the stale terminal marker is no longer projected at the bottom of the thread.
|
|
43520
43597
|
|
|
43521
43598
|
MCP mode uses the existing tenant-authorized MCP surfaces. It requires an active seat-scoped MCP token for the AICOS seat and does not grant hidden tenant-admin access or run browser-side MCP tool calls. Users operate MCP AICOS from their authorized agent interface; the web chat remains the same readable thread surface.
|
|
43522
43599
|
|
|
43523
43600
|
Model behavior is now explicit in the AICOS session contract. A thread can run in **Auto** or use a pinned compatible model from the guided catalog. Auto chooses a fast tier for short low-risk turns, the balanced default for normal operating help, and a higher-reasoning tier for onboarding synthesis or large context. The panel shows the effective model, disables lower-context choices once the active thread outgrows them, and tells the user to start a new session for those models. Session context is estimated and maintained as a bounded rolling summary for memory search; when the thread crosses the configured threshold, that summary becomes the compacted context for future model calls rather than resending the whole thread. Raw messages remain in history. Summaries preserve durable decision cues, open questions, linked artifacts or objects, and unresolved setup facts where the transcript contains them.
|
|
43524
43601
|
|
|
43525
|
-
Assistant answers render safe Markdown for headings, short lists, emphasis, code, tables, and in-app links. User messages remain plain escaped text. Links only become clickable when they target same-origin app routes such as \`/inbox\` or \`/settings\`; external, protocol, script,
|
|
43602
|
+
Assistant answers render safe Markdown for headings, short lists, emphasis, code, tables, and in-app links. User messages remain plain escaped text. Links only become clickable when they target same-origin app routes such as \`/inbox\` or \`/settings\`; external, protocol, script, API-style, or traversal targets are stripped to plain text before transcript storage. When an answer includes a validated app route, the chat can surface one consent-required navigation suggestion and, if the user has enabled the local preference, open that route automatically. Navigation is never authorization; destination pages still enforce their own tenant, role, and seat checks.
|
|
43526
43603
|
|
|
43527
43604
|
AICOS can also retrieve bounded summaries from prior sessions owned by the same tenant user and surface them as session-memory read models. Setup-limited users do not retrieve sensitive historical run or company-memory summaries through this path. This is a practical memory seam for AICOS continuity; it is not yet the future Company Brain, and it does not make unaccepted knowledge authoritative.
|
|
43528
43605
|
|
|
@@ -44339,7 +44416,7 @@ External connectors are being rolled out provider by provider, conservatively (r
|
|
|
44339
44416
|
order: 48,
|
|
44340
44417
|
title: "CLI and MCP installation guide",
|
|
44341
44418
|
summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
|
|
44342
|
-
version: "2026-07-
|
|
44419
|
+
version: "2026-07-04.1",
|
|
44343
44420
|
public: true,
|
|
44344
44421
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
44345
44422
|
stages: ["company_setup", "staffing"],
|
|
@@ -44816,6 +44893,7 @@ The signed-in app exposes the same Skill command surface under **Skills** in the
|
|
|
44816
44893
|
| \`{{cli}} deliverable list|get|create|attach\` | \`deliverable.list\`, \`deliverable.get\`, \`deliverable.create\`, \`deliverable.attach\` | List, get, create, or attach agent deliverables for a seat. Deliverables are durable work outputs visible across UI, CLI, and MCP. | Tenant (list/get), Seat (create/attach) | \`{{cli}} deliverable list --seat-id <id> --json\`; \`{{cli}} deliverable create --title "Brief" --kind brief\` |
|
|
44817
44894
|
| \`{{cli}} graph show\` | \`graph.get\` | Print a table view of the Responsibility Graph with explicit \`seat_id\` and \`parent_seat_id\` columns. | Tenant | \`{{cli}} graph show\` |
|
|
44818
44895
|
| \`{{cli}} seat list|get|create|rename|reparent|decommission\` | \`graph.get\`, \`seat.get\`, \`seat.create\`, \`seat.rename\`, \`seat.reparent\`, \`seat.decommission\`, \`seat.decommission_preview\` | Work with seats as first-class CLI primitives. \`seat decommission --dry-run\` previews affected occupancies, agents, Charters, tokens, credentials, work orders, and schedules before the human-gated teardown. | Tenant / Seat for targeted mutations | \`{{cli}} seat list\`; \`{{cli}} seat decommission --seat-id <id> --dry-run\` |
|
|
44896
|
+
| \`{{cli}} forge project-create|project-list|request-create|request-list|request-show\` | \`software_factory.project.create\`, \`software_factory.project.list\`, \`software_factory.request.create\`, \`software_factory.request.list\`, \`software_factory.request.show\` | Create/list Forge projects and open/read governed Forge build requests. Project creation is tenant-admin, entitlement-gated, and human-gated; reads and request creation require the Forge add-on. | Tenant / Tenant-admin for create | \`{{cli}} forge project-create --name "Leiluna app" --base-branch main\`; \`{{cli}} forge request-create --software-project-id <id> --title "Add invoice export"\` |
|
|
44819
44897
|
|
|
44820
44898
|
Skills wrapper help:
|
|
44821
44899
|
|
|
@@ -44988,6 +45066,8 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
|
|
|
44988
45066
|
| \`rost_update_product_learning_policy\` | \`settings.product_learning.update\` | Set product-learning mode. | Tenant-admin | Human-gated; call with \`{"mode":"enabled"}\`, \`{"mode":"disabled"}\`, or \`{"mode":"enterprise_contract"}\`. |
|
|
44989
45067
|
| \`rost_get_company_autonomy_ceiling\` | \`settings.agent_policy.get\` | Read the company autonomy ceiling (Company Guardrails): profile, enforcement, and max_autonomous_risk. | Tenant | Call with \`{}\`; metadata only. |
|
|
44990
45068
|
| \`rost_set_company_autonomy_ceiling\` | \`settings.agent_policy.update\` | Set the company autonomy ceiling. | Tenant-admin | Owner-only, human-gated; call with \`{"profile":"locked_down"}\` (or \`balanced\`/\`high_autonomy\`, or \`{"profile":"custom","max_autonomous_risk":"high"}\`). Enforced by default. |
|
|
45069
|
+
| \`rost_get_aicos_brain_settings\` | \`aicos.brain_settings.get\` | Read AICOS lane and brain labels for cloud managed/BYOK, runner Claude/Codex, and MCP client. | Tenant | Call with \`{}\`; returns enum labels only, never keys, vault refs, or runner secrets. |
|
|
45070
|
+
| \`rost_update_aicos_brain_settings\` | \`aicos.brain_settings.update\` | Update AICOS lane and cloud/runner brain preferences. | Tenant-admin | Owner-only and human-gated; call with \`{"lane":"runner","runner_brain":"codex-cli"}\` or \`{"cloud_brain":"byok"}\`. BYOK requires an active tenant Anthropic key. |
|
|
44991
45071
|
| \`rost_list_signals\` | \`signal.list\` | List measurables with their latest reading and on/off-track state. | Seat or tenant-admin | Call with \`{}\` to find measurable ids. |
|
|
44992
45072
|
| \`rost_get_signal\` | \`signal.get\` | Read a measurable with its full reading history. | Seat or tenant-admin | Call with \`{"measurable_id":"<id>"}\`. |
|
|
44993
45073
|
| \`rost_confirm_signal_reading\` | \`signal.confirm_reading\` | Confirm an unconfirmed reading as human-verified. | Seat or tenant-admin | Humans confirm; call with \`{"reading_id":"<id>"}\`. |
|
|
@@ -45053,6 +45133,7 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
|
|
|
45053
45133
|
| \`rost_assign_skill_to_seat\` | \`skill.assign_to_seat\` | Propose or human-approve a published Skill version for a Seat after dependency checks. Missing required tools block approval; optional tools warn. | Tenant-admin | Call with \`{"seat_id":"<seat-id>","slug":"invoice-review","status":"proposed","rationale":"Use for AP exception work."}\`. |
|
|
45054
45134
|
| \`rost_revoke_skill_from_seat\` | \`skill.revoke_from_seat\` | Human-gated revocation that stops future Skill use without deleting historical activations. | Tenant-admin | Call with \`{"assignment_id":"<assignment-id>"}\`; non-interactive callers receive a confirmation handoff. |
|
|
45055
45135
|
| \`rost_list_model_catalog\` | \`model.catalog\` | List guided model tiers \u2014 recommendations, token prices, cost bands, best-fit work, and model ids for \`--model\`. | Tenant | Call with \`{}\`. |
|
|
45136
|
+
| \`rost_create_a_forge_project\` | \`software_factory.project.create\` | Create an active Forge software project before binding repositories or opening build requests. Tenant-admin, human-gated, and entitlement-gated. | Tenant-admin | Call with \`{"name":"Leiluna app","slug":"leiluna-app","base_branch":"main"}\`; non-interactive callers receive a confirmation handoff. |
|
|
45056
45137
|
| \`rost_create_a_forge_build_request\` | \`software_factory.request.create\` | Open a governed Forge build request against a connected software project; records the request plus its initial intake phase run. Requires the Forge add-on; the title is untrusted display text. | Tenant | Call with \`{"software_project_id":"<project-id>","title":"Add invoice export"}\`. |
|
|
45057
45138
|
| \`rost_list_forge_projects\` | \`software_factory.project.list\` | List active Forge software projects so a tenant can choose a project for build requests, GitHub repository bindings, and config. | Tenant | Call with \`{}\`; use the returned \`id\` as \`software_project_id\`. |
|
|
45058
45139
|
| \`rost_list_forge_build_requests\` | \`software_factory.request.list\` | The Forge control-room board: build requests with status, current phase, and risk. Read-only; requires the Forge add-on. | Tenant | Call with \`{}\` or \`{"limit":20}\`. |
|
|
@@ -46085,11 +46166,11 @@ Do not claim that a live charge happened unless Stripe test/live evidence proves
|
|
|
46085
46166
|
order: 72,
|
|
46086
46167
|
title: "Settings guide",
|
|
46087
46168
|
summary: "How to use Settings as the control plane for company access, channels, providers, tokens, and operating defaults.",
|
|
46088
|
-
version: "2026-07-03.
|
|
46169
|
+
version: "2026-07-03.2",
|
|
46089
46170
|
public: true,
|
|
46090
46171
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
46091
46172
|
stages: ["company_setup", "staffing"],
|
|
46092
|
-
relatedCommandIds: ["onboarding.create_invite", "mcp_token.create", "mcp_token.revoke", "mcp_token.list", "integration.list", "integration.readiness", "integration.status", "integration.test", "settings.get", "settings.update", "tenant.rename", "settings.sync_brief_scope.get", "settings.sync_brief_scope.update", "settings.product_learning.get", "settings.product_learning.update", "settings.agent_policy.get", "settings.agent_policy.update"],
|
|
46173
|
+
relatedCommandIds: ["onboarding.create_invite", "mcp_token.create", "mcp_token.revoke", "mcp_token.list", "integration.list", "integration.readiness", "integration.status", "integration.test", "settings.get", "settings.update", "tenant.rename", "settings.sync_brief_scope.get", "settings.sync_brief_scope.update", "settings.product_learning.get", "settings.product_learning.update", "settings.agent_policy.get", "settings.agent_policy.update", "aicos.brain_settings.get", "aicos.brain_settings.update"],
|
|
46093
46174
|
legal: { publicRisk: "low", notes: ["{{brand}}-native settings guidance."] },
|
|
46094
46175
|
sources: [
|
|
46095
46176
|
{
|
|
@@ -46164,6 +46245,7 @@ Agents that run on {{brand}}-managed inference draw against a tenant inference b
|
|
|
46164
46245
|
- Set the hard cap with \`settings.update\` (CLI: \`{{cli}} settings update --hard-cap-usd <amount>\`). The optional soft cap warns before the hard cap and must be less than or equal to it.
|
|
46165
46246
|
- The sandbox dry run is free and is never blocked by the cap, so a fresh company can charter, dry-run, and take an agent live before setting a budget. The cap applies only to real managed-inference runs.
|
|
46166
46247
|
- A company that brings its own provider key (BYOK) is metered on that key and is not subject to the {{brand}}-managed hard cap. BYOK changes the provider account used for eligible cloud calls, not the Charter, tool guard, human gate, or data-retention posture; see the ai-model-data-handling-guide before making provider-handling claims.
|
|
46248
|
+
- AICOS cloud brain selection is managed with \`aicos.brain_settings.get\` and owner-gated \`aicos.brain_settings.update\`. Managed cloud answers draw from the included allowance; BYOK cloud answers meter against the tenant key. Runner Claude, Runner Codex, and MCP client answers are labeled separately and do not draw from the managed cloud allowance.
|
|
46167
46249
|
|
|
46168
46250
|
## Company autonomy ceiling (Company Guardrails)
|
|
46169
46251
|
|
|
@@ -48108,6 +48190,8 @@ var COMMAND_MANIFEST = [
|
|
|
48108
48190
|
{ "id": "agent.show_markdown", "namespace": "agent", "action": "show_markdown", "title": "Show agent setup as markdown", "description": "Compose a seat's agent setup, steward, model, tools, and Charter into a clean, human-skimmable markdown card for review.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Render a seat's agent setup, model, steward, tools, and Charter as a clean markdown card to show your human a quick review." },
|
|
48109
48191
|
{ "id": "agent.status", "namespace": "agent", "action": "status", "title": "Get agent status", "description": "Return the agent occupancy, lane, schedule, live/offline state, steward chain, dry-run result, and Runner availability for a seat.", "requiredScope": "seat", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Check an agent's lane, live state, steward chain, dry-run result, and Runner availability before relying on it." },
|
|
48110
48192
|
{ "id": "agent.update_schedule", "namespace": "agent", "action": "update_schedule", "title": "Update agent schedule", "description": "Set or clear the scheduled execution cron for a draft or live agent on a seat.", "requiredScope": "tenant", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "schedule_cron", "flag": "schedule-cron", "type": "string", "required": true }], "hasComplexInput": false, "help": "Set or clear an agent's scheduled execution; a live scheduled agent must keep a steward chain resolving to a human." },
|
|
48193
|
+
{ "id": "aicos.brain_settings.get", "namespace": "aicos", "action": "brain_settings.get", "title": "Get AICOS brain settings", "description": "Read the AICOS run lane and brain selection. Returns labels and enum settings only; no secrets or vault refs.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [], "hasComplexInput": false, "help": "Read the AICOS lane and brain selection labels without returning provider keys, vault refs, or runner secrets." },
|
|
48194
|
+
{ "id": "aicos.brain_settings.update", "namespace": "aicos", "action": "brain_settings.update", "title": "Update AICOS brain settings", "description": "Update the AICOS lane and cloud/runner brain preferences. Owner-only and audited.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "lane", "flag": "lane", "type": "enum", "required": false, "enumValues": ["cloud", "runner", "mcp"] }, { "name": "cloud_brain", "flag": "cloud-brain", "type": "enum", "required": false, "enumValues": ["managed", "byok"] }, { "name": "runner_brain", "flag": "runner-brain", "type": "enum", "required": false, "enumValues": ["claude-cli", "codex-cli"] }], "hasComplexInput": false, "help": "Owner-only update for AICOS cloud managed/BYOK and runner Claude/Codex preferences; BYOK requires an active tenant Anthropic key." },
|
|
48111
48195
|
{ "id": "cascade.import", "namespace": "cascade", "action": "import", "title": "Import Rocks from a ninety Rocks export", "description": "Bulk-import a ninety Rocks export into the Cascade as cycle goals under a company objective in the active cycle. Owners are seat names resolved to seats. Requires an active cycle and a target company objective (auto-selected when exactly one exists, else pass parent_objective_id). Idempotent \u2014 re-importing the same export is a no-op, and an existing cycle goal with the same objective + seat + title is skipped.", "requiredScope": "tenant_admin", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "dry_run", "flag": "dry-run", "type": "boolean", "required": false }, { "name": "parent_objective_id", "flag": "parent-objective-id", "type": "string", "required": false }], "hasComplexInput": true, "help": "Import a ninety Rocks export into the Cascade as cycle goals under a company objective in the active cycle; owners resolve to seats." },
|
|
48112
48196
|
{ "id": "charter.apply_seat_type_recommendation", "namespace": "charter", "action": "apply_seat_type_recommendation", "title": "Apply Charter seat-type recommendation", "description": "Apply the seat-type recommendation from a draft Charter.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "charter_version_id", "flag": "charter-version-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Apply seat-type recommendations only after the Charter clarifies work shape, risk, and Steward accountability." },
|
|
48113
48197
|
{ "id": "charter.approve", "namespace": "charter", "action": "approve", "title": "Approve charter", "description": "Approve a draft Charter as a human owner.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": false }, { "name": "charter_version_id", "flag": "charter-version-id", "type": "string", "required": false }, { "name": "apply_seat_type", "flag": "apply-seat-type", "type": "boolean", "required": false }], "hasComplexInput": true, "help": "Charter approval is a human decision that activates the seat's operating contract." },
|
|
@@ -48256,6 +48340,7 @@ var COMMAND_MANIFEST = [
|
|
|
48256
48340
|
{ "id": "software_factory.github.installation.bind", "namespace": "software_factory", "action": "github.installation.bind", "title": "Bind a Forge GitHub installation", "description": "Bind a GitHub App installation and selected repositories to Forge projects from the authenticated Forge GitHub settings flow. Owner-only and human-gated; webhook payloads never supply tenant authority.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": false, "fields": [{ "name": "app_slug", "flag": "app-slug", "type": "string", "required": false }, { "name": "installation_id", "flag": "installation-id", "type": "integer", "required": true }, { "name": "account_login", "flag": "account-login", "type": "string", "required": true }, { "name": "account_id", "flag": "account-id", "type": "integer", "required": true }, { "name": "account_type", "flag": "account-type", "type": "string", "required": true }], "hasComplexInput": true, "help": "Bind a GitHub App installation and selected repositories to Forge projects from the authenticated Forge GitHub settings flow. Owner-only and human-gated." },
|
|
48257
48341
|
{ "id": "software_factory.github.policy.upsert", "namespace": "software_factory", "action": "github.policy.upsert", "title": "Set a Forge GitHub automation policy", "description": "Set the server-side policy for GitHub actions and automation-mode ceilings. Owner-only and human-gated; production deploy remains human-gated.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": true }, { "name": "authority_profile_id", "flag": "authority-profile-id", "type": "string", "required": false }, { "name": "automation_mode_ceiling", "flag": "automation-mode-ceiling", "type": "enum", "required": false, "enumValues": ["plan_only", "pr_only", "merge_after_checks", "deploy_preview", "deploy_production"] }, { "name": "allowed_actions", "flag": "allowed-actions", "type": "array", "required": true, "itemType": "string" }, { "name": "requires_human_for", "flag": "requires-human-for", "type": "array", "required": true, "itemType": "string" }], "hasComplexInput": false, "help": "Set Forge's server-side GitHub automation policy for actions, mode ceilings, and human-gated operations." },
|
|
48258
48342
|
{ "id": "software_factory.phase.advance", "namespace": "software_factory", "action": "phase.advance", "title": "Advance a Forge build request phase", "description": "Advance a build request to the next phase, enforcing the closed phase state machine server-side (an illegal transition is rejected). Writes a phase-run row and updates the current phase. Entitlement-gated.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "build_request_id", "flag": "build-request-id", "type": "string", "required": true }, { "name": "to_phase", "flag": "to-phase", "type": "enum", "required": true, "enumValues": ["intake", "discovery_scoping", "plan_review", "implementation", "plan_conformance_review", "security_review", "qa_verification", "release_preview", "merge_or_deploy_gate", "closeout"] }, { "name": "owning_seat_id", "flag": "owning-seat-id", "type": "string", "required": false }, { "name": "note", "flag": "note", "type": "string", "required": false }], "hasComplexInput": false, "help": "Advance a build request to its next phase; the server enforces the closed phase state machine and rejects an illegal transition." },
|
|
48343
|
+
{ "id": "software_factory.project.create", "namespace": "software_factory", "action": "project.create", "title": "Create a Forge project", "description": "Create an active Forge software project before binding repositories or opening build requests. Tenant-admin, human-gated, and entitlement-gated.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "name", "flag": "name", "type": "string", "required": true }, { "name": "slug", "flag": "slug", "type": "string", "required": false }, { "name": "base_branch", "flag": "base-branch", "type": "string", "required": false }, { "name": "repo_ref", "flag": "repo-ref", "type": "string", "required": false }], "hasComplexInput": false, "help": "Create an active Forge software project before binding repositories or opening build requests. Tenant-admin and human-gated; requires the Forge add-on." },
|
|
48259
48344
|
{ "id": "software_factory.project.list", "namespace": "software_factory", "action": "project.list", "title": "List Forge projects", "description": "List active Forge software projects so a tenant can choose a project for build requests, GitHub repository bindings, and config. Read-only and entitlement-gated.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [], "hasComplexInput": false, "help": "List active Forge software projects so a tenant can choose a project for build requests, GitHub repository bindings, and config. Read-only; requires the Forge add-on." },
|
|
48260
48345
|
{ "id": "software_factory.request.create", "namespace": "software_factory", "action": "request.create", "title": "Create a Forge build request", "description": "Open a governed Forge build request against a connected software project. Records the request plus its initial intake phase run. Entitlement-gated (Forge add-on); the title is untrusted display text, never an instruction.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": true }, { "name": "title", "flag": "title", "type": "string", "required": true }, { "name": "source_channel", "flag": "source-channel", "type": "enum", "required": false, "enumValues": ["ui", "cli", "github_issue", "linear", "api"] }, { "name": "source_ref", "flag": "source-ref", "type": "string", "required": false }], "hasComplexInput": true, "help": "Open a governed Forge build request against a connected software project; the title is untrusted display text. Requires the Forge add-on." },
|
|
48261
48346
|
{ "id": "software_factory.request.list", "namespace": "software_factory", "action": "request.list", "title": "List Forge build requests", "description": "The Forge control-room board: the tenant's build requests with status, current phase, and risk/automation mode. Read-only, entitlement-gated.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "limit", "flag": "limit", "type": "integer", "required": false }], "hasComplexInput": false, "help": "List Forge build requests (the control-room board) with status, current phase, and risk. Read-only; requires the Forge add-on." },
|
|
@@ -50086,6 +50171,7 @@ function operationUsageLines(bin) {
|
|
|
50086
50171
|
// Local runner service lifecycle (DER-1142). The orchestrator mirrors this
|
|
50087
50172
|
// exact line into the mcp-and-cli-guide so the help/guide parity gate passes.
|
|
50088
50173
|
`${bin} runner install-service|start|stop|restart|status|logs|uninstall --name <name>`,
|
|
50174
|
+
`${bin} forge project-create|project-list|request-create|request-list|request-show`,
|
|
50089
50175
|
`${bin} notification settings|test|errors`,
|
|
50090
50176
|
`${bin} settings get|update|product-learning|agent-policy|rename`,
|
|
50091
50177
|
`${bin} member invite|update|remove`,
|
|
@@ -50823,7 +50909,8 @@ ${usage()}
|
|
|
50823
50909
|
let failed = false;
|
|
50824
50910
|
let activeSessions = 0;
|
|
50825
50911
|
do {
|
|
50826
|
-
const
|
|
50912
|
+
const detectedCapabilities = await detectCapabilities();
|
|
50913
|
+
const capabilities = capabilitiesForConfiguredRuntime(detectedCapabilities, config2.runtime);
|
|
50827
50914
|
try {
|
|
50828
50915
|
const heartbeat = await post2(fetchImpl, options.appUrl, "/api/runner/heartbeat", {
|
|
50829
50916
|
capabilities,
|
|
@@ -50928,6 +51015,19 @@ function effectiveExecutionRuntime(runtime, capabilities) {
|
|
|
50928
51015
|
}
|
|
50929
51016
|
return capabilities.claude.installed ? "claude" : null;
|
|
50930
51017
|
}
|
|
51018
|
+
function capabilitiesForConfiguredRuntime(capabilities, runtime) {
|
|
51019
|
+
return {
|
|
51020
|
+
...capabilities,
|
|
51021
|
+
claude: {
|
|
51022
|
+
...capabilities.claude,
|
|
51023
|
+
installed: runtime === "codex" ? false : capabilities.claude.installed
|
|
51024
|
+
},
|
|
51025
|
+
codex: {
|
|
51026
|
+
...capabilities.codex,
|
|
51027
|
+
installed: runtime === "codex" ? capabilities.codex.installed : false
|
|
51028
|
+
}
|
|
51029
|
+
};
|
|
51030
|
+
}
|
|
50931
51031
|
function requiredValue(args, index) {
|
|
50932
51032
|
const value = args[index + 1];
|
|
50933
51033
|
if (value === void 0 || value.startsWith("--")) {
|
|
@@ -51085,12 +51185,16 @@ async function executeClaimedUnit(fetchImpl, appUrl2, state, io, runtime, input)
|
|
|
51085
51185
|
if (started.status !== 200) {
|
|
51086
51186
|
throw new Error(`${claimedUnitLabel(input.kind)} start failed ${started.status}: ${redactForLog(JSON.stringify(started.json))}`);
|
|
51087
51187
|
}
|
|
51088
|
-
const
|
|
51188
|
+
const turnRuntime = runtimeForClaimedUnit(input.item, runtime, input.kind);
|
|
51189
|
+
const result = turnRuntime ? await runLocalTurn(appUrl2, input.item, turnRuntime, input.kind) : {
|
|
51190
|
+
ok: false,
|
|
51191
|
+
summary: `Runner runtime ${runtime} cannot execute requested ${String(input.item.brain ?? "unknown")} turn.`
|
|
51192
|
+
};
|
|
51089
51193
|
const reported = await post2(fetchImpl, appUrl2, input.resultPath(id), {
|
|
51090
51194
|
status: result.ok ? "succeeded" : "failed",
|
|
51091
51195
|
summary: result.summary,
|
|
51092
51196
|
log_ref: input.logRef(id),
|
|
51093
|
-
model: runtime === "codex" ? "codex-cli" : "claude-cli"
|
|
51197
|
+
model: (turnRuntime ?? runtime) === "codex" ? "codex-cli" : "claude-cli"
|
|
51094
51198
|
}, state.runner_secret);
|
|
51095
51199
|
if (reported.status !== 200) {
|
|
51096
51200
|
throw new Error(`${claimedUnitLabel(input.kind)} result failed ${reported.status}: ${redactForLog(JSON.stringify(reported.json))}`);
|
|
@@ -51101,6 +51205,15 @@ async function executeClaimedUnit(fetchImpl, appUrl2, state, io, runtime, input)
|
|
|
51101
51205
|
function claimedUnitLabel(kind) {
|
|
51102
51206
|
return kind === "work_order" ? "work order" : "turn execution";
|
|
51103
51207
|
}
|
|
51208
|
+
function runtimeForClaimedUnit(item, fallback, kind) {
|
|
51209
|
+
if (kind !== "turn_execution") {
|
|
51210
|
+
return fallback;
|
|
51211
|
+
}
|
|
51212
|
+
if (item.brain === "codex-cli") {
|
|
51213
|
+
return fallback === "codex" ? "codex" : null;
|
|
51214
|
+
}
|
|
51215
|
+
return fallback === "claude" ? "claude" : null;
|
|
51216
|
+
}
|
|
51104
51217
|
function runLocalTurn(appUrl2, workOrder, runtime, kind) {
|
|
51105
51218
|
return runtime === "codex" ? runCodexTurn(appUrl2, workOrder, kind) : runClaudeTurn(appUrl2, workOrder, kind);
|
|
51106
51219
|
}
|