@holo-js/cli 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-skills-CHAXS2YN.mjs +180 -0
- package/dist/bin/holo.mjs +105 -25
- package/dist/{broadcast-AVYI67BU.mjs → broadcast-JBQWQZSO.mjs} +2 -1
- package/dist/{broadcast-CMPONJ5J.mjs → broadcast-YGJFCEPP.mjs} +2 -1
- package/dist/{cache-2EUUQJX2.mjs → cache-HUGRWOHQ.mjs} +1 -1
- package/dist/{cache-4OVL2YTS.mjs → cache-OSJ4PD52.mjs} +1 -1
- package/dist/{cache-migrations-LGTPRUDS.mjs → cache-migrations-77TLXIVG.mjs} +6 -6
- package/dist/{cache-migrations-TJWWJB4I.mjs → cache-migrations-FKAHRP24.mjs} +6 -6
- package/dist/{chunk-HZJWXL2W.mjs → chunk-4K4CWMMP.mjs} +3 -3
- package/dist/{chunk-6UDDQUXY.mjs → chunk-7B2RVYLL.mjs} +67 -67
- package/dist/{chunk-ZHFXVJBE.mjs → chunk-AJLRAC5M.mjs} +3 -3
- package/dist/{chunk-LGU5YVKP.mjs → chunk-C624G3R2.mjs} +67 -67
- package/dist/{dev-I4NZRFTS.mjs → dev-L4Y2GU2E.mjs} +2 -2
- package/dist/{dev-WOOZOWLR.mjs → dev-YPBQBEOE.mjs} +2 -2
- package/dist/{generators-FUOVIC2E.mjs → generators-H4NTV4DB.mjs} +2 -2
- package/dist/{generators-Y47HYPQT.mjs → generators-VCYISHWO.mjs} +2 -2
- package/dist/index.mjs +105 -25
- package/dist/{media-migrations-FGYPWPBF.mjs → media-migrations-BNVAPYEM.mjs} +6 -6
- package/dist/{media-migrations-N63DGHGG.mjs → media-migrations-NNB3DAQR.mjs} +6 -6
- package/dist/{queue-HB22LB66.mjs → queue-5BXSDFCO.mjs} +7 -7
- package/dist/{queue-UQ6TPIK4.mjs → queue-D4LSWNS2.mjs} +7 -7
- package/dist/{queue-migrations-FENTWONO.mjs → queue-migrations-EF4AMMSY.mjs} +21 -20
- package/dist/{queue-migrations-HJ4Z55FB.mjs → queue-migrations-LXEWXJYT.mjs} +21 -20
- package/dist/{runtime-7KCBHTRV.mjs → runtime-RPMZMTD4.mjs} +1 -1
- package/dist/{runtime-PLE3TUX2.mjs → runtime-UKBJQFXM.mjs} +1 -1
- package/dist/{scaffold-2PPKFFAZ.mjs → scaffold-NJ5VH73M.mjs} +1 -1
- package/dist/{scaffold-3LLBQ2JF.mjs → scaffold-VV3KTYGO.mjs} +1 -1
- package/dist/{security-NAOOXRFV.mjs → security-JR4P7L2C.mjs} +1 -1
- package/dist/{security-QFDYNF2Z.mjs → security-K5PZS3E3.mjs} +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// src/agent-skills.ts
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { dirname, resolve } from "path";
|
|
4
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
5
|
+
var SUPPORTED_AGENT_SKILL_TARGETS = [
|
|
6
|
+
"codex",
|
|
7
|
+
"claude",
|
|
8
|
+
"cursor",
|
|
9
|
+
"windsurf",
|
|
10
|
+
"opencode",
|
|
11
|
+
"gemini",
|
|
12
|
+
"kiro"
|
|
13
|
+
];
|
|
14
|
+
var HOLO_AGENT_SKILL = `---
|
|
15
|
+
name: holo-js
|
|
16
|
+
description: Help users build applications with the Holo-JS framework by researching the current Holo-JS documentation at https://docs.holo-js.com/ before answering or coding. Use when a user asks how to scaffold, configure, integrate, or implement Holo-JS app features in Nuxt, Next.js, or SvelteKit, including database, ORM, auth, authorization, validation, forms, storage, media, queues, events, broadcast, realtime, mail, notifications, testing, or deployment. Prefer this for user-facing app work, not Holo-JS framework internals.
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Holo-JS
|
|
20
|
+
|
|
21
|
+
Use the docs as the source of truth, then act. Do not answer from memory when exact commands, imports, API names, config shape, route shape, or framework integration details matter.
|
|
22
|
+
|
|
23
|
+
Primary documentation URL: https://docs.holo-js.com/
|
|
24
|
+
|
|
25
|
+
## Required Workflow
|
|
26
|
+
|
|
27
|
+
1. Clarify the user's task category in your own reasoning: setup, config, database, ORM, auth, authorization, validation/forms, storage/media, queue/events, broadcast/realtime, mail/notifications, testing, deployment, or framework integration.
|
|
28
|
+
2. Search the live docs before giving implementation details.
|
|
29
|
+
3. Open the most relevant docs page and read only the sections that match the task.
|
|
30
|
+
4. Open at most one adjacent or overview page when the task touches package setup, framework integration, auth/session/security, background workers, or deployment.
|
|
31
|
+
5. Stop researching as soon as the docs provide enough information to implement the requested task.
|
|
32
|
+
6. Implement the task immediately using the docs you just read.
|
|
33
|
+
7. Mention when docs do not cover the requested detail and ask for a docs link or local project context.
|
|
34
|
+
|
|
35
|
+
Do not read package implementation files after docs lookup unless one of these is true:
|
|
36
|
+
|
|
37
|
+
- the docs are missing the API detail required to compile the code
|
|
38
|
+
- the implementation already failed and you need source to debug the failure
|
|
39
|
+
- the user explicitly asks you to inspect package internals
|
|
40
|
+
|
|
41
|
+
## How To Search
|
|
42
|
+
|
|
43
|
+
Prefer these approaches, in order:
|
|
44
|
+
|
|
45
|
+
1. Use the docs site's own search if you have browser access.
|
|
46
|
+
2. Use web search with \`site:docs.holo-js.com\` plus the concrete feature terms.
|
|
47
|
+
3. Open likely docs URLs from search results, then follow sidebar or in-page links to related pages.
|
|
48
|
+
4. If working inside the Holo-JS repository, search local docs source under \`apps/docs/docs/**/*.md\` with \`rg\` as a fallback or for faster exact matching.
|
|
49
|
+
|
|
50
|
+
Good search queries:
|
|
51
|
+
|
|
52
|
+
- \`site:docs.holo-js.com Holo-JS install <package-or-feature>\`
|
|
53
|
+
- \`site:docs.holo-js.com Holo-JS <framework> <feature>\`
|
|
54
|
+
- \`site:docs.holo-js.com Holo-JS <api-or-command-name>\`
|
|
55
|
+
- \`site:docs.holo-js.com Holo-JS <error message or concept>\`
|
|
56
|
+
|
|
57
|
+
Local repo fallback:
|
|
58
|
+
|
|
59
|
+
\`\`\`bash
|
|
60
|
+
rg -n "<feature|api|command|error>" apps/docs/docs
|
|
61
|
+
find apps/docs/docs -type f -name '*.md' | sort
|
|
62
|
+
\`\`\`
|
|
63
|
+
|
|
64
|
+
## What To Open
|
|
65
|
+
|
|
66
|
+
Use docs pages by task area, not by package guesses. Examples:
|
|
67
|
+
|
|
68
|
+
- Starting a project: installation, configuration, directory structure.
|
|
69
|
+
- Framework routing or handlers: routing, runtime services, framework-specific integration pages.
|
|
70
|
+
- Database and models: database pages first, then ORM pages.
|
|
71
|
+
- Auth flows: auth overview plus the specific flow page, then session/cookies or current auth client if state is involved.
|
|
72
|
+
- Authorization: authorization overview plus policies or abilities.
|
|
73
|
+
- Forms: forms overview plus server validation, client usage, and framework integration as needed.
|
|
74
|
+
- Files: storage first; media only when files belong to models or need conversions/collections.
|
|
75
|
+
- Background work: queue, events, queued listeners, workers, failed jobs, and deployment pages as needed.
|
|
76
|
+
- Browser realtime: broadcast or realtime docs plus framework helper pages.
|
|
77
|
+
- Production behavior: deployment plus any worker/driver page for the feature.
|
|
78
|
+
|
|
79
|
+
These names are navigation hints, not an API reference. Confirm exact paths and examples from the docs before responding.
|
|
80
|
+
|
|
81
|
+
## Answering Rules
|
|
82
|
+
|
|
83
|
+
- Cite or link the docs pages you used when the environment supports links.
|
|
84
|
+
- Keep examples aligned with the user's framework and package manager.
|
|
85
|
+
- Preserve framework-native routing, redirect, server action, and handler conventions shown by the docs.
|
|
86
|
+
- Do not invent helper APIs to make an answer look cleaner.
|
|
87
|
+
- Do not assume optional packages are installed. Check install/setup docs for the feature.
|
|
88
|
+
- Do not expose secrets in client code or examples.
|
|
89
|
+
- Do not hand-edit generated Holo-JS output unless docs explicitly instruct it.
|
|
90
|
+
- If docs and installed package behavior disagree, tell the user what you found and verify the smallest relevant package surface before continuing.
|
|
91
|
+
|
|
92
|
+
## Coding Against An Existing App
|
|
93
|
+
|
|
94
|
+
When editing a user's app:
|
|
95
|
+
|
|
96
|
+
1. Inspect the app's framework, package manager, installed \`@holo-js/*\` packages, and existing Holo-JS config.
|
|
97
|
+
2. Search docs for the exact feature and framework.
|
|
98
|
+
3. Match the app's existing conventions.
|
|
99
|
+
4. Add validation and authorization at boundaries when the docs indicate they are required.
|
|
100
|
+
5. Run the app's relevant typecheck, lint, and tests when available.
|
|
101
|
+
|
|
102
|
+
If the user asks for a broad implementation such as "add auth" or "add realtime", start from the docs' setup/overview pages and implement the smallest complete vertical slice rather than assembling APIs from memory.
|
|
103
|
+
`;
|
|
104
|
+
function resolveAgentSkillPath(root, agent) {
|
|
105
|
+
return resolve(root, agentRoot(agent), "skills/holo-js/SKILL.md");
|
|
106
|
+
}
|
|
107
|
+
function resolveGlobalAgentSkillPath(agent) {
|
|
108
|
+
const home = homedir();
|
|
109
|
+
if (agent === "opencode") {
|
|
110
|
+
return resolve(home, ".config/opencode/skills/holo-js/SKILL.md");
|
|
111
|
+
}
|
|
112
|
+
return resolveAgentSkillPath(home, agent);
|
|
113
|
+
}
|
|
114
|
+
function agentRoot(agent) {
|
|
115
|
+
if (agent === "claude") {
|
|
116
|
+
return ".claude";
|
|
117
|
+
}
|
|
118
|
+
if (agent === "opencode") {
|
|
119
|
+
return ".opencode";
|
|
120
|
+
}
|
|
121
|
+
return `.${agent}`;
|
|
122
|
+
}
|
|
123
|
+
async function readExisting(path) {
|
|
124
|
+
try {
|
|
125
|
+
return await readFile(path, "utf8");
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
128
|
+
return void 0;
|
|
129
|
+
}
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function normalizeAgentSkillTargets(values) {
|
|
134
|
+
const requested = values.length > 0 ? values : ["all"];
|
|
135
|
+
const agents = /* @__PURE__ */ new Set();
|
|
136
|
+
for (const value of requested) {
|
|
137
|
+
const normalized = value.trim().toLowerCase();
|
|
138
|
+
if (!normalized) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (normalized === "all") {
|
|
142
|
+
for (const agent of SUPPORTED_AGENT_SKILL_TARGETS) {
|
|
143
|
+
agents.add(agent);
|
|
144
|
+
}
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (!SUPPORTED_AGENT_SKILL_TARGETS.includes(normalized)) {
|
|
148
|
+
throw new Error(`Unsupported agent skill target: ${value}.`);
|
|
149
|
+
}
|
|
150
|
+
agents.add(normalized);
|
|
151
|
+
}
|
|
152
|
+
return [...agents];
|
|
153
|
+
}
|
|
154
|
+
async function installAgentSkills(projectRoot, options) {
|
|
155
|
+
const results = [];
|
|
156
|
+
for (const agent of options.agents) {
|
|
157
|
+
const path = options.global === true ? resolveGlobalAgentSkillPath(agent) : resolveAgentSkillPath(projectRoot, agent);
|
|
158
|
+
const existing = await readExisting(path);
|
|
159
|
+
if (existing === HOLO_AGENT_SKILL) {
|
|
160
|
+
results.push({ agent, path, status: "unchanged" });
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (typeof existing === "string" && options.force !== true) {
|
|
164
|
+
throw new Error(`Refusing to overwrite existing ${agent} skill at ${path}. Re-run with --force to replace it.`);
|
|
165
|
+
}
|
|
166
|
+
await mkdir(dirname(path), { recursive: true });
|
|
167
|
+
await writeFile(path, HOLO_AGENT_SKILL, "utf8");
|
|
168
|
+
results.push({
|
|
169
|
+
agent,
|
|
170
|
+
path,
|
|
171
|
+
status: typeof existing === "string" ? "updated" : "created"
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return results;
|
|
175
|
+
}
|
|
176
|
+
export {
|
|
177
|
+
SUPPORTED_AGENT_SKILL_TARGETS,
|
|
178
|
+
installAgentSkills,
|
|
179
|
+
normalizeAgentSkillTargets
|
|
180
|
+
};
|
package/dist/bin/holo.mjs
CHANGED
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
} from "../chunk-LBJAJLKU.mjs";
|
|
31
31
|
import "../chunk-D7O4SU6N.mjs";
|
|
32
32
|
import "../chunk-VP2E62DF.mjs";
|
|
33
|
-
import "../chunk-
|
|
33
|
+
import "../chunk-7B2RVYLL.mjs";
|
|
34
34
|
import "../chunk-YEFJBN56.mjs";
|
|
35
35
|
import "../chunk-J76GH2DR.mjs";
|
|
36
36
|
import {
|
|
@@ -112,6 +112,7 @@ var AUTH_INSTALL_FEATURES = ["social", "workos", "clerk"];
|
|
|
112
112
|
var AUTH_SOCIAL_PROVIDER_MODES = ["default", "specific"];
|
|
113
113
|
var EVENTS_QUEUE_ACTIONS = ["skip", "enable"];
|
|
114
114
|
var MODEL_GENERATOR_OPTIONS = ["migration", "observer", "seeder", "factory"];
|
|
115
|
+
var COMMAND_LIST_DESCRIPTION_COLUMN = 32;
|
|
115
116
|
var runtimeModulePromise;
|
|
116
117
|
var queueModulePromise;
|
|
117
118
|
var cacheModulePromise;
|
|
@@ -126,44 +127,45 @@ var projectConfigModulePromise;
|
|
|
126
127
|
var projectDiscoveryModulePromise;
|
|
127
128
|
var projectRuntimeModulePromise;
|
|
128
129
|
var projectScaffoldModulePromise;
|
|
130
|
+
var agentSkillsModulePromise;
|
|
129
131
|
function loadRuntimeModule() {
|
|
130
|
-
runtimeModulePromise ??= import("../runtime-
|
|
132
|
+
runtimeModulePromise ??= import("../runtime-RPMZMTD4.mjs");
|
|
131
133
|
return runtimeModulePromise;
|
|
132
134
|
}
|
|
133
135
|
function loadQueueModule() {
|
|
134
|
-
queueModulePromise ??= import("../queue-
|
|
136
|
+
queueModulePromise ??= import("../queue-D4LSWNS2.mjs");
|
|
135
137
|
return queueModulePromise;
|
|
136
138
|
}
|
|
137
139
|
function loadCacheModule() {
|
|
138
|
-
cacheModulePromise ??= import("../cache-
|
|
140
|
+
cacheModulePromise ??= import("../cache-OSJ4PD52.mjs");
|
|
139
141
|
return cacheModulePromise;
|
|
140
142
|
}
|
|
141
143
|
function loadQueueMigrationsModule() {
|
|
142
|
-
queueMigrationsModulePromise ??= import("../queue-migrations-
|
|
144
|
+
queueMigrationsModulePromise ??= import("../queue-migrations-LXEWXJYT.mjs");
|
|
143
145
|
return queueMigrationsModulePromise;
|
|
144
146
|
}
|
|
145
147
|
function loadCacheMigrationsModule() {
|
|
146
|
-
cacheMigrationsModulePromise ??= import("../cache-migrations-
|
|
148
|
+
cacheMigrationsModulePromise ??= import("../cache-migrations-FKAHRP24.mjs");
|
|
147
149
|
return cacheMigrationsModulePromise;
|
|
148
150
|
}
|
|
149
151
|
function loadMediaMigrationsModule() {
|
|
150
|
-
mediaMigrationsModulePromise ??= import("../media-migrations-
|
|
152
|
+
mediaMigrationsModulePromise ??= import("../media-migrations-BNVAPYEM.mjs");
|
|
151
153
|
return mediaMigrationsModulePromise;
|
|
152
154
|
}
|
|
153
155
|
function loadGeneratorsModule() {
|
|
154
|
-
generatorsModulePromise ??= import("../generators-
|
|
156
|
+
generatorsModulePromise ??= import("../generators-VCYISHWO.mjs");
|
|
155
157
|
return generatorsModulePromise;
|
|
156
158
|
}
|
|
157
159
|
function loadBroadcastModule() {
|
|
158
|
-
broadcastModulePromise ??= import("../broadcast-
|
|
160
|
+
broadcastModulePromise ??= import("../broadcast-JBQWQZSO.mjs");
|
|
159
161
|
return broadcastModulePromise;
|
|
160
162
|
}
|
|
161
163
|
function loadSecurityModule() {
|
|
162
|
-
securityModulePromise ??= import("../security-
|
|
164
|
+
securityModulePromise ??= import("../security-K5PZS3E3.mjs");
|
|
163
165
|
return securityModulePromise;
|
|
164
166
|
}
|
|
165
167
|
function loadDevModule() {
|
|
166
|
-
devModulePromise ??= import("../dev-
|
|
168
|
+
devModulePromise ??= import("../dev-YPBQBEOE.mjs");
|
|
167
169
|
return devModulePromise;
|
|
168
170
|
}
|
|
169
171
|
function loadProjectConfigModule() {
|
|
@@ -179,9 +181,13 @@ function loadProjectRuntimeModule() {
|
|
|
179
181
|
return projectRuntimeModulePromise;
|
|
180
182
|
}
|
|
181
183
|
function loadProjectScaffoldModule() {
|
|
182
|
-
projectScaffoldModulePromise ??= import("../scaffold-
|
|
184
|
+
projectScaffoldModulePromise ??= import("../scaffold-NJ5VH73M.mjs");
|
|
183
185
|
return projectScaffoldModulePromise;
|
|
184
186
|
}
|
|
187
|
+
function loadAgentSkillsModule() {
|
|
188
|
+
agentSkillsModulePromise ??= import("../agent-skills-CHAXS2YN.mjs");
|
|
189
|
+
return agentSkillsModulePromise;
|
|
190
|
+
}
|
|
185
191
|
async function resolveRuntimeExecutor(runtimeExecutor) {
|
|
186
192
|
return runtimeExecutor ?? (await loadRuntimeModule()).withRuntimeEnvironment;
|
|
187
193
|
}
|
|
@@ -249,23 +255,47 @@ function createCommandContext(io, projectRoot, loadProject, input) {
|
|
|
249
255
|
loadProject
|
|
250
256
|
};
|
|
251
257
|
}
|
|
258
|
+
function serializePassthroughInput(input) {
|
|
259
|
+
const tokens = [...input.args];
|
|
260
|
+
for (const [name, value] of Object.entries(input.flags)) {
|
|
261
|
+
if (value === false) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const flag = name.length === 1 ? `-${name}` : `--${name}`;
|
|
265
|
+
const values = Array.isArray(value) ? value : [value];
|
|
266
|
+
for (const currentValue of values) {
|
|
267
|
+
tokens.push(flag);
|
|
268
|
+
if (currentValue !== true) {
|
|
269
|
+
tokens.push(String(currentValue));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return tokens;
|
|
274
|
+
}
|
|
252
275
|
function printCommandList(io, registry) {
|
|
253
276
|
const internal = registry.filter((command) => command.source === "internal");
|
|
254
277
|
const app = registry.filter((command) => command.source === "app");
|
|
255
|
-
writeLine(io.stdout, "
|
|
256
|
-
|
|
257
|
-
writeLine(io.stdout, ` ${command.usage} ${command.description}`);
|
|
258
|
-
}
|
|
278
|
+
writeLine(io.stdout, "Usage:");
|
|
279
|
+
writeLine(io.stdout, " holo <command> [options] [arguments]");
|
|
259
280
|
writeLine(io.stdout);
|
|
260
|
-
writeLine(io.stdout, "
|
|
281
|
+
writeLine(io.stdout, "Internal commands:");
|
|
282
|
+
printCommandListEntries(io, internal);
|
|
283
|
+
writeLine(io.stdout);
|
|
284
|
+
writeLine(io.stdout, "App commands:");
|
|
261
285
|
if (app.length === 0) {
|
|
262
286
|
writeLine(io.stdout, " (none)");
|
|
263
287
|
return;
|
|
264
288
|
}
|
|
265
|
-
|
|
266
|
-
|
|
289
|
+
printCommandListEntries(io, app);
|
|
290
|
+
}
|
|
291
|
+
function printCommandListEntries(io, commands) {
|
|
292
|
+
for (const command of commands) {
|
|
293
|
+
printCommandListEntry(io, command);
|
|
267
294
|
}
|
|
268
295
|
}
|
|
296
|
+
function printCommandListEntry(io, command) {
|
|
297
|
+
writeLine(io.stdout, ` ${command.name.padEnd(COMMAND_LIST_DESCRIPTION_COLUMN)}${command.description}`);
|
|
298
|
+
}
|
|
269
299
|
function printCommandHelp(io, command) {
|
|
270
300
|
writeLine(io.stdout, command.usage);
|
|
271
301
|
writeLine(io.stdout, command.description);
|
|
@@ -368,6 +398,50 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
368
398
|
writeLine(context.stdout, ` ${resolvePackageManagerDevCommand(packageManager)}`);
|
|
369
399
|
}
|
|
370
400
|
},
|
|
401
|
+
{
|
|
402
|
+
name: "agents:install",
|
|
403
|
+
aliases: ["agent:install", "ai:install"],
|
|
404
|
+
description: "Install Holo-JS docs-search skills for coding agents.",
|
|
405
|
+
usage: "holo agents:install [--agent <all|codex|claude|cursor|windsurf|opencode|gemini|kiro>] [--global] [--force]",
|
|
406
|
+
source: "internal",
|
|
407
|
+
async prepare(input) {
|
|
408
|
+
const { normalizeAgentSkillTargets, SUPPORTED_AGENT_SKILL_TARGETS } = await loadAgentSkillsModule();
|
|
409
|
+
const requestedAgents = (collectMultiStringFlag(input.flags, "agent") ?? []).flatMap((entry) => splitCsv(entry) ?? []);
|
|
410
|
+
const agents = requestedAgents.length > 0 ? normalizeAgentSkillTargets(requestedAgents) : isInteractive(context, input.flags) ? await promptMultiChoice(context, "Coding agents", SUPPORTED_AGENT_SKILL_TARGETS, {
|
|
411
|
+
required: true,
|
|
412
|
+
initialValues: [...SUPPORTED_AGENT_SKILL_TARGETS]
|
|
413
|
+
}) : normalizeAgentSkillTargets([]);
|
|
414
|
+
return {
|
|
415
|
+
args: [],
|
|
416
|
+
flags: {
|
|
417
|
+
agent: agents,
|
|
418
|
+
...resolveBooleanFlag(input.flags, "global") === true ? { global: true } : {},
|
|
419
|
+
...resolveBooleanFlag(input.flags, "force") === true ? { force: true } : {}
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
},
|
|
423
|
+
async run(commandContext) {
|
|
424
|
+
const { installAgentSkills } = await loadAgentSkillsModule();
|
|
425
|
+
const agents = collectMultiStringFlag(commandContext.flags, "agent") ?? [];
|
|
426
|
+
const results = await installAgentSkills(context.projectRoot, {
|
|
427
|
+
agents,
|
|
428
|
+
global: commandContext.flags.global === true,
|
|
429
|
+
force: commandContext.flags.force === true
|
|
430
|
+
});
|
|
431
|
+
const created = results.filter((result) => result.status === "created").length;
|
|
432
|
+
const updated = results.filter((result) => result.status === "updated").length;
|
|
433
|
+
const unchanged = results.filter((result) => result.status === "unchanged").length;
|
|
434
|
+
const changed = created + updated;
|
|
435
|
+
writeLine(
|
|
436
|
+
context.stdout,
|
|
437
|
+
changed > 0 ? "Installed Holo-JS agent skills." : "Holo-JS agent skills are already installed."
|
|
438
|
+
);
|
|
439
|
+
for (const result of results) {
|
|
440
|
+
writeLine(context.stdout, ` - ${result.status} ${result.agent}: ${result.path}`);
|
|
441
|
+
}
|
|
442
|
+
writeLine(context.stdout, ` - summary: ${created} created, ${updated} updated, ${unchanged} unchanged`);
|
|
443
|
+
}
|
|
444
|
+
},
|
|
371
445
|
{
|
|
372
446
|
name: "key:generate",
|
|
373
447
|
description: "Generate APP_KEY in the project .env file when it is missing.",
|
|
@@ -751,13 +825,18 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
751
825
|
{
|
|
752
826
|
name: "start",
|
|
753
827
|
description: "Run the production framework server with Holo runtime preloads.",
|
|
754
|
-
usage: "holo start",
|
|
828
|
+
usage: "holo start [...frameworkArgs]",
|
|
755
829
|
source: "internal",
|
|
756
|
-
async prepare() {
|
|
757
|
-
return { args:
|
|
830
|
+
async prepare(input) {
|
|
831
|
+
return { args: input.args, flags: input.flags };
|
|
758
832
|
},
|
|
759
|
-
async run() {
|
|
833
|
+
async run(input) {
|
|
760
834
|
const runProjectStartServer = await resolveProjectExecutor(projectExecutors, "runProjectStartServer");
|
|
835
|
+
const passthroughArgs = serializePassthroughInput(input);
|
|
836
|
+
if (passthroughArgs.length > 0) {
|
|
837
|
+
await runProjectStartServer(context, context.projectRoot, void 0, passthroughArgs);
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
761
840
|
await runProjectStartServer(context, context.projectRoot);
|
|
762
841
|
}
|
|
763
842
|
},
|
|
@@ -1577,7 +1656,8 @@ function findCommand(registry, name) {
|
|
|
1577
1656
|
async function runCli(argv, io) {
|
|
1578
1657
|
try {
|
|
1579
1658
|
const requestedCommandName = argv[0];
|
|
1580
|
-
const
|
|
1659
|
+
const usesCurrentDirectoryAsProjectRoot = requestedCommandName === "new" || requestedCommandName === "agents:install" || requestedCommandName === "agent:install" || requestedCommandName === "ai:install";
|
|
1660
|
+
const projectRoot = usesCurrentDirectoryAsProjectRoot ? io.cwd : await (await loadProjectRuntimeModule()).findProjectRoot(io.cwd);
|
|
1581
1661
|
let cachedProject;
|
|
1582
1662
|
const loadProject = async () => {
|
|
1583
1663
|
cachedProject ??= await (await loadProjectConfigModule()).loadProjectConfig(projectRoot);
|
|
@@ -1592,7 +1672,7 @@ async function runCli(argv, io) {
|
|
|
1592
1672
|
};
|
|
1593
1673
|
const internalCommands = createInternalCommands(internalContext);
|
|
1594
1674
|
const registry = [...internalCommands];
|
|
1595
|
-
const canSkipAppDiscovery = requestedCommandName === "config:cache" || requestedCommandName === "config:clear" || requestedCommandName === "key:generate" || requestedCommandName === "new" || requestedCommandName === "install" || requestedCommandName === "auth:notifications:publish" || requestedCommandName === "prepare" || requestedCommandName === "dev" || requestedCommandName === "build" || requestedCommandName === "cache:table" || requestedCommandName === "cache:clear" || requestedCommandName === "cache:forget" || requestedCommandName === "media:table" || requestedCommandName === "broadcast:work" || requestedCommandName === "queue:table" || requestedCommandName === "queue:failed-table" || requestedCommandName === "queue:work" || requestedCommandName === "queue:listen" || requestedCommandName === "queue:failed" || requestedCommandName === "queue:retry" || requestedCommandName === "queue:forget" || requestedCommandName === "queue:flush" || requestedCommandName === "queue:restart" || requestedCommandName === "queue:clear" || requestedCommandName === "rate-limit:clear";
|
|
1675
|
+
const canSkipAppDiscovery = requestedCommandName === "config:cache" || requestedCommandName === "config:clear" || requestedCommandName === "key:generate" || requestedCommandName === "new" || requestedCommandName === "install" || requestedCommandName === "agents:install" || requestedCommandName === "agent:install" || requestedCommandName === "ai:install" || requestedCommandName === "auth:notifications:publish" || requestedCommandName === "prepare" || requestedCommandName === "dev" || requestedCommandName === "build" || requestedCommandName === "cache:table" || requestedCommandName === "cache:clear" || requestedCommandName === "cache:forget" || requestedCommandName === "media:table" || requestedCommandName === "broadcast:work" || requestedCommandName === "queue:table" || requestedCommandName === "queue:failed-table" || requestedCommandName === "queue:work" || requestedCommandName === "queue:listen" || requestedCommandName === "queue:failed" || requestedCommandName === "queue:retry" || requestedCommandName === "queue:forget" || requestedCommandName === "queue:flush" || requestedCommandName === "queue:restart" || requestedCommandName === "queue:clear" || requestedCommandName === "rate-limit:clear";
|
|
1596
1676
|
if (!canSkipAppDiscovery) {
|
|
1597
1677
|
const initialProject = await loadProject();
|
|
1598
1678
|
const appCommands = (await (await loadProjectDiscoveryModule()).discoverAppCommands(projectRoot, initialProject.config)).map((entry) => createAppCommandDefinition(entry));
|
|
@@ -9,7 +9,7 @@ import "./chunk-D7O4SU6N.mjs";
|
|
|
9
9
|
import {
|
|
10
10
|
prepareProjectDiscovery
|
|
11
11
|
} from "./chunk-VP2E62DF.mjs";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-7B2RVYLL.mjs";
|
|
13
13
|
import {
|
|
14
14
|
loadProjectConfig
|
|
15
15
|
} from "./chunk-YEFJBN56.mjs";
|
|
@@ -146,6 +146,7 @@ async function createRealtimeWorkerBindings(projectRoot) {
|
|
|
146
146
|
return await withRealtimeRequest(options.context, async (authRequest) => {
|
|
147
147
|
return await realtime.subscribeRealtimeQuery(await resolveDefinition(name), args, {
|
|
148
148
|
onData: options.onData,
|
|
149
|
+
onPatch: options.onPatch,
|
|
149
150
|
onError: options.onError
|
|
150
151
|
}, { authRequest });
|
|
151
152
|
});
|
|
@@ -9,7 +9,7 @@ import "./chunk-D7O4SU6N.mjs";
|
|
|
9
9
|
import {
|
|
10
10
|
prepareProjectDiscovery
|
|
11
11
|
} from "./chunk-VP2E62DF.mjs";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-C624G3R2.mjs";
|
|
13
13
|
import {
|
|
14
14
|
loadProjectConfig
|
|
15
15
|
} from "./chunk-YEFJBN56.mjs";
|
|
@@ -146,6 +146,7 @@ async function createRealtimeWorkerBindings(projectRoot) {
|
|
|
146
146
|
return await withRealtimeRequest(options.context, async (authRequest) => {
|
|
147
147
|
return await realtime.subscribeRealtimeQuery(await resolveDefinition(name), args, {
|
|
148
148
|
onData: options.onData,
|
|
149
|
+
onPatch: options.onPatch,
|
|
149
150
|
onError: options.onError
|
|
150
151
|
}, { authRequest });
|
|
151
152
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runProjectPrepare
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4K4CWMMP.mjs";
|
|
4
4
|
import "./chunk-FGQ2I2YH.mjs";
|
|
5
5
|
import {
|
|
6
6
|
getRegistryMigrationSlug,
|
|
@@ -8,15 +8,15 @@ import {
|
|
|
8
8
|
hasRegisteredMigrationSlug,
|
|
9
9
|
nextMigrationTemplate
|
|
10
10
|
} from "./chunk-LXGQCG56.mjs";
|
|
11
|
+
import "./chunk-LBJAJLKU.mjs";
|
|
11
12
|
import {
|
|
12
13
|
writeLine
|
|
13
14
|
} from "./chunk-I7QBCEV7.mjs";
|
|
14
|
-
import "./chunk-LBJAJLKU.mjs";
|
|
15
15
|
import "./chunk-D7O4SU6N.mjs";
|
|
16
16
|
import {
|
|
17
17
|
prepareProjectDiscovery
|
|
18
18
|
} from "./chunk-VP2E62DF.mjs";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-C624G3R2.mjs";
|
|
20
20
|
import {
|
|
21
21
|
ensureProjectConfig
|
|
22
22
|
} from "./chunk-YEFJBN56.mjs";
|
|
@@ -94,14 +94,14 @@ function renderCacheTableMigration(tableName = DEFAULT_CACHE_DATABASE_TABLE, loc
|
|
|
94
94
|
const entryTableDefinition = resolveCacheDatabaseTableDefinition("entries");
|
|
95
95
|
const lockTableDefinition = resolveCacheDatabaseTableDefinition("locks");
|
|
96
96
|
return [
|
|
97
|
-
"import { defineMigration
|
|
97
|
+
"import { defineMigration } from '@holo-js/db'",
|
|
98
98
|
"",
|
|
99
99
|
"export default defineMigration({",
|
|
100
|
-
" async up({ schema }
|
|
100
|
+
" async up({ schema }) {",
|
|
101
101
|
...renderCacheTableCreateStatement(tableName, entryTableDefinition),
|
|
102
102
|
...renderCacheTableCreateStatement(lockTableName, lockTableDefinition),
|
|
103
103
|
" },",
|
|
104
|
-
" async down({ schema }
|
|
104
|
+
" async down({ schema }) {",
|
|
105
105
|
` await schema.dropTable('${escapeSingleQuotedString(lockTableName)}')`,
|
|
106
106
|
` await schema.dropTable('${escapeSingleQuotedString(tableName)}')`,
|
|
107
107
|
" },",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runProjectPrepare
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AJLRAC5M.mjs";
|
|
4
4
|
import "./chunk-FGQ2I2YH.mjs";
|
|
5
5
|
import {
|
|
6
6
|
getRegistryMigrationSlug,
|
|
@@ -8,15 +8,15 @@ import {
|
|
|
8
8
|
hasRegisteredMigrationSlug,
|
|
9
9
|
nextMigrationTemplate
|
|
10
10
|
} from "./chunk-LXGQCG56.mjs";
|
|
11
|
-
import "./chunk-LBJAJLKU.mjs";
|
|
12
11
|
import {
|
|
13
12
|
writeLine
|
|
14
13
|
} from "./chunk-I7QBCEV7.mjs";
|
|
14
|
+
import "./chunk-LBJAJLKU.mjs";
|
|
15
15
|
import "./chunk-D7O4SU6N.mjs";
|
|
16
16
|
import {
|
|
17
17
|
prepareProjectDiscovery
|
|
18
18
|
} from "./chunk-VP2E62DF.mjs";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-7B2RVYLL.mjs";
|
|
20
20
|
import {
|
|
21
21
|
ensureProjectConfig
|
|
22
22
|
} from "./chunk-YEFJBN56.mjs";
|
|
@@ -94,14 +94,14 @@ function renderCacheTableMigration(tableName = DEFAULT_CACHE_DATABASE_TABLE, loc
|
|
|
94
94
|
const entryTableDefinition = resolveCacheDatabaseTableDefinition("entries");
|
|
95
95
|
const lockTableDefinition = resolveCacheDatabaseTableDefinition("locks");
|
|
96
96
|
return [
|
|
97
|
-
"import { defineMigration
|
|
97
|
+
"import { defineMigration } from '@holo-js/db'",
|
|
98
98
|
"",
|
|
99
99
|
"export default defineMigration({",
|
|
100
|
-
" async up({ schema }
|
|
100
|
+
" async up({ schema }) {",
|
|
101
101
|
...renderCacheTableCreateStatement(tableName, entryTableDefinition),
|
|
102
102
|
...renderCacheTableCreateStatement(lockTableName, lockTableDefinition),
|
|
103
103
|
" },",
|
|
104
|
-
" async down({ schema }
|
|
104
|
+
" async down({ schema }) {",
|
|
105
105
|
` await schema.dropTable('${escapeSingleQuotedString(lockTableName)}')`,
|
|
106
106
|
` await schema.dropTable('${escapeSingleQuotedString(tableName)}')`,
|
|
107
107
|
" },",
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-VP2E62DF.mjs";
|
|
7
7
|
import {
|
|
8
8
|
syncManagedDriverDependencies
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-C624G3R2.mjs";
|
|
10
10
|
import {
|
|
11
11
|
ensureGeneratedSchemaPlaceholder,
|
|
12
12
|
ensureProjectConfig
|
|
@@ -97,9 +97,9 @@ async function runProjectBuild(io, projectRoot, spawn2 = spawnSync) {
|
|
|
97
97
|
throw new Error(result.stderr?.trim() || result.stdout?.trim() || "Project build failed.");
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
async function runProjectStartServer(io, projectRoot, spawnProcess = spawn) {
|
|
100
|
+
async function runProjectStartServer(io, projectRoot, spawnProcess = spawn, passthroughArgs = []) {
|
|
101
101
|
const invocation = resolveFrameworkRunnerInvocation(projectRoot, "start");
|
|
102
|
-
const child = spawnProcess(invocation.command, [...invocation.args], {
|
|
102
|
+
const child = spawnProcess(invocation.command, [...invocation.args, ...passthroughArgs], {
|
|
103
103
|
cwd: projectRoot,
|
|
104
104
|
env: process.env,
|
|
105
105
|
stdio: ["pipe", "pipe", "pipe"]
|