@platless/axom-cli 0.1.0 → 0.3.13
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/README.md +1 -1
- package/dist/authScopes.js +19 -0
- package/dist/axom-patch/cli/README.md +110 -0
- package/dist/axom-patch/cli/pi-steering.json +37 -0
- package/dist/axom-patch/cli/probes/claude-late-async-terminal.mjs +34 -0
- package/dist/axom-patch/cli/probes/pi-steering.mjs +80 -0
- package/dist/axom-patch/cli/probes/qoder-steering.mjs +89 -0
- package/dist/axom-patch/cli/probes/qoder-subagent-origin.mjs +49 -0
- package/dist/axom-patch/cli/qoder-background-terminal.md +81 -0
- package/dist/axom-patch/cli/qoder-foreground-output.md +41 -0
- package/dist/axom-patch/cli/qoder-steering.json +52 -0
- package/dist/axom-patch/cli/qoder-steering.md +30 -0
- package/dist/axom-patch/cli/qoder-subagent-origin.json +73 -0
- package/dist/axom-patch/cli/qoder-subagent-subwork.md +73 -0
- package/dist/axom-patch/cli/runtime.json +37 -0
- package/dist/axom-patch/cli/steering/claude-steering-js.patch +89 -0
- package/dist/axom-patch/cli/steering/claude-steering-types.patch +28 -0
- package/dist/axom-patch/cli/steering/codex-steering.patch +57 -0
- package/dist/axom-patch/cli/steering/pi-steering.js +79 -0
- package/dist/cli.js +9 -1
- package/dist/commands/auth.js +4 -13
- package/dist/commands/execute.js +4 -4
- package/dist/commands/record.js +6 -6
- package/dist/commands/struct.js +4 -4
- package/dist/commands/workstation.js +2 -2
- package/dist/credentials.js +2 -2
- package/dist/install/claude/commands.js +13 -13
- package/dist/mcp.js +32 -14
- package/dist/workstation/acp/acpAgents.js +447 -166
- package/dist/workstation/acp/acpClient.js +232 -18
- package/dist/workstation/acp/acpSession.js +502 -74
- package/dist/workstation/acp/activityBusy.js +43 -0
- package/dist/workstation/acp/activityReporting.js +54 -0
- package/dist/workstation/acp/adoption.js +107 -49
- package/dist/workstation/acp/authUrlSniffer.js +36 -0
- package/dist/workstation/acp/contract.js +11 -6
- package/dist/workstation/acp/delegationMcp.js +24 -0
- package/dist/workstation/acp/draftInterceptor.js +9 -0
- package/dist/workstation/acp/managedPatches.js +228 -0
- package/dist/workstation/acp/patchAssets.js +63 -0
- package/dist/workstation/acp/permission.js +300 -34
- package/dist/workstation/acp/qoderStartup.js +45 -0
- package/dist/workstation/acp/registry/catalog.js +263 -4
- package/dist/workstation/acp/registry/detect.js +55 -0
- package/dist/workstation/acp/sessionScope.js +19 -0
- package/dist/workstation/acp/sessionUpdateMapper.js +39 -21
- package/dist/workstation/acp/terminalLogin.js +197 -0
- package/dist/workstation/acp/test/fakeAgent.js +185 -9
- package/dist/workstation/acp/validate.js +33 -5
- package/dist/workstation/agentSessions.js +532 -44
- package/dist/workstation/channels/agent.js +7 -1
- package/dist/workstation/channels/computer.js +152 -4
- package/dist/workstation/channels/management.js +3 -3
- package/dist/workstation/config.js +3 -1
- package/dist/workstation/connection/encryptedChannel.js +88 -21
- package/dist/workstation/daemon.js +25 -3
- package/dist/workstation/desktop/binding.js +36 -0
- package/dist/workstation/desktop/bridge.js +212 -0
- package/dist/workstation/desktop/flow-control.js +52 -0
- package/dist/workstation/desktop/focused-text.js +130 -0
- package/dist/workstation/desktop/protocol.js +35 -0
- package/dist/workstation/fileOps.js +277 -0
- package/dist/workstation/filePaths.js +174 -0
- package/dist/workstation/fileWorker.js +81 -0
- package/dist/workstation/fileWorkerClient.js +121 -0
- package/dist/workstation/oauth/deviceAuthorization.js +21 -12
- package/dist/workstation/protocol/agent.js +154 -5
- package/dist/workstation/protocol/common.js +6 -0
- package/dist/workstation/protocol/computer.js +92 -3
- package/dist/workstation/qoderAdapter/backgroundProcess.js +106 -0
- package/dist/workstation/qoderAdapter/backgroundTerminal.js +262 -0
- package/dist/workstation/qoderAdapter/completedContinuation.js +139 -0
- package/dist/workstation/qoderAdapter/contract.js +78 -0
- package/dist/workstation/qoderAdapter/foregroundOutput.js +30 -0
- package/dist/workstation/qoderAdapter/history.js +87 -0
- package/dist/workstation/qoderAdapter/identityIndex.js +191 -0
- package/dist/workstation/qoderAdapter/inputQueue.js +42 -0
- package/dist/workstation/qoderAdapter/main.js +93 -0
- package/dist/workstation/qoderAdapter/mapper.js +117 -0
- package/dist/workstation/qoderAdapter/observerPlugin.js +245 -0
- package/dist/workstation/qoderAdapter/observerReceiver.js +187 -0
- package/dist/workstation/qoderAdapter/permissions.js +61 -0
- package/dist/workstation/qoderAdapter/profile.js +93 -0
- package/dist/workstation/qoderAdapter/sdkDriver.js +49 -0
- package/dist/workstation/qoderAdapter/session.js +319 -0
- package/dist/workstation/qoderAdapter/subagentMeta.js +28 -0
- package/dist/workstation/qoderAdapter/subwork.js +77 -0
- package/dist/workstation/qoderAdapter/taskControl.js +38 -0
- package/dist/workstation/qoderAdapter/taskEvent.js +26 -0
- package/dist/workstation/qoderAdapter/taskLedger.js +163 -0
- package/dist/workstation/qoderAdapter/types.js +1 -0
- package/dist/workstation/qoderAdapter/usage.js +37 -0
- package/dist/workstation/register.js +4 -0
- package/dist/workstation/tools/browser.js +394 -0
- package/dist/workstation/tools/client.js +269 -0
- package/dist/workstation/tools/core.js +50 -0
- package/dist/workstation/tools/files.js +525 -0
- package/dist/workstation/tools/keeperProcess.js +114 -0
- package/dist/workstation/tools/terminal.js +214 -0
- package/dist/workstation/tools/validation.js +50 -0
- package/dist/workstation/update/coordinator.js +29 -0
- package/dist/workstation/update/npmInstaller.js +2 -0
- package/dist/workstation/update/ptyPreflight.js +24 -0
- package/dist/workstation/update/taskRegistry.js +44 -20
- package/dist/workstation/update/watchdog.js +66 -0
- package/package.json +14 -4
- package/skills/axom/SKILL.md +55 -17
- package/skills/axom-definition/SKILL.md +32 -32
- package/skills/axom-platform/SKILL.md +39 -39
|
@@ -54,8 +54,8 @@ async function ensureRegistered(deps, serverFlag, nameFlag) {
|
|
|
54
54
|
* that runs in `/workspace` — a container is precisely where this product runs untrusted code. What
|
|
55
55
|
* would leak is not the workstation's own key pair (scoped to one workstation, on disk) but a
|
|
56
56
|
* credential that authenticates *as the user*: it can register further workstations under their
|
|
57
|
-
* account and, with
|
|
58
|
-
* it. Fixed once here rather than filtered at each of the two spawn sites, so the next spawn site
|
|
57
|
+
* account and, with business scopes, call granted MCP tools as them, until somebody notices and
|
|
58
|
+
* revokes it. Fixed once here rather than filtered at each of the two spawn sites, so the next spawn site
|
|
59
59
|
* inherits the fix instead of having to remember it.
|
|
60
60
|
*
|
|
61
61
|
* Nothing after this point needs the value. The daemon authenticates with the file credential
|
package/dist/credentials.js
CHANGED
|
@@ -168,8 +168,8 @@ async function refreshRequest(server, refreshToken) {
|
|
|
168
168
|
}),
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
|
-
export async function revokeRefreshToken(server, refreshToken) {
|
|
172
|
-
await
|
|
171
|
+
export async function revokeRefreshToken(server, refreshToken, fetch_ = globalThis.fetch) {
|
|
172
|
+
await fetch_(`${normalizedServer(server)}/oauth/revoke`, {
|
|
173
173
|
method: 'POST',
|
|
174
174
|
headers: { 'content-type': 'application/x-www-form-urlencoded' },
|
|
175
175
|
body: new URLSearchParams({ token: refreshToken, token_type_hint: 'refresh_token', client_id: 'axom-cli' }),
|
|
@@ -8,8 +8,8 @@ Use the Axomwork MCP tools to answer this structural question about the platform
|
|
|
8
8
|
$ARGUMENTS
|
|
9
9
|
|
|
10
10
|
Workflow:
|
|
11
|
-
1. \`
|
|
12
|
-
2. \`
|
|
11
|
+
1. \`axom__app_struct__list_applications\` to see applications; \`axom__app_struct__get_application\` for one app's models and menus.
|
|
12
|
+
2. \`axom__app_struct__list_models\` / \`axom__app_struct__get_model\` for a model's attributes, operations, and display metadata.
|
|
13
13
|
3. Prefer read-only struct tools here; do not mutate anything from this command.
|
|
14
14
|
|
|
15
15
|
For the underlying concepts (applications, models, attributes, references), load guide \`concepts/data-model/index.md\` with \`axom__guide__load\`.
|
|
@@ -23,10 +23,10 @@ Use the Axomwork MCP record tools to fulfil this request:
|
|
|
23
23
|
$ARGUMENTS
|
|
24
24
|
|
|
25
25
|
Workflow:
|
|
26
|
-
1. Discover structure first when unsure: \`
|
|
27
|
-
2. Query with \`
|
|
28
|
-
3. Mutate with \`
|
|
29
|
-
4. \`
|
|
26
|
+
1. Discover structure first when unsure: \`axom__app_struct__get_model\` for attribute names and types.
|
|
27
|
+
2. Query with \`axom__record_query__query_records\` (filters/sorts/page criteria — for criteria syntax, load guide \`agent-integration/mcp/record-query-criteria.md\`).
|
|
28
|
+
3. Mutate with \`axom__record_write__create_record\` / \`axom__record_write__update_record\` / \`axom__record_write__upsert_record\` / \`axom__record_write__delete_record\`. Read the record first before updating; confirm with the user before deleting.
|
|
29
|
+
4. \`axom__record_write__upsert_record\` needs \`identityField\` and the identity value inside \`record\`.
|
|
30
30
|
|
|
31
31
|
For safe mutation patterns, load guide \`agent-integration/operating-patterns/safe-record-mutations.md\`.
|
|
32
32
|
`,
|
|
@@ -39,18 +39,18 @@ Execute the requested Axomwork operation or service:
|
|
|
39
39
|
$ARGUMENTS
|
|
40
40
|
|
|
41
41
|
Workflow:
|
|
42
|
-
1. Find the operation on its model (\`
|
|
43
|
-
2. Call \`
|
|
42
|
+
1. Find the operation on its model (\`axom__app_struct__get_model\`) or the service by name.
|
|
43
|
+
2. Call \`axom__execute__run_operation\` (applicationName/modelName/operationName/input) or \`axom__execute__run_service\` (serviceName/input).
|
|
44
44
|
3. Interpret the ExecuteResult payload: \`status\` (success/failure/running), \`message\`, \`text\`, \`returnValue\`, \`runId\`/\`runType\`, \`errors[]\` ({target,code,message}).
|
|
45
45
|
4. When \`status\` is \`running\`, follow \`runId\` (see \`runType\`) until a terminal state before reporting the outcome.
|
|
46
46
|
|
|
47
47
|
For sync-vs-job semantics load guide \`concepts/execution/synchronous-and-task-execution.md\`; for run following load guide \`agent-integration/operating-patterns/following-runs.md\`.
|
|
48
48
|
`,
|
|
49
49
|
definition: `---
|
|
50
|
-
description: Develop Axomwork definitions — apps, models, attributes, operations, workflows (requires
|
|
50
|
+
description: Develop Axomwork definitions — apps, models, attributes, operations, workflows (requires app_studio scope and an admin account)
|
|
51
51
|
---
|
|
52
52
|
|
|
53
|
-
You are editing Axomwork application definitions with the canonical \`
|
|
53
|
+
You are editing Axomwork application definitions with the canonical \`axom__app_studio__*\` MCP tools (requires the \`app_studio\` scope and an administrator account).
|
|
54
54
|
|
|
55
55
|
$ARGUMENTS
|
|
56
56
|
|
|
@@ -61,16 +61,16 @@ Rules:
|
|
|
61
61
|
4. Confirm destructive definition deletes with the user first.
|
|
62
62
|
`,
|
|
63
63
|
platform: `---
|
|
64
|
-
description: Operate Axomwork platform configuration — AI
|
|
64
|
+
description: Operate Axomwork platform configuration — AI providers/profiles, cowork agents, datasources, platform skills and settings (requires setting_platform scope and an admin account)
|
|
65
65
|
---
|
|
66
66
|
|
|
67
|
-
You are operating Axomwork platform configuration with the canonical \`
|
|
67
|
+
You are operating Axomwork platform configuration with the canonical \`axom__setting_platform__*\` MCP tools (skills, settings, AI providers/profiles/memory, cowork agents, data sources; requires the \`setting_platform\` scope and an administrator account).
|
|
68
68
|
|
|
69
69
|
$ARGUMENTS
|
|
70
70
|
|
|
71
71
|
Rules:
|
|
72
72
|
1. Read current configuration before editing; respect ETag guards where tools expose them.
|
|
73
|
-
2. For configuration semantics (AI
|
|
73
|
+
2. For configuration semantics (AI providers and profiles, cowork agents, datasources, platform skills and settings), load guide \`platform-operations/index.md\` first.
|
|
74
74
|
3. Confirm with the user before changes that can interrupt running workflows or agent sessions.
|
|
75
75
|
`,
|
|
76
76
|
guide: `---
|
package/dist/mcp.js
CHANGED
|
@@ -11,7 +11,7 @@ export async function callAxomTool(server, toolName, args) {
|
|
|
11
11
|
}
|
|
12
12
|
catch (error) {
|
|
13
13
|
if (isInsufficientScope(error))
|
|
14
|
-
throw insufficientScopeError(normalizedServer);
|
|
14
|
+
throw insufficientScopeError(normalizedServer, toolName);
|
|
15
15
|
if (!isUnauthorized(error))
|
|
16
16
|
throw error;
|
|
17
17
|
// An env token cannot be refreshed: `accessTokenFor` returns the same literal whatever
|
|
@@ -28,7 +28,7 @@ export async function callAxomTool(server, toolName, args) {
|
|
|
28
28
|
}
|
|
29
29
|
catch (error) {
|
|
30
30
|
if (isInsufficientScope(error))
|
|
31
|
-
throw insufficientScopeError(normalizedServer);
|
|
31
|
+
throw insufficientScopeError(normalizedServer, toolName);
|
|
32
32
|
if (isUnauthorized(error)) {
|
|
33
33
|
throw new AuthError(`MCP authentication failed with ${normalizedServer}. Run: axom auth --server ${normalizedServer}`);
|
|
34
34
|
}
|
|
@@ -45,7 +45,7 @@ async function callAxomToolOnce(server, token, toolName, args) {
|
|
|
45
45
|
try {
|
|
46
46
|
await client.connect(transport);
|
|
47
47
|
const result = await client.callTool({ name: toolName, arguments: args });
|
|
48
|
-
return toToolOutcome(result);
|
|
48
|
+
return addPermissionAdvice(toolName, toToolOutcome(result));
|
|
49
49
|
}
|
|
50
50
|
finally {
|
|
51
51
|
try {
|
|
@@ -89,12 +89,7 @@ function isUnauthorized(error) {
|
|
|
89
89
|
const message = error instanceof Error ? error.message : String(error);
|
|
90
90
|
return /\b401\b/.test(message);
|
|
91
91
|
}
|
|
92
|
-
/**
|
|
93
|
-
* `/mcp` returns 403 (not 401) when the bearer token is valid but lacks the `mcp` scope — this is
|
|
94
|
-
* how a `workstation`-only access token (the default for a token minted without `--scope mcp`)
|
|
95
|
-
* looks from the client. Retrying with a refreshed token would not help, since the new token would
|
|
96
|
-
* carry the same scopes, so this is checked before the 401/refresh path, not folded into it.
|
|
97
|
-
*/
|
|
92
|
+
/** A 403 is an authorization refusal, so refreshing the same grant cannot make it succeed. */
|
|
98
93
|
export function isInsufficientScope(error) {
|
|
99
94
|
const candidate = error;
|
|
100
95
|
if (candidate.status === 403 || candidate.code === 403 || candidate.response?.status === 403)
|
|
@@ -102,11 +97,34 @@ export function isInsufficientScope(error) {
|
|
|
102
97
|
const message = error instanceof Error ? error.message : String(error);
|
|
103
98
|
return /\b403\b/.test(message);
|
|
104
99
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
100
|
+
/** Abilities every credential has (Ability registry: BASELINE with the MCP surface). */
|
|
101
|
+
const BASELINE_TOOL_SCOPES = new Set(['system', 'guide', 'app_struct']);
|
|
102
|
+
const TOOL_SCOPE = /^axom__([a-z][a-z0-9]*(?:_[a-z0-9]+)*)__[a-z]/;
|
|
103
|
+
const ADMIN_NOTE = ' Scopes marked "Requires an administrator account" on the consent page also need an administrator user.';
|
|
104
|
+
/** An external tool's middle segment IS the OAuth scope that grants it (spec 2026-09-26 §3.5). */
|
|
105
|
+
export function scopeForTool(toolName) {
|
|
106
|
+
const scope = toolName ? TOOL_SCOPE.exec(toolName)?.[1] : undefined;
|
|
107
|
+
return scope && !BASELINE_TOOL_SCOPES.has(scope) ? scope : undefined;
|
|
108
|
+
}
|
|
109
|
+
export function insufficientScopeError(server, toolName) {
|
|
110
|
+
const scope = scopeForTool(toolName);
|
|
111
|
+
if (!scope)
|
|
112
|
+
return new AuthError(`MCP authorization was denied by ${server}. Check this credential's approved scopes.`);
|
|
113
|
+
const remedy = usesEnvAccessToken()
|
|
114
|
+
? ` Create or edit an access token under Settings → Security and grant ${scope}.`
|
|
115
|
+
: ` Run axom auth --server ${server} and select ${scope}.`;
|
|
116
|
+
return new AuthError(`MCP authorization was denied by ${server}. Required OAuth scope: ${scope}.${remedy}${ADMIN_NOTE}`);
|
|
117
|
+
}
|
|
118
|
+
function addPermissionAdvice(toolName, outcome) {
|
|
119
|
+
if (!outcome.isError || !isPermissionFailure(outcome.text))
|
|
120
|
+
return outcome;
|
|
121
|
+
const scope = scopeForTool(toolName);
|
|
122
|
+
if (!scope)
|
|
123
|
+
return outcome;
|
|
124
|
+
return { ...outcome, text: `${outcome.text}\nRequired OAuth scope: ${scope}.${ADMIN_NOTE}` };
|
|
125
|
+
}
|
|
126
|
+
function isPermissionFailure(message) {
|
|
127
|
+
return /permission denied|not authorized|forbidden|insufficient[_ ]scope|MCP grant is no longer valid/i.test(message);
|
|
110
128
|
}
|
|
111
129
|
/**
|
|
112
130
|
* Is this process authenticating with `AXOM_ACCESS_TOKEN` rather than a stored login? Mirrors
|