@intelligo-dev/cli 1.0.0-beta.13 → 1.0.0-beta.15
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 +65 -2
- package/dist/args.d.ts +10 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +20 -0
- package/dist/args.js.map +1 -0
- package/dist/bin.js +103 -22
- package/dist/bin.js.map +1 -1
- package/dist/commands/add.d.ts +4 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +28 -2
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/create-flow.d.ts +8 -1
- package/dist/commands/create-flow.d.ts.map +1 -1
- package/dist/commands/create-flow.js +101 -34
- package/dist/commands/create-flow.js.map +1 -1
- package/dist/commands/create.d.ts +24 -4
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +57 -14
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +123 -35
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/migrate-check.d.ts +20 -1
- package/dist/commands/migrate-check.d.ts.map +1 -1
- package/dist/commands/migrate-check.js +35 -6
- package/dist/commands/migrate-check.js.map +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +2 -8
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/sync-messages.d.ts +37 -0
- package/dist/commands/sync-messages.d.ts.map +1 -0
- package/dist/commands/sync-messages.js +88 -0
- package/dist/commands/sync-messages.js.map +1 -0
- package/dist/commands/sync-scaffold.d.ts +36 -0
- package/dist/commands/sync-scaffold.d.ts.map +1 -0
- package/dist/commands/sync-scaffold.js +53 -0
- package/dist/commands/sync-scaffold.js.map +1 -0
- package/dist/commands/sync.d.ts +109 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +392 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/upgrade-check.d.ts.map +1 -1
- package/dist/commands/upgrade-check.js +4 -1
- package/dist/commands/upgrade-check.js.map +1 -1
- package/dist/env-files.d.ts +11 -0
- package/dist/env-files.d.ts.map +1 -1
- package/dist/env-files.js +28 -9
- package/dist/env-files.js.map +1 -1
- package/dist/manifest.d.ts +27 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +30 -3
- package/dist/manifest.js.map +1 -1
- package/dist/module-exports.d.ts +63 -0
- package/dist/module-exports.d.ts.map +1 -0
- package/dist/module-exports.js +231 -0
- package/dist/module-exports.js.map +1 -0
- package/dist/registry-bundle.d.ts +43 -0
- package/dist/registry-bundle.d.ts.map +1 -0
- package/dist/registry-bundle.js +74 -0
- package/dist/registry-bundle.js.map +1 -0
- package/dist/registry-items.d.ts +41 -13
- package/dist/registry-items.d.ts.map +1 -1
- package/dist/registry-items.js +117 -33
- package/dist/registry-items.js.map +1 -1
- package/package.json +1 -1
- package/src/args.ts +25 -0
- package/src/bin.ts +124 -22
- package/src/commands/add.ts +39 -12
- package/src/commands/create-flow.ts +119 -29
- package/src/commands/create.ts +82 -14
- package/src/commands/doctor.ts +156 -47
- package/src/commands/migrate-check.ts +51 -10
- package/src/commands/migrate.ts +2 -8
- package/src/commands/sync-messages.ts +114 -0
- package/src/commands/sync-scaffold.ts +83 -0
- package/src/commands/sync.ts +574 -0
- package/src/commands/upgrade-check.ts +4 -1
- package/src/env-files.ts +28 -7
- package/src/manifest.ts +57 -3
- package/src/module-exports.ts +266 -0
- package/src/registry-bundle.ts +103 -0
- package/src/registry-items.ts +141 -36
- package/templates/admin-page/admin-page.tsx.tpl +96 -24
- package/templates/app-scaffold/gitignore.tpl +25 -0
- package/templates/app-scaffold/intelligo.ts.tpl +6 -47
- package/templates/app-scaffold/next.config.mjs.tpl +31 -2
- package/templates/app-scaffold/package.json.tpl +2 -2
- package/templates/manifest.json +40 -3
- package/templates/pnpm-standalone/npmrc.tpl +6 -0
- package/templates/pnpm-standalone/pnpm-workspace.yaml.tpl +10 -0
- package/templates/registry/ai-agent-activity.json +23 -0
- package/templates/registry/ai-agent-progress.json +21 -0
- package/templates/registry/ai-approval-card.json +27 -0
- package/templates/registry/ai-artifact.json +22 -0
- package/templates/registry/ai-branch.json +21 -0
- package/templates/registry/ai-citations.json +24 -0
- package/templates/registry/ai-code-block.json +23 -0
- package/templates/registry/ai-composer-menu.json +19 -0
- package/templates/registry/ai-file-diff.json +25 -0
- package/templates/registry/ai-image-generation.json +23 -0
- package/templates/registry/ai-markdown.json +23 -0
- package/templates/registry/ai-message-bubble.json +23 -0
- package/templates/registry/ai-message-scroller.json +22 -0
- package/templates/registry/ai-message.json +21 -0
- package/templates/registry/ai-motion.json +19 -0
- package/templates/registry/ai-prompt-input.json +28 -0
- package/templates/registry/ai-reasoning-text.json +22 -0
- package/templates/registry/ai-reasoning.json +22 -0
- package/templates/registry/ai-shimmer-text.json +19 -0
- package/templates/registry/ai-sidebar.json +25 -0
- package/templates/registry/ai-speech-input.json +21 -0
- package/templates/registry/ai-streaming-response.json +24 -0
- package/templates/registry/ai-suggestion.json +19 -0
- package/templates/registry/ai-todo-list.json +22 -0
- package/templates/registry/ai-tool-approval.json +26 -0
- package/templates/registry/ai-tool-result.json +25 -0
- package/templates/registry/alert-dialog.json +23 -0
- package/templates/registry/animated-list.json +21 -0
- package/templates/registry/app-shell.json +93 -0
- package/templates/registry/artifacts.json +82 -0
- package/templates/registry/attachment.json +22 -0
- package/templates/registry/auth-email-verification.json +39 -0
- package/templates/registry/auth-login.json +72 -0
- package/templates/registry/auth-password-reset.json +53 -0
- package/templates/registry/auth-signup.json +41 -0
- package/templates/registry/billing-settings.json +66 -0
- package/templates/registry/button.json +22 -0
- package/templates/registry/chat-eve.json +19 -0
- package/templates/registry/chat-panel.json +30 -0
- package/templates/registry/chat-share.json +42 -0
- package/templates/registry/chat-widget.json +34 -0
- package/templates/registry/chat.json +326 -0
- package/templates/registry/checkbox.json +22 -0
- package/templates/registry/checkout.json +40 -0
- package/templates/registry/collapsible.json +19 -0
- package/templates/registry/command.json +23 -0
- package/templates/registry/copy-button.json +21 -0
- package/templates/registry/dashboard.json +69 -0
- package/templates/registry/dialog.json +24 -0
- package/templates/registry/document-viewer.json +22 -0
- package/templates/registry/dropdown-menu.json +23 -0
- package/templates/registry/expandable-tabs.json +22 -0
- package/templates/registry/feature-gating.json +73 -0
- package/templates/registry/file-upload.json +24 -0
- package/templates/registry/hold-action-button.json +22 -0
- package/templates/registry/input-group.json +23 -0
- package/templates/registry/input.json +19 -0
- package/templates/registry/intelligo.json +187 -0
- package/templates/registry/invitation-accept.json +64 -0
- package/templates/registry/language-switcher.json +29 -0
- package/templates/registry/morphing-modal.json +24 -0
- package/templates/registry/notification-stack.json +24 -0
- package/templates/registry/notifications.json +87 -0
- package/templates/registry/onboarding.json +83 -0
- package/templates/registry/otp-input.json +22 -0
- package/templates/registry/page-header.json +15 -0
- package/templates/registry/payment-poll.json +58 -0
- package/templates/registry/popover-morph.json +22 -0
- package/templates/registry/popover.json +22 -0
- package/templates/registry/pricing.json +117 -0
- package/templates/registry/privacy-settings.json +65 -0
- package/templates/registry/profile-settings.json +68 -0
- package/templates/registry/progress.json +19 -0
- package/templates/registry/radio-group.json +22 -0
- package/templates/registry/registry.json +2960 -0
- package/templates/registry/route-error.json +65 -0
- package/templates/registry/select-morph.json +23 -0
- package/templates/registry/select.json +23 -0
- package/templates/registry/settings-shell.json +47 -0
- package/templates/registry/sheet.json +24 -0
- package/templates/registry/sidebar.json +28 -0
- package/templates/registry/smoke.json +34 -0
- package/templates/registry/spinner.json +16 -0
- package/templates/registry/stat-card.json +18 -0
- package/templates/registry/status-badge.json +18 -0
- package/templates/registry/switch.json +20 -0
- package/templates/registry/tabs.json +23 -0
- package/templates/registry/team-settings.json +97 -0
- package/templates/registry/textarea.json +16 -0
- package/templates/registry/tooltip.json +22 -0
- package/templates/registry/trial-banner.json +43 -0
- package/templates/registry/usage.json +84 -0
- package/templates/registry/workspace-settings.json +71 -0
- package/templates/registry-items.json +3 -3
- package/templates/registry-requires.json +30 -4
- package/templates/vitest/server-only.ts.tpl +7 -0
- package/templates/vitest/vitest.config.ts.tpl +37 -0
package/dist/registry-items.js
CHANGED
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
* is, what else it needs installed first, and the commands that install
|
|
4
4
|
* a selection into a fresh app.
|
|
5
5
|
*
|
|
6
|
-
* Installing
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* (requires.json `items`) has to land after it.
|
|
6
|
+
* Installing goes through `intelligo sync` (commands/sync.ts): one
|
|
7
|
+
* `shadcn add` per item from the registry bundled with this CLI, in the
|
|
8
|
+
* order requires.json `items` implies — an item that imports a
|
|
9
|
+
* sibling's files lands after it.
|
|
11
10
|
*/
|
|
12
11
|
import { existsSync, readFileSync } from "node:fs";
|
|
13
12
|
import path from "node:path";
|
|
@@ -56,8 +55,16 @@ export function detectPackageManager(userAgent = process.env.npm_config_user_age
|
|
|
56
55
|
const name = userAgent?.split("/")[0];
|
|
57
56
|
return name === "npm" || name === "yarn" || name === "bun" ? name : "pnpm";
|
|
58
57
|
}
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
/**
|
|
59
|
+
* The command as a reader pastes it from `from` (the app's directory):
|
|
60
|
+
* a command that runs elsewhere is wrapped in a `cd`.
|
|
61
|
+
*/
|
|
62
|
+
export function formatCommand(c, from) {
|
|
63
|
+
const line = [c.command, ...c.args].join(" ");
|
|
64
|
+
if (!c.cwd || !from || path.resolve(c.cwd) === path.resolve(from)) {
|
|
65
|
+
return line;
|
|
66
|
+
}
|
|
67
|
+
return `(cd ${path.relative(from, c.cwd) || "."} && ${line})`;
|
|
61
68
|
}
|
|
62
69
|
const EXEC = {
|
|
63
70
|
pnpm: ["pnpm", "exec"],
|
|
@@ -69,35 +76,112 @@ const EXEC = {
|
|
|
69
76
|
export function hasLocalShadcn(appRoot) {
|
|
70
77
|
return existsSync(path.join(appRoot, "node_modules", ".bin", "shadcn"));
|
|
71
78
|
}
|
|
79
|
+
/** The `packages:` globs of a pnpm-workspace.yaml (`!` exclusions kept). */
|
|
80
|
+
export function workspaceGlobs(yaml) {
|
|
81
|
+
const globs = [];
|
|
82
|
+
let inPackages = false;
|
|
83
|
+
for (const raw of yaml.split(/\r?\n/)) {
|
|
84
|
+
const line = raw.replace(/\s+#.*$/, "");
|
|
85
|
+
const key = /^packages\s*:\s*(.*)$/.exec(line);
|
|
86
|
+
if (key) {
|
|
87
|
+
const flow = /^\[(.*)\]$/.exec(key[1].trim());
|
|
88
|
+
if (flow) {
|
|
89
|
+
for (const g of flow[1].split(",")) {
|
|
90
|
+
const glob = g.trim().replace(/^["']|["']$/g, "");
|
|
91
|
+
if (glob)
|
|
92
|
+
globs.push(glob);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else
|
|
96
|
+
inPackages = true;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (!inPackages)
|
|
100
|
+
continue;
|
|
101
|
+
const entry = /^\s+-\s*(.+?)\s*$/.exec(line);
|
|
102
|
+
if (entry)
|
|
103
|
+
globs.push(entry[1].replace(/^["']|["']$/g, ""));
|
|
104
|
+
else if (/^\S/.test(line))
|
|
105
|
+
inPackages = false;
|
|
106
|
+
}
|
|
107
|
+
return globs;
|
|
108
|
+
}
|
|
109
|
+
function globToRegExp(glob) {
|
|
110
|
+
const pattern = glob
|
|
111
|
+
.replace(/^\.\//, "")
|
|
112
|
+
.replace(/\/+$/, "")
|
|
113
|
+
.split(/(\*\*|\*|\?)/)
|
|
114
|
+
.map((part) => part === "**"
|
|
115
|
+
? ".*"
|
|
116
|
+
: part === "*"
|
|
117
|
+
? "[^/]*"
|
|
118
|
+
: part === "?"
|
|
119
|
+
? "[^/]"
|
|
120
|
+
: part.replace(/[.+^${}()|[\]\\]/g, "\\$&"))
|
|
121
|
+
.join("");
|
|
122
|
+
return new RegExp(`^${pattern}$`);
|
|
123
|
+
}
|
|
72
124
|
/**
|
|
73
|
-
* The
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
|
|
125
|
+
* The root of the pnpm workspace that has `appRoot` as a member, if
|
|
126
|
+
* any: the nearest pnpm-workspace.yaml above the app, when one of its
|
|
127
|
+
* `packages` globs matches the app's path and no `!` glob excludes it.
|
|
128
|
+
* Installing from there updates the workspace's one lockfile instead of
|
|
129
|
+
* starting a nested one in the app.
|
|
130
|
+
*/
|
|
131
|
+
export function findWorkspaceRoot(appRoot) {
|
|
132
|
+
const app = path.resolve(appRoot);
|
|
133
|
+
let dir = path.dirname(app);
|
|
134
|
+
for (;;) {
|
|
135
|
+
const file = path.join(dir, "pnpm-workspace.yaml");
|
|
136
|
+
if (existsSync(file)) {
|
|
137
|
+
const rel = path.relative(dir, app).split(path.sep).join("/");
|
|
138
|
+
const globs = workspaceGlobs(readFileSync(file, "utf8"));
|
|
139
|
+
const included = globs
|
|
140
|
+
.filter((g) => !g.startsWith("!"))
|
|
141
|
+
.some((g) => globToRegExp(g).test(rel));
|
|
142
|
+
const excluded = globs
|
|
143
|
+
.filter((g) => g.startsWith("!"))
|
|
144
|
+
.some((g) => globToRegExp(g.slice(1)).test(rel));
|
|
145
|
+
return included && !excluded ? dir : null;
|
|
146
|
+
}
|
|
147
|
+
const parent = path.dirname(dir);
|
|
148
|
+
if (parent === dir)
|
|
149
|
+
return null;
|
|
150
|
+
dir = parent;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/** The design-system base, installed before any page. */
|
|
154
|
+
const BASE = "intelligo";
|
|
155
|
+
/**
|
|
156
|
+
* How `items` get into the app at `appRoot`: the dependencies first
|
|
157
|
+
* when shadcn is missing, then `intelligo sync` of the base and every
|
|
158
|
+
* item — one `shadcn add` per item in dependency order, from the
|
|
159
|
+
* registry bundled with this CLI, with `--force` because a fresh
|
|
160
|
+
* scaffold's files (globals.css, the theme provider) are the registry's
|
|
161
|
+
* to replace. Null when nothing was picked.
|
|
79
162
|
*/
|
|
80
163
|
export function installPlan(items, options) {
|
|
81
164
|
if (items.length === 0)
|
|
82
|
-
return
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
165
|
+
return null;
|
|
166
|
+
const packageManager = options.workspaceRoot
|
|
167
|
+
? "pnpm"
|
|
168
|
+
: options.packageManager;
|
|
169
|
+
const [command, ...exec] = EXEC[packageManager];
|
|
170
|
+
const synced = [BASE, ...items.filter((n) => n !== BASE)];
|
|
171
|
+
return {
|
|
172
|
+
install: hasLocalShadcn(options.appRoot)
|
|
173
|
+
? null
|
|
174
|
+
: {
|
|
175
|
+
command: packageManager,
|
|
176
|
+
args: ["install"],
|
|
177
|
+
cwd: options.workspaceRoot ?? options.appRoot,
|
|
178
|
+
},
|
|
179
|
+
items: synced,
|
|
180
|
+
sync: {
|
|
181
|
+
command: command,
|
|
182
|
+
args: [...exec, "intelligo", "sync", ...synced, "--force"],
|
|
183
|
+
cwd: options.appRoot,
|
|
184
|
+
},
|
|
185
|
+
};
|
|
102
186
|
}
|
|
103
187
|
//# sourceMappingURL=registry-items.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry-items.js","sourceRoot":"","sources":["../src/registry-items.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"registry-items.js","sourceRoot":"","sources":["../src/registry-items.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/args.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The flags a command accepts. A flag it does not know is an error
|
|
3
|
+
* rather than ignored: `sync --chek` must not apply, and `add --all`
|
|
4
|
+
* must not look as if it did something.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export function unknownFlags(
|
|
8
|
+
args: readonly string[],
|
|
9
|
+
allowed: readonly string[]
|
|
10
|
+
): string[] {
|
|
11
|
+
return args.filter((arg) => arg.startsWith("-") && !allowed.includes(arg));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function wantsHelp(args: readonly string[]): boolean {
|
|
15
|
+
return args.includes("--help") || args.includes("-h");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** `a,b c` → `["a", "b", "c"]`: items as `create --items` takes them, or space-separated. */
|
|
19
|
+
export function itemNames(args: readonly string[]): string[] {
|
|
20
|
+
return args
|
|
21
|
+
.filter((arg) => !arg.startsWith("-"))
|
|
22
|
+
.flatMap((arg) => arg.split(","))
|
|
23
|
+
.map((name) => name.trim())
|
|
24
|
+
.filter(Boolean);
|
|
25
|
+
}
|
package/src/bin.ts
CHANGED
|
@@ -35,13 +35,26 @@ import {
|
|
|
35
35
|
applyMigrations,
|
|
36
36
|
formatApplyResult,
|
|
37
37
|
} from "./commands/migrate.js";
|
|
38
|
+
import {
|
|
39
|
+
formatSyncReport,
|
|
40
|
+
installedFrameworkVersion,
|
|
41
|
+
selectItems,
|
|
42
|
+
syncApply,
|
|
43
|
+
syncCheck,
|
|
44
|
+
syncCheckExitCode,
|
|
45
|
+
type SyncContext,
|
|
46
|
+
} from "./commands/sync.js";
|
|
38
47
|
import {
|
|
39
48
|
formatUpgradeReport,
|
|
40
49
|
upgradeCheck,
|
|
41
50
|
upgradeCheckExitCode,
|
|
42
51
|
} from "./commands/upgrade-check.js";
|
|
43
52
|
|
|
53
|
+
import { itemNames, unknownFlags, wantsHelp } from "./args.js";
|
|
44
54
|
import { loadAppEnv } from "./env-files.js";
|
|
55
|
+
import { workspaceRootVariable } from "./commands/create.js";
|
|
56
|
+
import { resolveRegistryDir } from "./registry-bundle.js";
|
|
57
|
+
import { findWorkspaceRoot, readRegistryCatalogue } from "./registry-items.js";
|
|
45
58
|
import { MIGRATION_LOCATIONS, resolveMigrationsDir } from "./migrations-dir.js";
|
|
46
59
|
|
|
47
60
|
/**
|
|
@@ -74,7 +87,7 @@ function usage(): string {
|
|
|
74
87
|
"intelligo <command>",
|
|
75
88
|
"",
|
|
76
89
|
" create [dir] Scaffold an app, then install the registry pages you pick",
|
|
77
|
-
" (--items a,b | --all, --yes, --no-install)",
|
|
90
|
+
" (--items a,b | --all, --yes, --no-install, --name <name>)",
|
|
78
91
|
" doctor Report configuration and migration-chain problems",
|
|
79
92
|
" migrate Apply the framework's migration chain to DATABASE_URL",
|
|
80
93
|
" migrate --check Compare the framework's migrations to a database",
|
|
@@ -82,6 +95,10 @@ function usage(): string {
|
|
|
82
95
|
" fresh | ahead | unmanaged | legacy)",
|
|
83
96
|
" add <feature> Generate consumer-owned source (--force to overwrite)",
|
|
84
97
|
" upgrade --check Show what a template upgrade would change",
|
|
98
|
+
" sync [items…] Install registry pages from this release's registry",
|
|
99
|
+
" (names space- or comma-separated),",
|
|
100
|
+
" keeping seams and merging messages (--force replaces",
|
|
101
|
+
" hand-edited files; --check only reports, exit 1 on drift)",
|
|
85
102
|
"",
|
|
86
103
|
].join("\n");
|
|
87
104
|
}
|
|
@@ -164,17 +181,72 @@ async function runMigrate(
|
|
|
164
181
|
}
|
|
165
182
|
}
|
|
166
183
|
|
|
184
|
+
function flagsOk(
|
|
185
|
+
command: string,
|
|
186
|
+
args: readonly string[],
|
|
187
|
+
allowed: readonly string[]
|
|
188
|
+
): boolean {
|
|
189
|
+
const unknown = unknownFlags(args, allowed);
|
|
190
|
+
if (unknown.length === 0) return true;
|
|
191
|
+
console.error(
|
|
192
|
+
`intelligo ${command}: unknown argument ${unknown.join(" ")}` +
|
|
193
|
+
(allowed.length ? ` (it takes ${allowed.join(", ")}).` : ".")
|
|
194
|
+
);
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function runAdd(rest: readonly string[]): number {
|
|
199
|
+
if (!flagsOk("add", rest, ["--force"])) return 2;
|
|
200
|
+
const feature = rest.find((a) => !a.startsWith("--"));
|
|
201
|
+
if (!feature) {
|
|
202
|
+
const catalogue = readCatalogue(TEMPLATES_DIR);
|
|
203
|
+
console.error("Usage: intelligo add <feature>\n");
|
|
204
|
+
for (const [name, spec] of Object.entries(catalogue)) {
|
|
205
|
+
console.error(` ${name.padEnd(16)} ${spec.description}`);
|
|
206
|
+
}
|
|
207
|
+
return 1;
|
|
208
|
+
}
|
|
209
|
+
if (feature === "pnpm-standalone" && findWorkspaceRoot(process.cwd())) {
|
|
210
|
+
console.error(
|
|
211
|
+
"intelligo add pnpm-standalone: this app is a member of a pnpm workspace, and a " +
|
|
212
|
+
"workspace file of its own would take it out; the workspace root's settings apply."
|
|
213
|
+
);
|
|
214
|
+
return 1;
|
|
215
|
+
}
|
|
216
|
+
const result = addFeature(feature, {
|
|
217
|
+
appRoot: process.cwd(),
|
|
218
|
+
templatesDir: TEMPLATES_DIR,
|
|
219
|
+
frameworkVersion: FRAMEWORK_VERSION,
|
|
220
|
+
force: rest.includes("--force"),
|
|
221
|
+
// Computed, not recorded: an app made before the variable existed
|
|
222
|
+
// has no value for it.
|
|
223
|
+
variables:
|
|
224
|
+
feature === "app-scaffold"
|
|
225
|
+
? workspaceRootVariable(process.cwd())
|
|
226
|
+
: undefined,
|
|
227
|
+
});
|
|
228
|
+
console.log(formatAddResult(result));
|
|
229
|
+
return addExitCode(result);
|
|
230
|
+
}
|
|
231
|
+
|
|
167
232
|
async function main(): Promise<number> {
|
|
168
233
|
const [, , command = "help", ...rest] = process.argv;
|
|
169
234
|
|
|
235
|
+
if (wantsHelp(rest)) {
|
|
236
|
+
console.log(usage());
|
|
237
|
+
return 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
170
240
|
// The commands that read the app's configuration see what the app
|
|
171
|
-
// itself would: its .env.local and .env,
|
|
241
|
+
// itself would: its .env.local and .env, then the pnpm workspace
|
|
242
|
+
// root's, under anything the shell set.
|
|
172
243
|
if (command === "doctor" || command === "migrate" || command === "upgrade") {
|
|
173
244
|
loadAppEnv(process.cwd());
|
|
174
245
|
}
|
|
175
246
|
|
|
176
247
|
switch (command) {
|
|
177
248
|
case "doctor": {
|
|
249
|
+
if (!flagsOk("doctor", rest, [])) return 2;
|
|
178
250
|
const results = runChecks();
|
|
179
251
|
console.log(formatResults(results));
|
|
180
252
|
return exitCodeFor(results);
|
|
@@ -203,32 +275,24 @@ async function main(): Promise<number> {
|
|
|
203
275
|
// command that converses.
|
|
204
276
|
const { parseCreateFlags, runCreate } =
|
|
205
277
|
await import("./commands/create-flow.js");
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const feature = rest.find((a) => !a.startsWith("--"));
|
|
214
|
-
if (!feature) {
|
|
215
|
-
const catalogue = readCatalogue(TEMPLATES_DIR);
|
|
216
|
-
console.error("Usage: intelligo add <feature>\n");
|
|
217
|
-
for (const [name, spec] of Object.entries(catalogue)) {
|
|
218
|
-
console.error(` ${name.padEnd(16)} ${spec.description}`);
|
|
219
|
-
}
|
|
220
|
-
return 1;
|
|
278
|
+
const flags = parseCreateFlags(rest);
|
|
279
|
+
if (flags.unknown.length > 0) {
|
|
280
|
+
console.error(
|
|
281
|
+
`intelligo create: unknown argument ${flags.unknown.join(" ")}.\n`
|
|
282
|
+
);
|
|
283
|
+
console.error(usage());
|
|
284
|
+
return 2;
|
|
221
285
|
}
|
|
222
|
-
|
|
223
|
-
appRoot: process.cwd(),
|
|
286
|
+
return runCreate(flags, {
|
|
224
287
|
templatesDir: TEMPLATES_DIR,
|
|
225
288
|
frameworkVersion: FRAMEWORK_VERSION,
|
|
226
|
-
|
|
289
|
+
interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
227
290
|
});
|
|
228
|
-
console.log(formatAddResult(result));
|
|
229
|
-
return addExitCode(result);
|
|
230
291
|
}
|
|
292
|
+
case "add":
|
|
293
|
+
return runAdd(rest);
|
|
231
294
|
case "upgrade": {
|
|
295
|
+
if (!flagsOk("upgrade", rest, ["--check"])) return 2;
|
|
232
296
|
if (!rest.includes("--check")) {
|
|
233
297
|
console.error("Only `upgrade --check` is implemented.");
|
|
234
298
|
console.error(
|
|
@@ -245,7 +309,45 @@ async function main(): Promise<number> {
|
|
|
245
309
|
console.log(formatUpgradeReport(report));
|
|
246
310
|
return upgradeCheckExitCode(report);
|
|
247
311
|
}
|
|
312
|
+
case "sync": {
|
|
313
|
+
if (!flagsOk("sync", rest, ["--check", "--force"])) return 2;
|
|
314
|
+
const registryDir = resolveRegistryDir(TEMPLATES_DIR);
|
|
315
|
+
if (!registryDir) {
|
|
316
|
+
console.error(
|
|
317
|
+
"This CLI has no bundled registry — in the framework repository, run `pnpm registry:build` first."
|
|
318
|
+
);
|
|
319
|
+
return 1;
|
|
320
|
+
}
|
|
321
|
+
const context: SyncContext = {
|
|
322
|
+
appRoot: process.cwd(),
|
|
323
|
+
registryDir,
|
|
324
|
+
requires: readRegistryCatalogue(TEMPLATES_DIR).requires,
|
|
325
|
+
frameworkVersion: FRAMEWORK_VERSION,
|
|
326
|
+
};
|
|
327
|
+
const installed = installedFrameworkVersion(context.appRoot);
|
|
328
|
+
if (installed && installed !== FRAMEWORK_VERSION) {
|
|
329
|
+
console.error(
|
|
330
|
+
`! @intelligo-dev/core is ${installed} but this CLI carries the ${FRAMEWORK_VERSION} registry — ` +
|
|
331
|
+
"run the CLI of the same version (`pnpm exec intelligo`), or pages and packages will disagree."
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
const selection = selectItems(itemNames(rest), context);
|
|
335
|
+
if (!selection.ok) {
|
|
336
|
+
console.error(selection.message);
|
|
337
|
+
return 1;
|
|
338
|
+
}
|
|
339
|
+
if (rest.includes("--check")) {
|
|
340
|
+
const report = syncCheck(selection.items, context);
|
|
341
|
+
console.log(formatSyncReport(report));
|
|
342
|
+
return syncCheckExitCode(report);
|
|
343
|
+
}
|
|
344
|
+
return syncApply(selection.items, context, {
|
|
345
|
+
force: rest.includes("--force"),
|
|
346
|
+
});
|
|
347
|
+
}
|
|
248
348
|
case "help":
|
|
349
|
+
case "--help":
|
|
350
|
+
case "-h":
|
|
249
351
|
console.log(usage());
|
|
250
352
|
return 0;
|
|
251
353
|
default:
|
package/src/commands/add.ts
CHANGED
|
@@ -30,6 +30,8 @@ export type TemplateFeature = {
|
|
|
30
30
|
deprecated?: string;
|
|
31
31
|
files: TemplateFile[];
|
|
32
32
|
cron?: TemplateCron;
|
|
33
|
+
/** What the developer still does by hand once the files are written. */
|
|
34
|
+
nextSteps?: string[];
|
|
33
35
|
};
|
|
34
36
|
export type TemplateCatalogue = Record<string, TemplateFeature>;
|
|
35
37
|
|
|
@@ -54,6 +56,8 @@ export type AddResult = {
|
|
|
54
56
|
* app has a vercel.json without it, which is the consumer's to edit.
|
|
55
57
|
*/
|
|
56
58
|
cron?: TemplateCron & { status: "written" | "present" | "manual" };
|
|
59
|
+
/** The catalogue's steps left to the developer, printed after the files. */
|
|
60
|
+
nextSteps?: string[];
|
|
57
61
|
};
|
|
58
62
|
|
|
59
63
|
export type AddOptions = {
|
|
@@ -81,6 +85,9 @@ export function substitute(
|
|
|
81
85
|
);
|
|
82
86
|
}
|
|
83
87
|
|
|
88
|
+
/** A `__NAME__` placeholder the variables did not fill. */
|
|
89
|
+
const PLACEHOLDER = /__[A-Z][A-Z0-9_]*__/;
|
|
90
|
+
|
|
84
91
|
const VERCEL_CONFIG = "vercel.json";
|
|
85
92
|
|
|
86
93
|
/**
|
|
@@ -137,16 +144,39 @@ export function addFeature(feature: string, options: AddOptions): AddResult {
|
|
|
137
144
|
skippedUnknown: [],
|
|
138
145
|
};
|
|
139
146
|
if (spec.deprecated) result.deprecated = spec.deprecated;
|
|
147
|
+
if (spec.nextSteps?.length) result.nextSteps = spec.nextSteps;
|
|
140
148
|
const recorded: GeneratedFile[] = [];
|
|
149
|
+
const handedOver = new Set(previous?.handedOver ?? []);
|
|
150
|
+
|
|
151
|
+
// Re-generating a feature substitutes what it was generated with, so
|
|
152
|
+
// `add app-scaffold` in an app `create` made takes the app's own name;
|
|
153
|
+
// values passed now fill in or replace them.
|
|
154
|
+
const variables =
|
|
155
|
+
previous?.variables || options.variables
|
|
156
|
+
? { ...previous?.variables, ...options.variables }
|
|
157
|
+
: undefined;
|
|
141
158
|
|
|
159
|
+
// Checked before anything is written, so a refusal leaves no half-made
|
|
160
|
+
// feature behind.
|
|
142
161
|
for (const file of spec.files) {
|
|
162
|
+
const unfilled = substitute(
|
|
163
|
+
readFileSync(path.join(options.templatesDir, file.template), "utf8"),
|
|
164
|
+
variables
|
|
165
|
+
).match(PLACEHOLDER);
|
|
166
|
+
if (unfilled) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
`${feature} needs a value for ${unfilled[0]} that only \`intelligo create\` supplies — ` +
|
|
169
|
+
"run `intelligo create <directory>`, or `intelligo create .` in an empty one."
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
for (const file of spec.files) {
|
|
175
|
+
// A registry item replaced it; `intelligo sync` keeps it now.
|
|
176
|
+
if (handedOver.has(file.target)) continue;
|
|
143
177
|
const source = path.join(options.templatesDir, file.template);
|
|
144
178
|
const target = path.join(options.appRoot, file.target);
|
|
145
|
-
const contents = substitute(
|
|
146
|
-
readFileSync(source, "utf8"),
|
|
147
|
-
options.variables
|
|
148
|
-
);
|
|
149
|
-
|
|
179
|
+
const contents = substitute(readFileSync(source, "utf8"), variables);
|
|
150
180
|
if (existsSync(target) && !options.force) {
|
|
151
181
|
const current = hashContents(readFileSync(target, "utf8"));
|
|
152
182
|
const known = previousByPath.get(file.target);
|
|
@@ -182,13 +212,7 @@ export function addFeature(feature: string, options: AddOptions): AddResult {
|
|
|
182
212
|
|
|
183
213
|
writeManifest(
|
|
184
214
|
options.appRoot,
|
|
185
|
-
recordFeature(
|
|
186
|
-
manifest,
|
|
187
|
-
feature,
|
|
188
|
-
spec.templateVersion,
|
|
189
|
-
recorded,
|
|
190
|
-
options.variables
|
|
191
|
-
)
|
|
215
|
+
recordFeature(manifest, feature, spec.templateVersion, recorded, variables)
|
|
192
216
|
);
|
|
193
217
|
|
|
194
218
|
return result;
|
|
@@ -212,6 +236,9 @@ export function formatAddResult(r: AddResult): string {
|
|
|
212
236
|
)
|
|
213
237
|
lines.push(" nothing to do");
|
|
214
238
|
if (r.cron) lines.push(...cronNextSteps(r.cron));
|
|
239
|
+
if (r.nextSteps?.length) {
|
|
240
|
+
lines.push("", " Next:", ...r.nextSteps.map((step) => ` - ${step}`));
|
|
241
|
+
}
|
|
215
242
|
return lines.join("\n");
|
|
216
243
|
}
|
|
217
244
|
|