agentful 0.1.0 → 0.1.2
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 +43 -17
- package/dist/index.cjs +115 -30
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,28 +1,44 @@
|
|
|
1
1
|
# Agentful CLI
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Develop locally, ship with one command. `agentful` gives you an AI coding
|
|
4
|
+
interface in your terminal and moves the project into your Agentful workspace
|
|
5
|
+
with a live preview URL — using the same models and credits as the web app.
|
|
5
6
|
|
|
7
|
+
```bash
|
|
8
|
+
npm i -g agentful
|
|
6
9
|
```
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
agentful login # once: confirm the code in your browser
|
|
15
|
+
agentful init # create or link the cloud project
|
|
16
|
+
agentful # start the coding interface
|
|
17
|
+
agentful push # upload, cloud build, preview URL
|
|
18
|
+
agentful open # open the preview
|
|
13
19
|
```
|
|
14
20
|
|
|
15
|
-
## Commands
|
|
21
|
+
## Commands
|
|
16
22
|
|
|
17
23
|
| Command | Purpose |
|
|
18
|
-
|
|
19
|
-
| `login` / `logout` / `whoami` |
|
|
20
|
-
| `init [--link <
|
|
21
|
-
| `push [--prebuilt [--dir <path>]]` |
|
|
22
|
-
| `open` | Open the preview
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| `login` / `logout` / `whoami` | Browser-based sign-in; the token is kept in the macOS Keychain |
|
|
26
|
+
| `init [--link <id>] [--title <t>]` | Create a cloud project or link an existing one (`.agentful/project.json`) |
|
|
27
|
+
| `push [--prebuilt [--dir <path>]]` | Upload the source and build in the cloud; `--prebuilt` uploads a local build |
|
|
28
|
+
| `open` | Open the live preview |
|
|
29
|
+
| `share [--private]` | Make the preview public, or private again |
|
|
30
|
+
| `publish <subdomain>` | Publish at `https://<subdomain>.agentful.dev` |
|
|
31
|
+
| `pull [--force]` | Fetch the cloud state into this directory |
|
|
32
|
+
| `models [--add-local]` | Show available models, manage your own providers |
|
|
33
|
+
| `upgrade` | Update the CLI to the latest published version |
|
|
34
|
+
| `licenses` | Licences of the software shipped with this CLI |
|
|
35
|
+
| `-s, --session <id>` | Resume a previous coding session |
|
|
36
|
+
|
|
37
|
+
Inside the interface, `/` lists the Agentful commands (`/setup`, `/push`,
|
|
38
|
+
`/preview`, `/publish`, `/share`, `/status`) alongside the built-in ones.
|
|
39
|
+
|
|
40
|
+
`push` respects your `.gitignore` and always excludes `.git`, `node_modules`,
|
|
41
|
+
build output and every `.env` file. Uploads are capped at 6 MB.
|
|
26
42
|
|
|
27
43
|
## Platform support
|
|
28
44
|
|
|
@@ -67,6 +83,16 @@ Local providers are governed by the organization's BYOK policy (`/api/org/me`):
|
|
|
67
83
|
the CLI, so it is a cooperative control, not a cryptographic one — the config
|
|
68
84
|
lives on the user's machine.
|
|
69
85
|
|
|
86
|
+
## Known limitation: the engine's exit banner
|
|
87
|
+
|
|
88
|
+
When the TUI closes, the engine writes its own splash (its logo plus a
|
|
89
|
+
`opencode -s <id>` hint) straight into the scrollback. v1.18.x offers no flag,
|
|
90
|
+
env var or config to suppress it, and patching the binary would break its
|
|
91
|
+
macOS signature. We therefore let it stand and print our own last line with
|
|
92
|
+
the command that actually works here — `agentful -s <id>`; the engine's hint
|
|
93
|
+
cannot work, because that binary is not on the user's PATH and its data lives
|
|
94
|
+
in a different directory.
|
|
95
|
+
|
|
70
96
|
## Branding
|
|
71
97
|
|
|
72
98
|
Everything user-visible lives in `src/branding/`: `branding.ts` (palette,
|
package/dist/index.cjs
CHANGED
|
@@ -3432,7 +3432,7 @@ var {
|
|
|
3432
3432
|
} = import_index.default;
|
|
3433
3433
|
|
|
3434
3434
|
// src/branding.ts
|
|
3435
|
-
var VERSION = "0.1.
|
|
3435
|
+
var VERSION = "0.1.2" ? "0.1.2" : null.version;
|
|
3436
3436
|
var brand = {
|
|
3437
3437
|
name: "agentful",
|
|
3438
3438
|
// the command users type
|
|
@@ -3792,7 +3792,11 @@ function writeProjectConfig(config, cwd = process.cwd()) {
|
|
|
3792
3792
|
function requireProject(cwd = process.cwd()) {
|
|
3793
3793
|
const config = readProjectConfig(cwd);
|
|
3794
3794
|
if (!config) {
|
|
3795
|
-
throw new ApiError(
|
|
3795
|
+
throw new ApiError(
|
|
3796
|
+
0,
|
|
3797
|
+
"not_initialized",
|
|
3798
|
+
"No Agentful project here. Run `agentful init` to create or link one (inside the TUI: /setup)."
|
|
3799
|
+
);
|
|
3796
3800
|
}
|
|
3797
3801
|
return config;
|
|
3798
3802
|
}
|
|
@@ -4763,8 +4767,8 @@ async function openCommand() {
|
|
|
4763
4767
|
}
|
|
4764
4768
|
|
|
4765
4769
|
// src/commands/tui.ts
|
|
4766
|
-
var
|
|
4767
|
-
var
|
|
4770
|
+
var import_node_child_process5 = require("child_process");
|
|
4771
|
+
var import_node_path12 = require("path");
|
|
4768
4772
|
|
|
4769
4773
|
// src/lib/binWrapper.ts
|
|
4770
4774
|
var import_node_fs4 = require("fs");
|
|
@@ -5088,32 +5092,38 @@ export default plugin
|
|
|
5088
5092
|
}
|
|
5089
5093
|
|
|
5090
5094
|
// src/branding/commands.ts
|
|
5095
|
+
var IF_NOT_LINKED = 'If the command reports "No Agentful project here", this directory is not linked yet: ask me for a project title, run `agentful init --title "<title>"`, then run the original command again and report its result.';
|
|
5091
5096
|
var SLASH_COMMANDS = {
|
|
5097
|
+
setup: {
|
|
5098
|
+
description: `${brand.displayName}: create or link the cloud project for this directory`,
|
|
5099
|
+
template: 'Check whether .agentful/project.json exists. If it does, report the linked project title and id and stop. Otherwise ask me for a project title, then run `agentful init --title "<title>"` using the bash tool and report what it created. Do not modify any other project files.'
|
|
5100
|
+
},
|
|
5092
5101
|
push: {
|
|
5093
|
-
description:
|
|
5094
|
-
template: "Run `agentful push` from the project root using the bash tool. Stream what it prints, and when it finishes report the preview URL on its own line. If it fails, show the error and suggest the fix \u2014 do not modify project files unless I ask."
|
|
5102
|
+
description: `${brand.displayName}: deploy this project and get a preview URL`,
|
|
5103
|
+
template: "Run `agentful push` from the project root using the bash tool. Stream what it prints, and when it finishes report the preview URL on its own line. " + IF_NOT_LINKED + " If it fails for another reason, show the error and suggest the fix \u2014 do not modify project files unless I ask."
|
|
5095
5104
|
},
|
|
5096
5105
|
preview: {
|
|
5097
|
-
description:
|
|
5098
|
-
template: "Run `agentful open` from the project root using the bash tool and report the URL it opened."
|
|
5106
|
+
description: `${brand.displayName}: open the live preview in the browser`,
|
|
5107
|
+
template: "Run `agentful open` from the project root using the bash tool and report the URL it opened. Note that `open` neither builds nor uploads \u2014 if I have not pushed yet, say so and offer to run `agentful push` first. " + IF_NOT_LINKED
|
|
5099
5108
|
},
|
|
5100
5109
|
publish: {
|
|
5101
|
-
description:
|
|
5102
|
-
template: "Ask me for the subdomain if I did not provide one in $ARGUMENTS, then run `agentful publish <subdomain>` from the project root using the bash tool and report the public URL."
|
|
5110
|
+
description: `${brand.displayName}: publish on a public subdomain`,
|
|
5111
|
+
template: "Ask me for the subdomain if I did not provide one in $ARGUMENTS, then run `agentful publish <subdomain>` from the project root using the bash tool and report the public URL. " + IF_NOT_LINKED
|
|
5103
5112
|
},
|
|
5104
5113
|
share: {
|
|
5105
|
-
description:
|
|
5106
|
-
template: "Run `agentful share` from the project root using the bash tool (add `--private` if $ARGUMENTS says private) and report the resulting visibility and URL."
|
|
5114
|
+
description: `${brand.displayName}: make the live preview public (or private again)`,
|
|
5115
|
+
template: "Run `agentful share` from the project root using the bash tool (add `--private` if $ARGUMENTS says private) and report the resulting visibility and URL. " + IF_NOT_LINKED
|
|
5107
5116
|
},
|
|
5108
5117
|
status: {
|
|
5109
|
-
description:
|
|
5110
|
-
template: "Run `agentful whoami`
|
|
5118
|
+
description: `${brand.displayName}: show the linked project and account`,
|
|
5119
|
+
template: "Run `agentful whoami` using the bash tool. Then read .agentful/project.json and report the linked project title and id, plus the preview URL https://preview-<projectId>.agentful.dev/. If the file does not exist, say that this directory is not linked yet and that `/setup` creates the link."
|
|
5111
5120
|
}
|
|
5112
5121
|
};
|
|
5113
5122
|
function commandMarkdown(name) {
|
|
5114
5123
|
const cmd = SLASH_COMMANDS[name];
|
|
5124
|
+
const description = JSON.stringify(cmd.description);
|
|
5115
5125
|
return `---
|
|
5116
|
-
description: ${
|
|
5126
|
+
description: ${description}
|
|
5117
5127
|
agent: build
|
|
5118
5128
|
---
|
|
5119
5129
|
|
|
@@ -5390,8 +5400,33 @@ function writeLocalProvidersExample() {
|
|
|
5390
5400
|
return path;
|
|
5391
5401
|
}
|
|
5392
5402
|
|
|
5403
|
+
// src/lib/sessions.ts
|
|
5404
|
+
var import_node_fs10 = require("fs");
|
|
5405
|
+
var import_node_path11 = require("path");
|
|
5406
|
+
var import_node_child_process4 = require("child_process");
|
|
5407
|
+
var SEP = "";
|
|
5408
|
+
function sqlite(dbPath, sql) {
|
|
5409
|
+
const res = (0, import_node_child_process4.spawnSync)("sqlite3", ["-readonly", dbPath, sql], { encoding: "utf8" });
|
|
5410
|
+
if (res.status !== 0 || !res.stdout) return null;
|
|
5411
|
+
return res.stdout.trim().split("\n").filter(Boolean);
|
|
5412
|
+
}
|
|
5413
|
+
function lastSessionForDirectory(cwd = process.cwd()) {
|
|
5414
|
+
const dbPath = (0, import_node_path11.join)(engineXdg().dataHome, "opencode", "opencode.db");
|
|
5415
|
+
if (!(0, import_node_fs10.existsSync)(dbPath)) return null;
|
|
5416
|
+
const escaped = cwd.replace(/'/g, "''");
|
|
5417
|
+
const rows = sqlite(
|
|
5418
|
+
dbPath,
|
|
5419
|
+
`SELECT id || char(31) || COALESCE(title, slug, '') FROM session
|
|
5420
|
+
WHERE directory = '${escaped}' AND time_archived IS NULL
|
|
5421
|
+
ORDER BY COALESCE(time_updated, time_created) DESC LIMIT 1;`
|
|
5422
|
+
);
|
|
5423
|
+
if (!rows?.length) return null;
|
|
5424
|
+
const [id, title] = rows[0].split(SEP);
|
|
5425
|
+
return id ? { id, title: title || "" } : null;
|
|
5426
|
+
}
|
|
5427
|
+
|
|
5393
5428
|
// src/commands/tui.ts
|
|
5394
|
-
async function tuiCommand() {
|
|
5429
|
+
async function tuiCommand(opts = {}) {
|
|
5395
5430
|
console.log(banner());
|
|
5396
5431
|
const auth = await ensureAuth();
|
|
5397
5432
|
const project = readProjectConfig();
|
|
@@ -5434,14 +5469,15 @@ async function tuiCommand() {
|
|
|
5434
5469
|
console.log("");
|
|
5435
5470
|
if (process.stdout.isTTY) process.stdout.write(`\x1B]0;${brand.displayName}\x07`);
|
|
5436
5471
|
const code = await new Promise((resolve) => {
|
|
5437
|
-
const
|
|
5472
|
+
const engineArgs = opts.session ? ["--session", opts.session] : [];
|
|
5473
|
+
const child = (0, import_node_child_process5.spawn)(binPath, engineArgs, {
|
|
5438
5474
|
stdio: "inherit",
|
|
5439
5475
|
cwd: process.cwd(),
|
|
5440
5476
|
env: {
|
|
5441
5477
|
...process.env,
|
|
5442
5478
|
// Slash commands run `agentful …` through the agent's bash tool, which
|
|
5443
5479
|
// has no access to the user's shell aliases.
|
|
5444
|
-
PATH: `${binDir}${
|
|
5480
|
+
PATH: `${binDir}${import_node_path12.delimiter}${process.env.PATH || ""}`,
|
|
5445
5481
|
XDG_CONFIG_HOME: xdg.configHome,
|
|
5446
5482
|
XDG_DATA_HOME: xdg.dataHome,
|
|
5447
5483
|
XDG_STATE_HOME: xdg.stateHome,
|
|
@@ -5476,6 +5512,14 @@ async function tuiCommand() {
|
|
|
5476
5512
|
}
|
|
5477
5513
|
} catch {
|
|
5478
5514
|
}
|
|
5515
|
+
try {
|
|
5516
|
+
const last = lastSessionForDirectory();
|
|
5517
|
+
if (last) {
|
|
5518
|
+
const label = last.title ? ` ${paint.dim(`(${last.title})`)}` : "";
|
|
5519
|
+
ui.info(`Resume: ${paint.accent(`agentful -s ${last.id}`)}${label}`);
|
|
5520
|
+
}
|
|
5521
|
+
} catch {
|
|
5522
|
+
}
|
|
5479
5523
|
process.exitCode = code;
|
|
5480
5524
|
}
|
|
5481
5525
|
|
|
@@ -5536,26 +5580,26 @@ async function shareCommand(opts) {
|
|
|
5536
5580
|
}
|
|
5537
5581
|
|
|
5538
5582
|
// src/commands/pull.ts
|
|
5539
|
-
var
|
|
5540
|
-
var
|
|
5583
|
+
var import_node_fs11 = require("fs");
|
|
5584
|
+
var import_node_path13 = require("path");
|
|
5541
5585
|
function isProbablyBase64Binary(path) {
|
|
5542
5586
|
return /\.(png|jpe?g|gif|webp|ico|woff2?|ttf|otf|eot|pdf|zip|mp[34]|webm|avif)$/i.test(path);
|
|
5543
5587
|
}
|
|
5544
5588
|
function writeEntry(root, rel, value) {
|
|
5545
|
-
const target = (0,
|
|
5546
|
-
(0,
|
|
5589
|
+
const target = (0, import_node_path13.join)(root, rel);
|
|
5590
|
+
(0, import_node_fs11.mkdirSync)((0, import_node_path13.dirname)(target), { recursive: true });
|
|
5547
5591
|
const content = typeof value === "object" && value !== null && "content" in value ? String(value.content) : String(value ?? "");
|
|
5548
5592
|
if (isProbablyBase64Binary(rel)) {
|
|
5549
|
-
(0,
|
|
5593
|
+
(0, import_node_fs11.writeFileSync)(target, Buffer.from(content, "base64"));
|
|
5550
5594
|
} else {
|
|
5551
|
-
(0,
|
|
5595
|
+
(0, import_node_fs11.writeFileSync)(target, content, "utf8");
|
|
5552
5596
|
}
|
|
5553
5597
|
}
|
|
5554
5598
|
async function pullCommand(opts) {
|
|
5555
5599
|
console.log(banner());
|
|
5556
5600
|
const auth = await ensureAuth();
|
|
5557
5601
|
const project = requireProject();
|
|
5558
|
-
const nonHidden = (0,
|
|
5602
|
+
const nonHidden = (0, import_node_fs11.readdirSync)(process.cwd()).filter((n) => n !== ".agentful" && !n.startsWith("."));
|
|
5559
5603
|
if (nonHidden.length > 0 && !opts.force) {
|
|
5560
5604
|
throw new ApiError(
|
|
5561
5605
|
0,
|
|
@@ -5579,9 +5623,9 @@ async function pullCommand(opts) {
|
|
|
5579
5623
|
ui.warn(`Skipped ${rel} (HTTP ${resp.status})`);
|
|
5580
5624
|
continue;
|
|
5581
5625
|
}
|
|
5582
|
-
const target = (0,
|
|
5583
|
-
(0,
|
|
5584
|
-
(0,
|
|
5626
|
+
const target = (0, import_node_path13.join)(process.cwd(), rel);
|
|
5627
|
+
(0, import_node_fs11.mkdirSync)((0, import_node_path13.dirname)(target), { recursive: true });
|
|
5628
|
+
(0, import_node_fs11.writeFileSync)(target, Buffer.from(await resp.arrayBuffer()));
|
|
5585
5629
|
written++;
|
|
5586
5630
|
}
|
|
5587
5631
|
} else if (data.files) {
|
|
@@ -5663,6 +5707,36 @@ async function modelsCommand(opts) {
|
|
|
5663
5707
|
}
|
|
5664
5708
|
}
|
|
5665
5709
|
|
|
5710
|
+
// src/commands/upgrade.ts
|
|
5711
|
+
var import_node_child_process6 = require("child_process");
|
|
5712
|
+
async function upgradeCommand() {
|
|
5713
|
+
console.log(banner());
|
|
5714
|
+
let latest = "";
|
|
5715
|
+
try {
|
|
5716
|
+
const manifest = await request(
|
|
5717
|
+
`${APP_URL}/cli/engine-manifest.json`,
|
|
5718
|
+
{ timeoutMs: 8e3 }
|
|
5719
|
+
);
|
|
5720
|
+
latest = manifest.latest_cli_version || "";
|
|
5721
|
+
} catch {
|
|
5722
|
+
}
|
|
5723
|
+
if (latest && compareVersions(VERSION, latest) >= 0) {
|
|
5724
|
+
ui.ok(`Already on the latest version (v${VERSION}).`);
|
|
5725
|
+
return;
|
|
5726
|
+
}
|
|
5727
|
+
if (latest) ui.step(`Updating ${brand.name} v${VERSION} \u2192 v${latest}\u2026`);
|
|
5728
|
+
else ui.step(`Updating ${brand.name} to the latest version\u2026`);
|
|
5729
|
+
const res = (0, import_node_child_process6.spawnSync)("npm", ["install", "-g", `${brand.name}@latest`], { stdio: "inherit" });
|
|
5730
|
+
if (res.status === 0) {
|
|
5731
|
+
ui.ok("Done. Run `agentful --version` to confirm.");
|
|
5732
|
+
return;
|
|
5733
|
+
}
|
|
5734
|
+
ui.fail("The automatic update did not succeed.");
|
|
5735
|
+
ui.info(`Run it yourself: ${paint.accent(`npm install -g ${brand.name}@latest`)}`);
|
|
5736
|
+
ui.info("If that reports a permission error, your Node installation needs sudo or a prefix change.");
|
|
5737
|
+
process.exitCode = 1;
|
|
5738
|
+
}
|
|
5739
|
+
|
|
5666
5740
|
// src/index.ts
|
|
5667
5741
|
var program2 = new Command();
|
|
5668
5742
|
var run = (fn) => async (...args) => {
|
|
@@ -5677,17 +5751,28 @@ var run = (fn) => async (...args) => {
|
|
|
5677
5751
|
process.exitCode = 1;
|
|
5678
5752
|
}
|
|
5679
5753
|
};
|
|
5680
|
-
program2.name("agentful").description("Agentful in your terminal \u2014 local development with push-to-cloud previews").version(VERSION)
|
|
5754
|
+
program2.name("agentful").description("Agentful in your terminal \u2014 local development with push-to-cloud previews").version(VERSION).option("-s, --session <id>", "resume a previous session (same as `tui -s`)").action(run((opts, cmd) => {
|
|
5755
|
+
const [unknown] = cmd.args;
|
|
5756
|
+
if (unknown) {
|
|
5757
|
+
throw new ApiError(
|
|
5758
|
+
0,
|
|
5759
|
+
"unknown_command",
|
|
5760
|
+
`Unknown command '${unknown}'. Run \`agentful --help\` to see what is available.`
|
|
5761
|
+
);
|
|
5762
|
+
}
|
|
5763
|
+
return tuiCommand(opts);
|
|
5764
|
+
})).showSuggestionAfterError();
|
|
5681
5765
|
program2.command("login").description("Sign in to your Agentful account (device flow)").option("--no-browser", "do not open the browser automatically").action(run((opts) => loginCommand({ browser: opts.browser !== false })));
|
|
5682
5766
|
program2.command("logout").description("Remove the stored credentials").action(run(logoutCommand));
|
|
5683
5767
|
program2.command("whoami").description("Show the signed-in account").action(run(whoamiCommand));
|
|
5684
5768
|
program2.command("init").description("Create (or link) the Agentful cloud project for this directory").option("--link <projectId>", "link an existing project instead of creating one").option("--title <title>", "project title (skips the prompt)").action(run((opts) => initCommand(opts)));
|
|
5685
5769
|
program2.command("push").description("Upload this project and get a live preview URL").option("--prebuilt", "upload a locally built output instead of building in the cloud").option("--dir <path>", "built-output directory for --prebuilt (default: auto-detect)").action(run((opts) => pushCommand(opts)));
|
|
5686
5770
|
program2.command("open").description("Open the live preview in the browser").action(run(openCommand));
|
|
5687
|
-
program2.command("tui"
|
|
5771
|
+
program2.command("tui").description("Start the Agentful coding TUI with your Agentful account").option("-s, --session <id>", "resume a previous session").action(run((opts) => tuiCommand(opts)));
|
|
5688
5772
|
program2.command("publish <subdomain>").description("Publish the built project at https://<subdomain>.agentful.dev").action(run(publishCommand));
|
|
5689
5773
|
program2.command("share").description("Make the live preview public (anyone with the link)").option("--private", "make the preview owner-only again").action(run((opts) => shareCommand(opts)));
|
|
5690
5774
|
program2.command("pull").description("Download the cloud workspace into this directory").option("--force", "overwrite files in a non-empty directory").action(run((opts) => pullCommand(opts)));
|
|
5691
5775
|
program2.command("models").description("List available models and manage local providers with your own key").option("--add-local", "create/show the local provider file to edit").action(run((opts) => modelsCommand(opts)));
|
|
5776
|
+
program2.command("upgrade").description("Update the CLI to the latest version").action(run(upgradeCommand));
|
|
5692
5777
|
program2.command("licenses").description("Show licenses of the software distributed with this CLI").action(run(licensesCommand));
|
|
5693
5778
|
program2.parseAsync(process.argv);
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentful",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Agentful in your terminal \u2014 local development with push-to-cloud previews",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://agentful.dev",
|
|
7
7
|
"bin": {
|
|
8
|
-
"agentful": "
|
|
8
|
+
"agentful": "dist/index.cjs"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"repository": {
|
|
38
38
|
"type": "git",
|
|
39
|
-
"url": "https://github.com/limoncello/mainmvp.git",
|
|
39
|
+
"url": "git+https://github.com/limoncello/mainmvp.git",
|
|
40
40
|
"directory": "cli"
|
|
41
41
|
},
|
|
42
42
|
"keywords": [
|