@automagik/genie 4.260331.5 → 4.260331.7
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/.claude-plugin/marketplace.json +1 -1
- package/CLAUDE.md +31 -5
- package/dist/genie.js +600 -691
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/plugins/genie/.claude-plugin/plugin.json +1 -1
- package/plugins/genie/package.json +1 -1
- package/skills/genie/SKILL.md +71 -233
- package/skills/genie/reference/lifecycle.md +65 -0
- package/src/db/migrations/015_agent_archived_state.sql +0 -20
- package/src/db/migrations/018_drop_app_store.sql +4 -0
- package/src/genie.ts +26 -14
- package/src/lib/agent-sync.ts +55 -194
- package/src/lib/export-format.ts +1 -12
- package/src/lib/import-order.ts +1 -11
- package/src/term-commands/agent/directory.ts +2 -37
- package/src/term-commands/agent/index.ts +6 -0
- package/src/term-commands/dir.ts +3 -160
- package/src/term-commands/export.ts +0 -13
- package/src/term-commands/msg.ts +8 -0
- package/src/term-commands/team.ts +8 -0
- package/src/lib/agent-cache.ts +0 -282
- package/src/lib/manifest.ts +0 -342
- package/src/term-commands/install.ts +0 -372
- package/src/term-commands/item-uninstall.ts +0 -118
- package/src/term-commands/item-update.ts +0 -205
- package/src/term-commands/publish.ts +0 -187
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Publish Command — `genie publish`
|
|
3
|
-
*
|
|
4
|
-
* Publishes the current directory as a genie item. Must be run from a
|
|
5
|
-
* directory containing a genie.yaml. Requires a pushed git tag matching
|
|
6
|
-
* the manifest version.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { execSync } from 'node:child_process';
|
|
10
|
-
import type { Command } from 'commander';
|
|
11
|
-
import { getItemFromStore, registerItemInStore, updateItemInStore } from '../lib/agent-cache.js';
|
|
12
|
-
import { getActor, recordAuditEvent } from '../lib/audit.js';
|
|
13
|
-
import { getConnection, isAvailable } from '../lib/db.js';
|
|
14
|
-
import { detectManifest, validateManifest } from '../lib/manifest.js';
|
|
15
|
-
|
|
16
|
-
// ============================================================================
|
|
17
|
-
// Git tag verification
|
|
18
|
-
// ============================================================================
|
|
19
|
-
|
|
20
|
-
function getGitRemoteTags(cwd: string): string[] {
|
|
21
|
-
try {
|
|
22
|
-
const output = execSync('git tag --list --merged HEAD', {
|
|
23
|
-
cwd,
|
|
24
|
-
encoding: 'utf-8',
|
|
25
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
26
|
-
});
|
|
27
|
-
return output.trim().split('\n').filter(Boolean);
|
|
28
|
-
} catch {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function isTagPushed(tag: string, cwd: string): boolean {
|
|
34
|
-
try {
|
|
35
|
-
execSync(`git ls-remote --tags origin refs/tags/${tag}`, {
|
|
36
|
-
cwd,
|
|
37
|
-
encoding: 'utf-8',
|
|
38
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
39
|
-
});
|
|
40
|
-
return true;
|
|
41
|
-
} catch {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function getGitSha(cwd: string): string | null {
|
|
47
|
-
try {
|
|
48
|
-
return execSync('git rev-parse HEAD', { cwd, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
49
|
-
} catch {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// ============================================================================
|
|
55
|
-
// Publish handler
|
|
56
|
-
// ============================================================================
|
|
57
|
-
|
|
58
|
-
async function handlePublish(): Promise<void> {
|
|
59
|
-
const cwd = process.cwd();
|
|
60
|
-
|
|
61
|
-
// Detect and validate manifest
|
|
62
|
-
const detection = await detectManifest(cwd);
|
|
63
|
-
if ('error' in detection) {
|
|
64
|
-
console.error(`Cannot publish: ${detection.error}`);
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const { manifest, source } = detection;
|
|
69
|
-
const validation = validateManifest(manifest, cwd);
|
|
70
|
-
for (const w of validation.warnings) {
|
|
71
|
-
console.log(` Warning: ${w}`);
|
|
72
|
-
}
|
|
73
|
-
if (!validation.valid) {
|
|
74
|
-
console.error(`Validation failed:\n${validation.errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
75
|
-
process.exit(1);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Check for git tag matching version
|
|
79
|
-
const expectedTag = `v${manifest.version}`;
|
|
80
|
-
const tags = getGitRemoteTags(cwd);
|
|
81
|
-
const hasTag = tags.includes(expectedTag) || tags.includes(manifest.version);
|
|
82
|
-
if (!hasTag) {
|
|
83
|
-
console.error(`No git tag "${expectedTag}" found. Create and push a tag first:`);
|
|
84
|
-
console.error(` git tag ${expectedTag} && git push origin ${expectedTag}`);
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Verify tag is pushed to remote
|
|
89
|
-
const tagToPush = tags.includes(expectedTag) ? expectedTag : manifest.version;
|
|
90
|
-
if (!isTagPushed(tagToPush, cwd)) {
|
|
91
|
-
console.error(`Tag "${tagToPush}" exists locally but is not pushed to remote.`);
|
|
92
|
-
console.error(` git push origin ${tagToPush}`);
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const gitSha = getGitSha(cwd);
|
|
97
|
-
|
|
98
|
-
// UPSERT into app_store
|
|
99
|
-
const existing = await getItemFromStore(manifest.name).catch(() => null);
|
|
100
|
-
if (existing) {
|
|
101
|
-
await updateItemInStore(manifest.name, {
|
|
102
|
-
version: manifest.version,
|
|
103
|
-
description: manifest.description,
|
|
104
|
-
manifest: manifest as unknown as Record<string, unknown>,
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// Update approval status
|
|
108
|
-
if (await isAvailable()) {
|
|
109
|
-
const sql = await getConnection();
|
|
110
|
-
await sql`
|
|
111
|
-
UPDATE app_store
|
|
112
|
-
SET approval_status = 'pending', updated_at = now()
|
|
113
|
-
WHERE name = ${manifest.name}
|
|
114
|
-
`;
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
await registerItemInStore({
|
|
118
|
-
name: manifest.name,
|
|
119
|
-
itemType: manifest.type,
|
|
120
|
-
version: manifest.version,
|
|
121
|
-
description: manifest.description,
|
|
122
|
-
authorName: manifest.author?.name,
|
|
123
|
-
authorUrl: manifest.author?.url,
|
|
124
|
-
installPath: cwd,
|
|
125
|
-
manifest: manifest as unknown as Record<string, unknown>,
|
|
126
|
-
tags: manifest.tags,
|
|
127
|
-
category: manifest.category,
|
|
128
|
-
license: manifest.license,
|
|
129
|
-
dependencies: manifest.dependencies,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Record version in app_versions
|
|
134
|
-
if (await isAvailable()) {
|
|
135
|
-
const sql = await getConnection();
|
|
136
|
-
const storeItem = await getItemFromStore(manifest.name);
|
|
137
|
-
if (storeItem) {
|
|
138
|
-
await sql`
|
|
139
|
-
INSERT INTO app_versions (app_store_id, version, git_tag, git_sha, manifest)
|
|
140
|
-
VALUES (
|
|
141
|
-
${storeItem.id},
|
|
142
|
-
${manifest.version},
|
|
143
|
-
${tagToPush},
|
|
144
|
-
${gitSha},
|
|
145
|
-
${sql.json(manifest as unknown as Record<string, unknown>)}
|
|
146
|
-
)
|
|
147
|
-
ON CONFLICT (app_store_id, version) DO UPDATE SET
|
|
148
|
-
git_sha = EXCLUDED.git_sha,
|
|
149
|
-
manifest = EXCLUDED.manifest,
|
|
150
|
-
published_at = now()
|
|
151
|
-
`;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Audit
|
|
156
|
-
recordAuditEvent('item', manifest.name, 'item_published', getActor(), {
|
|
157
|
-
type: manifest.type,
|
|
158
|
-
version: manifest.version,
|
|
159
|
-
tag: tagToPush,
|
|
160
|
-
sha: gitSha,
|
|
161
|
-
manifestSource: source,
|
|
162
|
-
}).catch(() => {});
|
|
163
|
-
|
|
164
|
-
console.log(`\nPublished ${manifest.type} "${manifest.name}" v${manifest.version}`);
|
|
165
|
-
console.log(` Tag: ${tagToPush}`);
|
|
166
|
-
if (gitSha) console.log(` SHA: ${gitSha.slice(0, 8)}`);
|
|
167
|
-
console.log(' Status: pending approval');
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// ============================================================================
|
|
171
|
-
// Command registration
|
|
172
|
-
// ============================================================================
|
|
173
|
-
|
|
174
|
-
export function registerPublishCommand(program: Command): void {
|
|
175
|
-
program
|
|
176
|
-
.command('publish')
|
|
177
|
-
.description('Publish the current directory as a genie item (requires pushed git tag)')
|
|
178
|
-
.action(async () => {
|
|
179
|
-
try {
|
|
180
|
-
await handlePublish();
|
|
181
|
-
} catch (error) {
|
|
182
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
183
|
-
console.error(`Error: ${message}`);
|
|
184
|
-
process.exit(1);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
}
|