@skrr-ai/cli 0.1.64 → 0.1.66
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/dist/commands/agents/visibility.d.ts +9 -0
- package/dist/commands/agents/visibility.js +30 -0
- package/dist/commands/goals/plan-now.d.ts +6 -0
- package/dist/commands/goals/plan-now.js +25 -0
- package/dist/commands/memory/approvals/issue.js +6 -3
- package/dist/commands/memory/mounts/resolve.js +1 -2
- package/dist/commands/memory/save.d.ts +1 -0
- package/dist/commands/memory/save.js +16 -55
- package/dist/commands/memory/stores/list.js +1 -2
- package/dist/commands/memory/stores/update.js +6 -3
- package/dist/commands/skills/visibility.d.ts +15 -0
- package/dist/commands/skills/visibility.js +49 -0
- package/dist/commands/store/admissions/approve.d.ts +1 -0
- package/dist/commands/store/admissions/approve.js +9 -3
- package/dist/commands/store/admissions/list.js +6 -0
- package/dist/commands/store/admissions/refuse.d.ts +1 -0
- package/dist/commands/store/admissions/refuse.js +9 -3
- package/dist/commands/store/artifacts/release.d.ts +3 -0
- package/dist/commands/store/artifacts/release.js +42 -0
- package/dist/commands/store/update.js +5 -1
- package/dist/commands/store/updates.d.ts +1 -1
- package/dist/commands/store/updates.js +3 -3
- package/dist/commands/tasks/comments/list.d.ts +10 -0
- package/dist/commands/tasks/comments/list.js +53 -9
- package/dist/commands/tasks/comments/react.js +3 -1
- package/dist/commands/tasks/deliverable/add.d.ts +1 -0
- package/dist/commands/tasks/deliverable/add.js +13 -2
- package/dist/commands/tasks/deliverable/list.js +15 -1
- package/dist/commands/tasks/lifecycle/transition.js +6 -3
- package/dist/commands/tasks/plan/run-update.js +1 -1
- package/dist/commands/tasks/result/submit.js +1 -1
- package/dist/commands/tasks/resume/save.js +6 -3
- package/dist/commands/tasks/updates/add.js +11 -1
- package/dist/lib/file-mime.js +1 -0
- package/dist/lib/prompt.d.ts +7 -0
- package/dist/lib/prompt.js +16 -0
- package/dist/lib/scoped-memory-command.d.ts +4 -2
- package/dist/lib/scoped-memory-command.js +27 -3
- package/dist/lib/task-asset-upload.d.ts +5 -0
- package/dist/lib/task-asset-upload.js +4 -0
- package/dist/lib/task-closure.d.ts +3 -1
- package/dist/lib/task-closure.js +14 -4
- package/dist/node_modules/@skrr-ai/data-provider/index.js +13 -5
- package/oclif.manifest.json +27743 -27621
- package/package.json +1 -1
|
@@ -10,6 +10,14 @@ export declare function parseCapabilityRationales(entries: readonly string[] | u
|
|
|
10
10
|
rationales?: Record<string, string>;
|
|
11
11
|
error?: string;
|
|
12
12
|
};
|
|
13
|
+
export declare function parseReleaseDependencies(entries: readonly string[] | undefined): {
|
|
14
|
+
dependencies?: Array<{
|
|
15
|
+
entityType: 'skill' | 'action';
|
|
16
|
+
entityId: string;
|
|
17
|
+
artifactVersionId: string;
|
|
18
|
+
}>;
|
|
19
|
+
error?: string;
|
|
20
|
+
};
|
|
13
21
|
export default class AgentsVisibility extends BaseCommand {
|
|
14
22
|
static description: string;
|
|
15
23
|
static examples: string[];
|
|
@@ -27,6 +35,7 @@ export default class AgentsVisibility extends BaseCommand {
|
|
|
27
35
|
'version-minor': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
28
36
|
'capability-rationale': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
29
37
|
language: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
38
|
+
dependency: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
30
39
|
};
|
|
31
40
|
run(): Promise<void>;
|
|
32
41
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseCapabilityRationales = parseCapabilityRationales;
|
|
4
|
+
exports.parseReleaseDependencies = parseReleaseDependencies;
|
|
4
5
|
const core_1 = require("@oclif/core");
|
|
5
6
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
7
|
const base_command_1 = require("../../base-command");
|
|
@@ -28,6 +29,23 @@ function parseCapabilityRationales(entries) {
|
|
|
28
29
|
}
|
|
29
30
|
return { rationales };
|
|
30
31
|
}
|
|
32
|
+
function parseReleaseDependencies(entries) {
|
|
33
|
+
if (!entries?.length)
|
|
34
|
+
return {};
|
|
35
|
+
const dependencies = [];
|
|
36
|
+
for (const entry of entries) {
|
|
37
|
+
const match = /^(skill|action):([^@]+)@(store_release_[A-Za-z0-9_-]+)$/.exec(entry);
|
|
38
|
+
if (!match) {
|
|
39
|
+
return { error: `--dependency expects skill:<id>@<store-release-id> or action:<id>@<store-release-id>, got "${entry}".` };
|
|
40
|
+
}
|
|
41
|
+
dependencies.push({
|
|
42
|
+
entityType: match[1],
|
|
43
|
+
entityId: match[2],
|
|
44
|
+
artifactVersionId: match[3],
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return { dependencies };
|
|
48
|
+
}
|
|
31
49
|
class AgentsVisibility extends base_command_1.BaseCommand {
|
|
32
50
|
static description = 'Set the visibility of an agent (accounts with 2FA need recent step-up for public publishing)';
|
|
33
51
|
static examples = [
|
|
@@ -37,6 +55,7 @@ class AgentsVisibility extends base_command_1.BaseCommand {
|
|
|
37
55
|
'<%= config.bin %> agents visibility <agent-id> --public --json',
|
|
38
56
|
'<%= config.bin %> agents visibility <agent-id> --public --capability-rationale "network:*=Looks up flight prices on the web"',
|
|
39
57
|
'<%= config.bin %> agents visibility <agent-id> --public --language en --language zh-Hans',
|
|
58
|
+
'<%= config.bin %> agents visibility <agent-id> --public --dependency skill:<skill-id>@<store-release-id>',
|
|
40
59
|
];
|
|
41
60
|
static args = {
|
|
42
61
|
id: core_1.Args.string({ description: 'Agent ID', required: true, ignoreStdin: true }),
|
|
@@ -72,6 +91,10 @@ class AgentsVisibility extends base_command_1.BaseCommand {
|
|
|
72
91
|
description: 'A language the release works in, as a BCP 47 tag such as en or zh-Hans (repeatable). Shown on the listing as declared by you; the platform does not check it.',
|
|
73
92
|
multiple: true,
|
|
74
93
|
}),
|
|
94
|
+
dependency: core_1.Flags.string({
|
|
95
|
+
description: 'Pin an attached Skill or Action to its immutable Store release: skill:<id>@<store-release-id> (repeatable)',
|
|
96
|
+
multiple: true,
|
|
97
|
+
}),
|
|
75
98
|
};
|
|
76
99
|
async run() {
|
|
77
100
|
this.requireAuth();
|
|
@@ -84,6 +107,12 @@ class AgentsVisibility extends base_command_1.BaseCommand {
|
|
|
84
107
|
if (rationaleError) {
|
|
85
108
|
this.error(rationaleError, { exit: 1 });
|
|
86
109
|
}
|
|
110
|
+
const { dependencies, error: dependencyError } = parseReleaseDependencies(flags.dependency);
|
|
111
|
+
if (dependencyError)
|
|
112
|
+
this.error(dependencyError, { exit: 1 });
|
|
113
|
+
if (dependencies && !isPublic) {
|
|
114
|
+
this.error('--dependency declares pins on a public release; pass it with --public.', { exit: 1 });
|
|
115
|
+
}
|
|
87
116
|
if (capabilityRationales && !isPublic) {
|
|
88
117
|
this.error('--capability-rationale applies only when publishing with --public.', {
|
|
89
118
|
exit: 1,
|
|
@@ -131,6 +160,7 @@ class AgentsVisibility extends base_command_1.BaseCommand {
|
|
|
131
160
|
versionMinor: flags['version-minor'],
|
|
132
161
|
capabilityRationales,
|
|
133
162
|
supportedLanguages: flags.language,
|
|
163
|
+
dependencies,
|
|
134
164
|
});
|
|
135
165
|
}
|
|
136
166
|
catch (err) {
|
|
@@ -23,6 +23,12 @@ export declare function describePlannerReason(reason: string | null | undefined)
|
|
|
23
23
|
* saying so.
|
|
24
24
|
*/
|
|
25
25
|
export declare function plannerTickDidNotRun(result: GoalPlanNowResponse | undefined): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* HTTP 202: the tick was handed to the planner worker rather than awaited in
|
|
28
|
+
* the request. `processed` is absent by design — it is neither a success to
|
|
29
|
+
* count nor a skip to fail on, it is a hand-off (OSK-12748).
|
|
30
|
+
*/
|
|
31
|
+
export declare function plannerTickAccepted(result: GoalPlanNowResponse | undefined): boolean;
|
|
26
32
|
/** Did the REQUEST give up, as opposed to the tick failing? */
|
|
27
33
|
export declare function isPlannerRequestTimeout(err: unknown): boolean;
|
|
28
34
|
/**
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.describePlannerReason = describePlannerReason;
|
|
4
4
|
exports.plannerTickDidNotRun = plannerTickDidNotRun;
|
|
5
|
+
exports.plannerTickAccepted = plannerTickAccepted;
|
|
5
6
|
exports.isPlannerRequestTimeout = isPlannerRequestTimeout;
|
|
6
7
|
exports.plannerTimeoutMessage = plannerTimeoutMessage;
|
|
7
8
|
const core_1 = require("@oclif/core");
|
|
@@ -85,6 +86,14 @@ function describePlannerReason(reason) {
|
|
|
85
86
|
function plannerTickDidNotRun(result) {
|
|
86
87
|
return result?.ok === false || result?.processed === false;
|
|
87
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* HTTP 202: the tick was handed to the planner worker rather than awaited in
|
|
91
|
+
* the request. `processed` is absent by design — it is neither a success to
|
|
92
|
+
* count nor a skip to fail on, it is a hand-off (OSK-12748).
|
|
93
|
+
*/
|
|
94
|
+
function plannerTickAccepted(result) {
|
|
95
|
+
return result?.accepted === true;
|
|
96
|
+
}
|
|
88
97
|
/** Did the REQUEST give up, as opposed to the tick failing? */
|
|
89
98
|
function isPlannerRequestTimeout(err) {
|
|
90
99
|
const status = err?.status;
|
|
@@ -163,6 +172,22 @@ class GoalsPlanNow extends base_command_1.BaseCommand {
|
|
|
163
172
|
}
|
|
164
173
|
const r = result;
|
|
165
174
|
const reasonText = describePlannerReason(r?.reason);
|
|
175
|
+
if (plannerTickAccepted(r)) {
|
|
176
|
+
// HTTP 202: the tick was handed to the planner worker — no counts exist
|
|
177
|
+
// yet, and that is the honest thing to print (OSK-12748). A 502 here used
|
|
178
|
+
// to mean "gateway gave up mid-run"; accepted means the request ended
|
|
179
|
+
// BEFORE the run, so nothing was left ambiguously in flight.
|
|
180
|
+
if (flags.json) {
|
|
181
|
+
this.log(JSON.stringify(r, null, 2));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
this.log(`Planner tick accepted for goal ${args.id} — running in the background.`);
|
|
185
|
+
if (r.backfilledCount) {
|
|
186
|
+
this.log(` backfilled: ${r.backfilledCount} existing task(s) tagged to the space.`);
|
|
187
|
+
}
|
|
188
|
+
this.log(` Watch \`${this.config.bin} goals tasks ${args.id}\` for what it creates.`);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
166
191
|
if (plannerTickDidNotRun(r)) {
|
|
167
192
|
// The backfill runs BEFORE planning and unconditionally, so a skipped
|
|
168
193
|
// tick can still have moved rows. Saying "nothing happened" would be the
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const scoped_memory_command_1 = require("../../../lib/scoped-memory-command");
|
|
5
|
+
const prompt_1 = require("../../../lib/prompt");
|
|
5
6
|
class MemoryApprovalsIssue extends scoped_memory_command_1.ScopedMemoryCommand {
|
|
6
7
|
static description = 'Issue a short-lived user approval for Space PII or Agent-to-Space promotion';
|
|
7
8
|
static flags = {
|
|
@@ -35,10 +36,12 @@ class MemoryApprovalsIssue extends scoped_memory_command_1.ScopedMemoryCommand {
|
|
|
35
36
|
this.error('--payload JSON is required for --purpose space_pii.', { exit: 2 });
|
|
36
37
|
}
|
|
37
38
|
try {
|
|
38
|
-
payload =
|
|
39
|
+
payload = (0, prompt_1.parseJsonFlag)(flags.payload, '--payload');
|
|
39
40
|
}
|
|
40
|
-
catch {
|
|
41
|
-
this.error('--payload must be valid JSON.', {
|
|
41
|
+
catch (err) {
|
|
42
|
+
this.error(err instanceof Error ? err.message : '--payload must be valid JSON.', {
|
|
43
|
+
exit: 2,
|
|
44
|
+
});
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
else if (!flags['source-store'] || !flags['source-memory'] || !flags['source-version']) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const data_schemas_1 = require("@skrr-ai/data-schemas");
|
|
5
4
|
const scoped_memory_command_1 = require("../../../lib/scoped-memory-command");
|
|
6
5
|
class MemoryMountsResolve extends scoped_memory_command_1.ScopedMemoryCommand {
|
|
7
6
|
static description = 'Resolve the ACL-aware Memory mounts for an Agent session';
|
|
@@ -14,7 +13,7 @@ class MemoryMountsResolve extends scoped_memory_command_1.ScopedMemoryCommand {
|
|
|
14
13
|
this.requireAuth();
|
|
15
14
|
const { flags } = await this.parse(MemoryMountsResolve);
|
|
16
15
|
const response = await this.memoryApi(flags.agent, `/mounts${this.query(flags)}`);
|
|
17
|
-
const result = { mounts: response.mounts.map(
|
|
16
|
+
const result = { mounts: response.mounts.map(scoped_memory_command_1.parseMemoryMount) };
|
|
18
17
|
if (flags.json)
|
|
19
18
|
return this.log(JSON.stringify(result, null, 2));
|
|
20
19
|
for (const mount of result.mounts) {
|
|
@@ -1,72 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
4
|
const base_command_1 = require("../../base-command");
|
|
6
|
-
const prompt_1 = require("../../lib/prompt");
|
|
7
5
|
const memory_scope_1 = require("../../lib/memory-scope");
|
|
8
|
-
|
|
6
|
+
/** Compatibility entry point for a write API removed by canonical Memory Stores. */
|
|
9
7
|
class MemorySave extends base_command_1.BaseCommand {
|
|
10
|
-
static description = '
|
|
8
|
+
static description = 'Retired flat memory write; use memory maintain remember or memory topics create';
|
|
11
9
|
static examples = [
|
|
12
|
-
'<%= config.bin %> memory
|
|
13
|
-
'<%= config.bin %> memory
|
|
14
|
-
'<%= config.bin %> memory save --key "note" --value "remember this" --json',
|
|
15
|
-
'<%= config.bin %> memory save --key "team-norm" --value "ship on fridays" --tier workspace --pool-workspace ws_123',
|
|
16
|
-
'<%= config.bin %> memory maintain remember \'{"path":"/notes","claim":"remember this"}\' --agent agent_abc123',
|
|
10
|
+
'<%= config.bin %> memory maintain remember \'{"path":"/notes","claim":"Remember this."}\' --agent agent_abc123',
|
|
11
|
+
'<%= config.bin %> memory topics create --help',
|
|
17
12
|
];
|
|
18
13
|
static flags = {
|
|
19
|
-
json: core_1.Flags.boolean({ description: 'Output
|
|
20
|
-
'from-json': core_1.Flags.string({
|
|
21
|
-
|
|
22
|
-
}),
|
|
23
|
-
key: core_1.Flags.string({ description: 'Memory key (required unless set via --from-json)' }),
|
|
24
|
-
value: core_1.Flags.string({ description: 'Memory value (required unless set via --from-json)' }),
|
|
14
|
+
json: core_1.Flags.boolean({ description: 'Output errors as JSON' }),
|
|
15
|
+
'from-json': core_1.Flags.string({ description: 'Retired flat memory input' }),
|
|
16
|
+
key: core_1.Flags.string({ description: 'Retired flat memory key' }),
|
|
17
|
+
value: core_1.Flags.string({ description: 'Retired flat memory value' }),
|
|
25
18
|
...memory_scope_1.memoryScopeFlags,
|
|
26
19
|
};
|
|
27
20
|
async run() {
|
|
28
|
-
this.requireAuth();
|
|
29
21
|
const { flags } = await this.parse(MemorySave);
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const payload = (0, prompt_1.mergeDefined)(body, {
|
|
39
|
-
key: flags.key,
|
|
40
|
-
value: flags.value,
|
|
22
|
+
const next = flags.agent
|
|
23
|
+
? `skrr memory maintain remember '{"path":"/notes","claim":"your memory"}' --agent ${flags.agent}`
|
|
24
|
+
: 'skrr memory topics create --help (choose an Agent or Space Store)';
|
|
25
|
+
this.failWithCliError({
|
|
26
|
+
code: 'LEGACY_MEMORY_WRITE_REMOVED',
|
|
27
|
+
message: `Flat memory writes have been retired. Use canonical Memory Stores. Run: ${next}`,
|
|
28
|
+
exit: 5,
|
|
29
|
+
retryable: false,
|
|
41
30
|
});
|
|
42
|
-
if (!payload.key || typeof payload.key !== 'string') {
|
|
43
|
-
this.error('A key is required. Pass --key "..." or include it in --from-json.', { exit: 1 });
|
|
44
|
-
}
|
|
45
|
-
if (!payload.value || typeof payload.value !== 'string') {
|
|
46
|
-
this.error('A value is required. Pass --value "..." or include it in --from-json.', {
|
|
47
|
-
exit: 1,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
let result;
|
|
51
|
-
try {
|
|
52
|
-
result = await data_provider_1.dataService.createMemory({
|
|
53
|
-
key: payload.key,
|
|
54
|
-
value: payload.value,
|
|
55
|
-
}, scope);
|
|
56
|
-
}
|
|
57
|
-
catch (err) {
|
|
58
|
-
this.handleApiError(err);
|
|
59
|
-
}
|
|
60
|
-
const guidance = scope.agentId ? (0, memory_workspace_guidance_1.semanticWorkspaceGuidance)(scope.agentId) : undefined;
|
|
61
|
-
if (flags.json) {
|
|
62
|
-
this.log(JSON.stringify(guidance ? { ...result, semanticWorkspace: guidance } : result, null, 2));
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
this.log(`Saved memory ${result.memory.key}`);
|
|
66
|
-
if (guidance) {
|
|
67
|
-
this.log(`\n${guidance.message}`);
|
|
68
|
-
this.log(`To include a fact in that context, run:\n${guidance.nextCommand}`);
|
|
69
|
-
}
|
|
70
31
|
}
|
|
71
32
|
}
|
|
72
33
|
exports.default = MemorySave;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const data_schemas_1 = require("@skrr-ai/data-schemas");
|
|
5
4
|
const scoped_memory_command_1 = require("../../../lib/scoped-memory-command");
|
|
6
5
|
class MemoryStoresList extends scoped_memory_command_1.ScopedMemoryCommand {
|
|
7
6
|
static description = 'List Memory Stores mounted for an Agent session';
|
|
@@ -15,7 +14,7 @@ class MemoryStoresList extends scoped_memory_command_1.ScopedMemoryCommand {
|
|
|
15
14
|
const { flags } = await this.parse(MemoryStoresList);
|
|
16
15
|
const response = await this.memoryApi(flags.agent, `/stores${this.query(flags)}`);
|
|
17
16
|
const result = {
|
|
18
|
-
stores: response.stores.map(
|
|
17
|
+
stores: response.stores.map(scoped_memory_command_1.parseMountedMemoryStore),
|
|
19
18
|
};
|
|
20
19
|
if (flags.json)
|
|
21
20
|
return this.log(JSON.stringify(result, null, 2));
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const scoped_memory_command_1 = require("../../../lib/scoped-memory-command");
|
|
5
|
+
const prompt_1 = require("../../../lib/prompt");
|
|
5
6
|
class MemoryStoresUpdate extends scoped_memory_command_1.ScopedMemoryCommand {
|
|
6
7
|
static description = 'Update Memory Store metadata with revision CAS';
|
|
7
8
|
static flags = {
|
|
@@ -18,10 +19,12 @@ class MemoryStoresUpdate extends scoped_memory_command_1.ScopedMemoryCommand {
|
|
|
18
19
|
const store = await this.resolveStore(flags, { write: true });
|
|
19
20
|
let attributes;
|
|
20
21
|
try {
|
|
21
|
-
attributes =
|
|
22
|
+
attributes = (0, prompt_1.parseJsonFlag)(flags.attributes, '--attributes');
|
|
22
23
|
}
|
|
23
|
-
catch {
|
|
24
|
-
this.error('--attributes must be valid JSON.', {
|
|
24
|
+
catch (err) {
|
|
25
|
+
this.error(err instanceof Error ? err.message : '--attributes must be valid JSON.', {
|
|
26
|
+
exit: 2,
|
|
27
|
+
});
|
|
25
28
|
}
|
|
26
29
|
const body = {
|
|
27
30
|
attributes,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class SkillsVisibility extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
public: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
private: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
price: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../base-command");
|
|
6
|
+
class SkillsVisibility extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Publish or unpublish an owned skill with a governed Store release';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> store artifacts release skill <skill-id> --versionLabel 1.0 --artifactRef skill:<skill-id> --permission-manifest <json>',
|
|
10
|
+
'<%= config.bin %> skills visibility <skill-id> --public',
|
|
11
|
+
'<%= config.bin %> skills visibility <skill-id> --private',
|
|
12
|
+
];
|
|
13
|
+
static args = {
|
|
14
|
+
id: core_1.Args.string({ description: 'Skill ID', required: true, ignoreStdin: true }),
|
|
15
|
+
};
|
|
16
|
+
static flags = {
|
|
17
|
+
public: core_1.Flags.boolean({ description: 'Publish the skill', exclusive: ['private'] }),
|
|
18
|
+
private: core_1.Flags.boolean({ description: 'Unpublish the skill', exclusive: ['public'] }),
|
|
19
|
+
price: core_1.Flags.integer({ description: 'Listing price in micro-USD' }),
|
|
20
|
+
json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
this.requireAuth();
|
|
24
|
+
const { args, flags } = await this.parse(SkillsVisibility);
|
|
25
|
+
if (!flags.public && !flags.private) {
|
|
26
|
+
this.error('Pass either --public or --private.', { exit: 2 });
|
|
27
|
+
}
|
|
28
|
+
if (flags.private && flags.price !== undefined) {
|
|
29
|
+
this.error('--price applies only when publishing with --public.', { exit: 2 });
|
|
30
|
+
}
|
|
31
|
+
let result;
|
|
32
|
+
try {
|
|
33
|
+
result = await data_provider_1.dataService.setSkillVisibility({
|
|
34
|
+
skillId: args.id,
|
|
35
|
+
isPublic: flags.public === true,
|
|
36
|
+
...(flags.price !== undefined ? { price: flags.price } : {}),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
this.handleApiError(error);
|
|
41
|
+
}
|
|
42
|
+
if (flags.json) {
|
|
43
|
+
this.log(JSON.stringify(result, null, 2));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this.log(`Set skill ${args.id} visibility: ${flags.public ? 'public' : 'private'}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.default = SkillsVisibility;
|
|
@@ -11,6 +11,7 @@ export default class StoreAdmissionsApprove extends BaseCommand {
|
|
|
11
11
|
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
12
12
|
};
|
|
13
13
|
static flags: {
|
|
14
|
+
artifact: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
15
|
kind: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
16
|
note: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
17
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
@@ -13,6 +13,7 @@ class StoreAdmissionsApprove extends base_command_1.BaseCommand {
|
|
|
13
13
|
static examples = [
|
|
14
14
|
'<%= config.bin %> store admissions approve ar_abc123',
|
|
15
15
|
'<%= config.bin %> store admissions approve skill_abc123 --kind skill',
|
|
16
|
+
'<%= config.bin %> store admissions approve store_release_abc123 --artifact',
|
|
16
17
|
];
|
|
17
18
|
static args = {
|
|
18
19
|
id: core_1.Args.string({
|
|
@@ -22,6 +23,7 @@ class StoreAdmissionsApprove extends base_command_1.BaseCommand {
|
|
|
22
23
|
}),
|
|
23
24
|
};
|
|
24
25
|
static flags = {
|
|
26
|
+
artifact: core_1.Flags.boolean({ description: 'The id is a Skill or Action artifact release' }),
|
|
25
27
|
kind: core_1.Flags.string({
|
|
26
28
|
description: 'The id is a listing, not a release',
|
|
27
29
|
options: ['skill', 'action'],
|
|
@@ -33,9 +35,13 @@ class StoreAdmissionsApprove extends base_command_1.BaseCommand {
|
|
|
33
35
|
this.requireAuth();
|
|
34
36
|
const { args, flags } = await this.parse(StoreAdmissionsApprove);
|
|
35
37
|
try {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
if (flags.artifact && flags.kind)
|
|
39
|
+
this.error('Use either --artifact or --kind');
|
|
40
|
+
const result = flags.artifact
|
|
41
|
+
? await data_provider_1.dataService.approveStoreArtifactAdmission(args.id, flags.note)
|
|
42
|
+
: flags.kind
|
|
43
|
+
? await data_provider_1.dataService.approveStoreListingAdmission(flags.kind, args.id, flags.note)
|
|
44
|
+
: await data_provider_1.dataService.approveStoreReleaseAdmission(args.id, flags.note);
|
|
39
45
|
if (flags.json) {
|
|
40
46
|
this.log(JSON.stringify(result, null, 2));
|
|
41
47
|
return;
|
|
@@ -45,6 +45,12 @@ class StoreAdmissionsList extends base_command_1.BaseCommand {
|
|
|
45
45
|
name: l.name || '',
|
|
46
46
|
facets: (l.admission?.facets || []).join(','),
|
|
47
47
|
})),
|
|
48
|
+
...(result.artifacts || []).map((a) => ({
|
|
49
|
+
kind: `${a.entityType} artifact`,
|
|
50
|
+
id: a.releaseId,
|
|
51
|
+
name: `${a.entityId} v${a.versionLabel}`,
|
|
52
|
+
facets: (a.admission?.facets || []).join(','),
|
|
53
|
+
})),
|
|
48
54
|
];
|
|
49
55
|
if (!rows.length) {
|
|
50
56
|
this.log('Nothing waiting for review.');
|
|
@@ -10,6 +10,7 @@ export default class StoreAdmissionsRefuse extends BaseCommand {
|
|
|
10
10
|
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
11
11
|
};
|
|
12
12
|
static flags: {
|
|
13
|
+
artifact: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
14
|
kind: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
15
|
note: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
16
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
@@ -12,6 +12,7 @@ class StoreAdmissionsRefuse extends base_command_1.BaseCommand {
|
|
|
12
12
|
static examples = [
|
|
13
13
|
'<%= config.bin %> store admissions refuse ar_abc123 --note "unbounded network egress"',
|
|
14
14
|
'<%= config.bin %> store admissions refuse act_abc123 --kind action --note "reason"',
|
|
15
|
+
'<%= config.bin %> store admissions refuse store_release_abc123 --artifact --note "reason"',
|
|
15
16
|
];
|
|
16
17
|
static args = {
|
|
17
18
|
id: core_1.Args.string({
|
|
@@ -21,6 +22,7 @@ class StoreAdmissionsRefuse extends base_command_1.BaseCommand {
|
|
|
21
22
|
}),
|
|
22
23
|
};
|
|
23
24
|
static flags = {
|
|
25
|
+
artifact: core_1.Flags.boolean({ description: 'The id is a Skill or Action artifact release' }),
|
|
24
26
|
kind: core_1.Flags.string({
|
|
25
27
|
description: 'The id is a listing, not a release',
|
|
26
28
|
options: ['skill', 'action'],
|
|
@@ -32,9 +34,13 @@ class StoreAdmissionsRefuse extends base_command_1.BaseCommand {
|
|
|
32
34
|
this.requireAuth();
|
|
33
35
|
const { args, flags } = await this.parse(StoreAdmissionsRefuse);
|
|
34
36
|
try {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
if (flags.artifact && flags.kind)
|
|
38
|
+
this.error('Use either --artifact or --kind');
|
|
39
|
+
const result = flags.artifact
|
|
40
|
+
? await data_provider_1.dataService.refuseStoreArtifactAdmission(args.id, flags.note || '')
|
|
41
|
+
: flags.kind
|
|
42
|
+
? await data_provider_1.dataService.refuseStoreListingAdmission(flags.kind, args.id, flags.note || '')
|
|
43
|
+
: await data_provider_1.dataService.refuseStoreReleaseAdmission(args.id, flags.note || '');
|
|
38
44
|
if (flags.json) {
|
|
39
45
|
this.log(JSON.stringify(result, null, 2));
|
|
40
46
|
return;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export declare function parsePermissionManifest(value: string): Record<string, string[]>;
|
|
2
3
|
export default class StoreArtifactsRelease extends BaseCommand {
|
|
3
4
|
static description: string;
|
|
5
|
+
static examples: string[];
|
|
4
6
|
static args: {
|
|
5
7
|
entityType: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
8
|
entityId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
@@ -8,6 +10,7 @@ export default class StoreArtifactsRelease extends BaseCommand {
|
|
|
8
10
|
static flags: {
|
|
9
11
|
versionLabel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
12
|
artifactRef: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
'permission-manifest': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
14
|
price: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
15
|
workspaceId: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
16
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
@@ -1,10 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parsePermissionManifest = parsePermissionManifest;
|
|
3
4
|
const core_1 = require("@oclif/core");
|
|
4
5
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
6
|
const base_command_1 = require("../../../base-command");
|
|
7
|
+
const permissionFields = [
|
|
8
|
+
'tools',
|
|
9
|
+
'connectors',
|
|
10
|
+
'dataScopes',
|
|
11
|
+
'networkDomains',
|
|
12
|
+
'secretNames',
|
|
13
|
+
];
|
|
14
|
+
function parsePermissionManifest(value) {
|
|
15
|
+
const parsed = JSON.parse(value);
|
|
16
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
17
|
+
throw new Error('The permission manifest must be an object');
|
|
18
|
+
}
|
|
19
|
+
const manifest = parsed;
|
|
20
|
+
if (Object.keys(manifest).some((key) => !permissionFields.includes(key)) ||
|
|
21
|
+
permissionFields.some((key) => {
|
|
22
|
+
const entries = manifest[key];
|
|
23
|
+
return (!Array.isArray(entries) ||
|
|
24
|
+
!entries.every((entry) => typeof entry === 'string' && entry.trim() === entry && entry.length > 0) ||
|
|
25
|
+
new Set(entries).size !== entries.length);
|
|
26
|
+
})) {
|
|
27
|
+
throw new Error('The permission manifest must explicitly declare five arrays of unique, non-empty strings');
|
|
28
|
+
}
|
|
29
|
+
return manifest;
|
|
30
|
+
}
|
|
6
31
|
class StoreArtifactsRelease extends base_command_1.BaseCommand {
|
|
7
32
|
static description = 'Publish an immutable dependency release for your own skill or action';
|
|
33
|
+
static examples = [
|
|
34
|
+
'<%= config.bin %> store artifacts release skill <skill-id> --versionLabel 1.0 --artifactRef skill:<skill-id> --permission-manifest <json>',
|
|
35
|
+
];
|
|
8
36
|
static args = {
|
|
9
37
|
entityType: core_1.Args.string({ required: true, ignoreStdin: true }),
|
|
10
38
|
entityId: core_1.Args.string({ required: true, ignoreStdin: true }),
|
|
@@ -12,6 +40,10 @@ class StoreArtifactsRelease extends base_command_1.BaseCommand {
|
|
|
12
40
|
static flags = {
|
|
13
41
|
versionLabel: core_1.Flags.string({ required: true }),
|
|
14
42
|
artifactRef: core_1.Flags.string({ required: true }),
|
|
43
|
+
'permission-manifest': core_1.Flags.string({
|
|
44
|
+
required: true,
|
|
45
|
+
description: 'Explicit JSON declaration of tools, connectors, dataScopes, networkDomains, and secretNames used by this release',
|
|
46
|
+
}),
|
|
15
47
|
price: core_1.Flags.integer({ description: 'Price in micro-USD; omit for zero-price' }),
|
|
16
48
|
workspaceId: core_1.Flags.string({ description: 'Publish as this workspace' }),
|
|
17
49
|
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
@@ -19,9 +51,19 @@ class StoreArtifactsRelease extends base_command_1.BaseCommand {
|
|
|
19
51
|
async run() {
|
|
20
52
|
this.requireAuth();
|
|
21
53
|
const { args, flags } = await this.parse(StoreArtifactsRelease);
|
|
54
|
+
let permissionManifest;
|
|
55
|
+
try {
|
|
56
|
+
permissionManifest = parsePermissionManifest(flags['permission-manifest']);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
this.error('--permission-manifest must declare tools, connectors, dataScopes, networkDomains, and secretNames as string arrays', {
|
|
60
|
+
exit: 2,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
22
63
|
const result = await data_provider_1.dataService.publishStoreArtifactRelease(args.entityType, args.entityId, {
|
|
23
64
|
versionLabel: flags.versionLabel,
|
|
24
65
|
artifactRef: flags.artifactRef,
|
|
66
|
+
permissionManifest,
|
|
25
67
|
...(flags.price !== undefined ? { price: flags.price } : {}),
|
|
26
68
|
...(flags.workspaceId ? { publishAs: { workspaceId: flags.workspaceId } } : {}),
|
|
27
69
|
});
|
|
@@ -51,7 +51,7 @@ class StoreUpdate extends base_command_1.BaseCommand {
|
|
|
51
51
|
if (!status?.purchased) {
|
|
52
52
|
this.error(`${args.agentId} is not installed from the Store. Install it first: skrr store install ${args.agentId}`, { exit: 1 });
|
|
53
53
|
}
|
|
54
|
-
if (status.pendingUpdate && !flags.decline) {
|
|
54
|
+
if (status.pendingUpdate && !flags.decline && !flags.json) {
|
|
55
55
|
this.log(`A ${status.pendingUpdate.versionLabel ?? 'new'} release is waiting for review ` +
|
|
56
56
|
`(${status.pendingUpdate.reason}).`);
|
|
57
57
|
}
|
|
@@ -71,6 +71,10 @@ class StoreUpdate extends base_command_1.BaseCommand {
|
|
|
71
71
|
// hands back the body as TEXT, so reading `err.body` as an object never
|
|
72
72
|
// saw a code at all and both answers below fell through to a bare error.
|
|
73
73
|
const body = (0, http_error_1.httpBodyOf)(err);
|
|
74
|
+
// The shared error renderer keeps the server's typed refusal in one JSON
|
|
75
|
+
// envelope. Human guidance below would corrupt stdout in --json mode.
|
|
76
|
+
if (flags.json)
|
|
77
|
+
this.handleApiError(err);
|
|
74
78
|
// Not an update: a new major is a separate purchase. Say which version
|
|
75
79
|
// keeps its free updates, and offer no command — none sells a second
|
|
76
80
|
// major of a listing yet, and `store install` refuses one you own.
|
|
@@ -9,7 +9,7 @@ import { BaseCommand } from '../../base-command';
|
|
|
9
9
|
*
|
|
10
10
|
* Three states, kept apart because they ask for three different things:
|
|
11
11
|
*
|
|
12
|
-
* ready a same-major release
|
|
12
|
+
* ready a same-major release is available; eligibility is checked on apply
|
|
13
13
|
* review one that could not be applied on its own — you and the publisher
|
|
14
14
|
* both changed the same field, the release widened capabilities, or
|
|
15
15
|
* the version your copy came from is unknown
|