planmode 0.1.1 → 0.1.3
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/index.js +25 -11
- package/package.json +1 -1
- package/src/commands/install.ts +16 -1
- package/src/commands/publish.ts +6 -6
- package/src/index.ts +1 -1
- package/src/lib/installer.ts +3 -2
- package/src/types/index.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -644,10 +644,11 @@ async function installPackage(packageName, options = {}) {
|
|
|
644
644
|
const { version, metadata } = await resolveVersion(packageName, options.version);
|
|
645
645
|
const versionMeta = await fetchVersionMetadata(packageName, version);
|
|
646
646
|
logger.info(`Fetching ${packageName}@${version}...`);
|
|
647
|
+
const basePath = versionMeta.source.path ? `${versionMeta.source.path}/` : "";
|
|
647
648
|
const manifestRaw = await fetchFileAtTag(
|
|
648
649
|
versionMeta.source.repository,
|
|
649
650
|
versionMeta.source.tag,
|
|
650
|
-
|
|
651
|
+
`${basePath}planmode.yaml`
|
|
651
652
|
);
|
|
652
653
|
const manifest = parseManifest(manifestRaw);
|
|
653
654
|
let content;
|
|
@@ -657,7 +658,7 @@ async function installPackage(packageName, options = {}) {
|
|
|
657
658
|
content = await fetchFileAtTag(
|
|
658
659
|
versionMeta.source.repository,
|
|
659
660
|
versionMeta.source.tag,
|
|
660
|
-
manifest.content_file
|
|
661
|
+
`${basePath}${manifest.content_file}`
|
|
661
662
|
);
|
|
662
663
|
} else {
|
|
663
664
|
throw new Error("Package has no content or content_file");
|
|
@@ -752,14 +753,27 @@ async function updatePackage(packageName, projectDir = process.cwd()) {
|
|
|
752
753
|
}
|
|
753
754
|
|
|
754
755
|
// src/commands/install.ts
|
|
755
|
-
|
|
756
|
+
function parseVariables(pairs) {
|
|
757
|
+
const vars = {};
|
|
758
|
+
for (const pair of pairs) {
|
|
759
|
+
const eq = pair.indexOf("=");
|
|
760
|
+
if (eq === -1) {
|
|
761
|
+
throw new Error(`Invalid variable format: "${pair}". Use --set key=value`);
|
|
762
|
+
}
|
|
763
|
+
vars[pair.slice(0, eq)] = pair.slice(eq + 1);
|
|
764
|
+
}
|
|
765
|
+
return vars;
|
|
766
|
+
}
|
|
767
|
+
var installCommand = new Command("install").description("Install a package into the current project").argument("<package>", "Package name (e.g., nextjs-tailwind-starter)").option("-v, --version <version>", "Install specific version").option("--rule", "Force install as a rule to .claude/rules/").option("--no-input", "Fail if any required variable is missing").option("--set <key=value...>", "Set template variables (e.g., --set project_name=myapp)").action(
|
|
756
768
|
async (packageName, options) => {
|
|
757
769
|
try {
|
|
758
770
|
logger.blank();
|
|
771
|
+
const variables = options.set ? parseVariables(options.set) : void 0;
|
|
759
772
|
await installPackage(packageName, {
|
|
760
773
|
version: options.version,
|
|
761
774
|
forceRule: options.rule,
|
|
762
|
-
noInput: options.input === false
|
|
775
|
+
noInput: options.input === false,
|
|
776
|
+
variables
|
|
763
777
|
});
|
|
764
778
|
logger.blank();
|
|
765
779
|
} catch (err) {
|
|
@@ -925,7 +939,7 @@ var publishCommand = new Command5("publish").description("Publish the current di
|
|
|
925
939
|
"User-Agent": "planmode-cli",
|
|
926
940
|
"Content-Type": "application/json"
|
|
927
941
|
};
|
|
928
|
-
await fetch("https://api.github.com/repos/planmode/
|
|
942
|
+
await fetch("https://api.github.com/repos/kaihannonen/planmode.org/forks", {
|
|
929
943
|
method: "POST",
|
|
930
944
|
headers
|
|
931
945
|
});
|
|
@@ -970,7 +984,7 @@ var publishCommand = new Command5("publish").description("Publish the current di
|
|
|
970
984
|
);
|
|
971
985
|
const branchName = `add-${manifest.name}-${manifest.version}`;
|
|
972
986
|
const refRes = await fetch(
|
|
973
|
-
`https://api.github.com/repos/${user.login}/
|
|
987
|
+
`https://api.github.com/repos/${user.login}/planmode.org/git/ref/heads/main`,
|
|
974
988
|
{ headers }
|
|
975
989
|
);
|
|
976
990
|
if (!refRes.ok) {
|
|
@@ -979,7 +993,7 @@ var publishCommand = new Command5("publish").description("Publish the current di
|
|
|
979
993
|
}
|
|
980
994
|
const refData = await refRes.json();
|
|
981
995
|
const baseSha = refData.object.sha;
|
|
982
|
-
await fetch(`https://api.github.com/repos/${user.login}/
|
|
996
|
+
await fetch(`https://api.github.com/repos/${user.login}/planmode.org/git/refs`, {
|
|
983
997
|
method: "POST",
|
|
984
998
|
headers,
|
|
985
999
|
body: JSON.stringify({
|
|
@@ -988,7 +1002,7 @@ var publishCommand = new Command5("publish").description("Publish the current di
|
|
|
988
1002
|
})
|
|
989
1003
|
});
|
|
990
1004
|
await fetch(
|
|
991
|
-
`https://api.github.com/repos/${user.login}/
|
|
1005
|
+
`https://api.github.com/repos/${user.login}/planmode.org/contents/registry/packages/${manifest.name}/metadata.json`,
|
|
992
1006
|
{
|
|
993
1007
|
method: "PUT",
|
|
994
1008
|
headers,
|
|
@@ -1000,7 +1014,7 @@ var publishCommand = new Command5("publish").description("Publish the current di
|
|
|
1000
1014
|
}
|
|
1001
1015
|
);
|
|
1002
1016
|
await fetch(
|
|
1003
|
-
`https://api.github.com/repos/${user.login}/
|
|
1017
|
+
`https://api.github.com/repos/${user.login}/planmode.org/contents/registry/packages/${manifest.name}/versions/${manifest.version}.json`,
|
|
1004
1018
|
{
|
|
1005
1019
|
method: "PUT",
|
|
1006
1020
|
headers,
|
|
@@ -1011,7 +1025,7 @@ var publishCommand = new Command5("publish").description("Publish the current di
|
|
|
1011
1025
|
})
|
|
1012
1026
|
}
|
|
1013
1027
|
);
|
|
1014
|
-
const prRes = await fetch("https://api.github.com/repos/planmode/
|
|
1028
|
+
const prRes = await fetch("https://api.github.com/repos/kaihannonen/planmode.org/pulls", {
|
|
1015
1029
|
method: "POST",
|
|
1016
1030
|
headers,
|
|
1017
1031
|
body: JSON.stringify({
|
|
@@ -1280,7 +1294,7 @@ var loginCommand = new Command10("login").description("Configure GitHub authenti
|
|
|
1280
1294
|
|
|
1281
1295
|
// src/index.ts
|
|
1282
1296
|
var program = new Command11();
|
|
1283
|
-
program.name("planmode").description("The open source package manager for AI plans, rules, and prompts.").version("0.1.
|
|
1297
|
+
program.name("planmode").description("The open source package manager for AI plans, rules, and prompts.").version("0.1.3");
|
|
1284
1298
|
program.addCommand(installCommand);
|
|
1285
1299
|
program.addCommand(uninstallCommand);
|
|
1286
1300
|
program.addCommand(searchCommand);
|
package/package.json
CHANGED
package/src/commands/install.ts
CHANGED
|
@@ -2,23 +2,38 @@ import { Command } from "commander";
|
|
|
2
2
|
import { installPackage } from "../lib/installer.js";
|
|
3
3
|
import { logger } from "../lib/logger.js";
|
|
4
4
|
|
|
5
|
+
function parseVariables(pairs: string[]): Record<string, string> {
|
|
6
|
+
const vars: Record<string, string> = {};
|
|
7
|
+
for (const pair of pairs) {
|
|
8
|
+
const eq = pair.indexOf("=");
|
|
9
|
+
if (eq === -1) {
|
|
10
|
+
throw new Error(`Invalid variable format: "${pair}". Use --set key=value`);
|
|
11
|
+
}
|
|
12
|
+
vars[pair.slice(0, eq)] = pair.slice(eq + 1);
|
|
13
|
+
}
|
|
14
|
+
return vars;
|
|
15
|
+
}
|
|
16
|
+
|
|
5
17
|
export const installCommand = new Command("install")
|
|
6
18
|
.description("Install a package into the current project")
|
|
7
19
|
.argument("<package>", "Package name (e.g., nextjs-tailwind-starter)")
|
|
8
20
|
.option("-v, --version <version>", "Install specific version")
|
|
9
21
|
.option("--rule", "Force install as a rule to .claude/rules/")
|
|
10
22
|
.option("--no-input", "Fail if any required variable is missing")
|
|
23
|
+
.option("--set <key=value...>", "Set template variables (e.g., --set project_name=myapp)")
|
|
11
24
|
.action(
|
|
12
25
|
async (
|
|
13
26
|
packageName: string,
|
|
14
|
-
options: { version?: string; rule?: boolean; input?: boolean },
|
|
27
|
+
options: { version?: string; rule?: boolean; input?: boolean; set?: string[] },
|
|
15
28
|
) => {
|
|
16
29
|
try {
|
|
17
30
|
logger.blank();
|
|
31
|
+
const variables = options.set ? parseVariables(options.set) : undefined;
|
|
18
32
|
await installPackage(packageName, {
|
|
19
33
|
version: options.version,
|
|
20
34
|
forceRule: options.rule,
|
|
21
35
|
noInput: options.input === false,
|
|
36
|
+
variables,
|
|
22
37
|
});
|
|
23
38
|
logger.blank();
|
|
24
39
|
} catch (err) {
|
package/src/commands/publish.ts
CHANGED
|
@@ -65,7 +65,7 @@ export const publishCommand = new Command("publish")
|
|
|
65
65
|
};
|
|
66
66
|
|
|
67
67
|
// Fork the registry repo (idempotent)
|
|
68
|
-
await fetch("https://api.github.com/repos/planmode/
|
|
68
|
+
await fetch("https://api.github.com/repos/kaihannonen/planmode.org/forks", {
|
|
69
69
|
method: "POST",
|
|
70
70
|
headers,
|
|
71
71
|
});
|
|
@@ -123,7 +123,7 @@ export const publishCommand = new Command("publish")
|
|
|
123
123
|
|
|
124
124
|
// Get main branch ref
|
|
125
125
|
const refRes = await fetch(
|
|
126
|
-
`https://api.github.com/repos/${user.login}/
|
|
126
|
+
`https://api.github.com/repos/${user.login}/planmode.org/git/ref/heads/main`,
|
|
127
127
|
{ headers },
|
|
128
128
|
);
|
|
129
129
|
|
|
@@ -136,7 +136,7 @@ export const publishCommand = new Command("publish")
|
|
|
136
136
|
const baseSha = refData.object.sha;
|
|
137
137
|
|
|
138
138
|
// Create branch
|
|
139
|
-
await fetch(`https://api.github.com/repos/${user.login}/
|
|
139
|
+
await fetch(`https://api.github.com/repos/${user.login}/planmode.org/git/refs`, {
|
|
140
140
|
method: "POST",
|
|
141
141
|
headers,
|
|
142
142
|
body: JSON.stringify({
|
|
@@ -147,7 +147,7 @@ export const publishCommand = new Command("publish")
|
|
|
147
147
|
|
|
148
148
|
// Create metadata.json
|
|
149
149
|
await fetch(
|
|
150
|
-
`https://api.github.com/repos/${user.login}/
|
|
150
|
+
`https://api.github.com/repos/${user.login}/planmode.org/contents/registry/packages/${manifest.name}/metadata.json`,
|
|
151
151
|
{
|
|
152
152
|
method: "PUT",
|
|
153
153
|
headers,
|
|
@@ -161,7 +161,7 @@ export const publishCommand = new Command("publish")
|
|
|
161
161
|
|
|
162
162
|
// Create version file
|
|
163
163
|
await fetch(
|
|
164
|
-
`https://api.github.com/repos/${user.login}/
|
|
164
|
+
`https://api.github.com/repos/${user.login}/planmode.org/contents/registry/packages/${manifest.name}/versions/${manifest.version}.json`,
|
|
165
165
|
{
|
|
166
166
|
method: "PUT",
|
|
167
167
|
headers,
|
|
@@ -174,7 +174,7 @@ export const publishCommand = new Command("publish")
|
|
|
174
174
|
);
|
|
175
175
|
|
|
176
176
|
// Create PR
|
|
177
|
-
const prRes = await fetch("https://api.github.com/repos/planmode/
|
|
177
|
+
const prRes = await fetch("https://api.github.com/repos/kaihannonen/planmode.org/pulls", {
|
|
178
178
|
method: "POST",
|
|
179
179
|
headers,
|
|
180
180
|
body: JSON.stringify({
|
package/src/index.ts
CHANGED
|
@@ -15,7 +15,7 @@ const program = new Command();
|
|
|
15
15
|
program
|
|
16
16
|
.name("planmode")
|
|
17
17
|
.description("The open source package manager for AI plans, rules, and prompts.")
|
|
18
|
-
.version("0.1.
|
|
18
|
+
.version("0.1.3");
|
|
19
19
|
|
|
20
20
|
program.addCommand(installCommand);
|
|
21
21
|
program.addCommand(uninstallCommand);
|
package/src/lib/installer.ts
CHANGED
|
@@ -60,10 +60,11 @@ export async function installPackage(
|
|
|
60
60
|
|
|
61
61
|
// Fetch manifest
|
|
62
62
|
logger.info(`Fetching ${packageName}@${version}...`);
|
|
63
|
+
const basePath = versionMeta.source.path ? `${versionMeta.source.path}/` : "";
|
|
63
64
|
const manifestRaw = await fetchFileAtTag(
|
|
64
65
|
versionMeta.source.repository,
|
|
65
66
|
versionMeta.source.tag,
|
|
66
|
-
|
|
67
|
+
`${basePath}planmode.yaml`,
|
|
67
68
|
);
|
|
68
69
|
const manifest = parseManifest(manifestRaw);
|
|
69
70
|
|
|
@@ -75,7 +76,7 @@ export async function installPackage(
|
|
|
75
76
|
content = await fetchFileAtTag(
|
|
76
77
|
versionMeta.source.repository,
|
|
77
78
|
versionMeta.source.tag,
|
|
78
|
-
manifest.content_file
|
|
79
|
+
`${basePath}${manifest.content_file}`,
|
|
79
80
|
);
|
|
80
81
|
} else {
|
|
81
82
|
throw new Error("Package has no content or content_file");
|