@backifydev/cli 0.3.3 → 0.3.4
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 +1 -1
- package/dist/index.js +29 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ See the [agent setup guide](https://agent.backify.dev/).
|
|
|
25
25
|
|
|
26
26
|
Copy the application AI prompt in Backify to receive the application ID, organization ID, and an application-scoped, single-use pairing code; the agent guide supplies the connection and initialization commands. Codes expire after 15 minutes; redeemed sessions expire after seven days. Add `--clone` even when the current folder contains AI coding-tool scaffolding. Empty directories of any name are allowed. Hidden tool-metadata directories and files, Markdown instruction files, and default `work/` and `outputs/` directories may contain tool settings or artifacts. The CLI clones into a temporary directory, validates collisions, then merges without deleting or overwriting existing tool files. Existing Git metadata, root application source, and symlinked tool directories are rejected; file conflicts stop before repository files are installed. Credentials are stored in the user's home configuration, not the project. The default API is `https://api.backify.dev/api`; local development can override it with `BACKIFY_API_URL` or the connection command's `--api` option. HTTPS is required outside loopback.
|
|
27
27
|
|
|
28
|
-
`init` adds a persistent delivery guide linked from the existing agent instructions. Before each application-building request, the agent sends only the user's own text through stdin to `backify prompt record --stdin --id <UUID>`, optionally adding repeated `--filename <basename>` arguments. Reuse the UUID on retries. The command never reads attachments; their bodies, extracted text, full paths, setup/pairing prompts, and credentials must not be submitted. History is displayed oldest-first under the application. This is an explicit agent workflow, not an automatic interceptor for every coding tool.
|
|
28
|
+
`init` adds a persistent delivery guide linked from the existing agent instructions. Before each application-building request, the agent sends only the user's own text through stdin to `backify prompt record --stdin --id <UUID>`, optionally adding repeated `--filename <basename>` arguments. Reuse the UUID on retries. The command never reads attachments; their bodies, extracted text, full paths, setup/pairing prompts, and credentials must not be submitted. History is displayed oldest-first under the application. This is an explicit agent workflow, not an automatic interceptor for every coding tool. Record the model, AI coding tool, and effective access for each request with --model, --ai-tool, and --access-level whenever known. Access is a short description of the tool’s actual filesystem, network, and approval permissions at the time of the request, not its Backify role. Use only exposed session information; never guess unknown values or inspect credentials to discover them. Omit unknown fields; older or incomplete records display “Not recorded”. These values are self-reported metadata, not verified authorization. Reuse the same metadata on retries. Model and tool names are limited to 200 characters each; access descriptions to 500. Never include secrets, tokens, full paths, or configuration file contents.
|
|
29
29
|
|
|
30
30
|
`pull` checks the connected application, repository, branch, and repository root, then fetches GitHub using a short-lived scoped credential. It fast-forwards only a clean, non-diverged branch. Incoming updates blocked by local changes, untracked files, or diverged history return a blocked result and a nonzero exit code; nothing is stashed, reset, rebased, or force-pushed. Connecting an existing repository runs this update automatically, and the agent guide requires it before editing each new user request. It is not a background watcher.
|
|
31
31
|
|
package/dist/index.js
CHANGED
|
@@ -813,9 +813,9 @@ Connection and initialization may proceed without application requirements. Then
|
|
|
813
813
|
|
|
814
814
|
For EVERY user request to build or modify this application, including the initial requirements supplied alongside or after setup, record only the user's own requirement text before changing application code. Submit the text through standard input to:
|
|
815
815
|
|
|
816
|
-
npx @backifydev/cli@latest prompt record --stdin --id <new-UUID> [--filename <basename> ...]
|
|
816
|
+
npx @backifydev/cli@latest prompt record --stdin --id <new-UUID> [--filename <basename> ...] [--model <model>] [--ai-tool <tool>] [--access-level <access>]
|
|
817
817
|
|
|
818
|
-
Record requests separately and in order. Generate a new UUID per request and reuse that UUID on retries. Add one --filename argument per attachment, using only its basename. Never send attachment bodies, extracted text, images, full paths, assistant responses, tool output, secrets, connection commands, or this setup/pairing block. Filename arguments are metadata only; never read attachment bodies to submit them. If recording fails, retry or report the blocker; never silently claim a request was recorded.
|
|
818
|
+
Record requests separately and in order. Generate a new UUID per request and reuse that UUID on retries. Add one --filename argument per attachment, using only its basename. Never send attachment bodies, extracted text, images, full paths, assistant responses, tool output, secrets, connection commands, or this setup/pairing block. Filename arguments are metadata only; never read attachment bodies to submit them. If recording fails, retry or report the blocker; never silently claim a request was recorded. Record the model, AI coding tool, and effective access for each request with --model, --ai-tool, and --access-level whenever known. Access is a short description of the tool\u2019s actual filesystem, network, and approval permissions at the time of the request, not its Backify role. Use only exposed session information; never guess unknown values or inspect credentials to discover them. Omit unknown fields; older or incomplete records display \u201CNot recorded\u201D. These values are self-reported metadata, not verified authorization. Reuse the same metadata on retries. Model and tool names are limited to 200 characters each; access descriptions to 500. Never include secrets, tokens, full paths, or configuration file contents.
|
|
819
819
|
|
|
820
820
|
## Keep local source current
|
|
821
821
|
|
|
@@ -849,6 +849,16 @@ The CLI verifies the repository and branch, runs checks, pushes committed source
|
|
|
849
849
|
|
|
850
850
|
If testing or approval is required, return the preview URL and explain the remaining action. Otherwise return the verified production URL and actual check results only after healthy activation. Inspect failures with the status command, fix them, and retry without asking the user to perform routine deployment steps. Never invent a successful check or deployment.
|
|
851
851
|
|
|
852
|
+
## User-facing handoff
|
|
853
|
+
|
|
854
|
+
After setup or a delivery attempt, give the user concise instructions: explain what is ready, how to open and use the application, and any sign-in, testing, approval, or other next steps. Summarize actual checks and blockers without exposing credentials or asking the user to perform routine deployment work the coding tool can complete.
|
|
855
|
+
|
|
856
|
+
Include separate Preview URL and Production URL lines, using the actual URLs returned by CLI status or deployment results. Include both URLs when available. If either is unavailable, say not deployed or unavailable and explain why; never invent a URL or claim an unverified deployment is live. When production still serves an earlier release, label it as the existing production version and explain that the new changes are preview-only or awaiting approval.
|
|
857
|
+
|
|
858
|
+
If application requirements are missing after setup, finish the response with this exact question as its final line, without any text after it:
|
|
859
|
+
|
|
860
|
+
What should the application do, and what should it look like?
|
|
861
|
+
|
|
852
862
|
These instructions are an explicit agent workflow, not a universal chat interceptor. Request capture depends on the coding tool following this guide or an integration invoking the recording command.
|
|
853
863
|
`;
|
|
854
864
|
|
|
@@ -988,7 +998,7 @@ var BACKIFY_SCHEMA = { $schema: "https://json-schema.org/draft/2020-12/schema",
|
|
|
988
998
|
import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
989
999
|
import { dirname as dirname2, join, relative as relativePath } from "node:path";
|
|
990
1000
|
import { createHash } from "node:crypto";
|
|
991
|
-
var previousGeneratedWorkflowHashes = /* @__PURE__ */ new Set(["578dfb4c771c623fd04454e8a604efd701d5563d11e11191324862369bd24718", "6eb280ae7bdb14c390011686c41400f59c023304c3015d8440b7e80aaafa1c11", "545e03a1d5b996ade179e0e60ed5c86accdadc1982c1c25efd094e34f72f47ee"]);
|
|
1001
|
+
var previousGeneratedWorkflowHashes = /* @__PURE__ */ new Set(["33e962274e8493f7cbac2afbac05a4e96afeec49ee08cf2bf82f8add9081b28b", "578dfb4c771c623fd04454e8a604efd701d5563d11e11191324862369bd24718", "6eb280ae7bdb14c390011686c41400f59c023304c3015d8440b7e80aaafa1c11", "545e03a1d5b996ade179e0e60ed5c86accdadc1982c1c25efd094e34f72f47ee"]);
|
|
992
1002
|
function validateDeliveryInstructions(root) {
|
|
993
1003
|
for (const filename of ["BACKIFY.md", "BACKIFY-WORKFLOW.md"]) {
|
|
994
1004
|
const path = join(root, filename);
|
|
@@ -1139,6 +1149,19 @@ function doctor(root = process.cwd(), agent, instructionFile) {
|
|
|
1139
1149
|
}
|
|
1140
1150
|
|
|
1141
1151
|
// src/development.ts
|
|
1152
|
+
function promptMetadata(args2) {
|
|
1153
|
+
const fields = [["--model", "model", 200], ["--ai-tool", "aiTool", 200], ["--access-level", "accessLevel", 500]];
|
|
1154
|
+
const metadata = {};
|
|
1155
|
+
for (const [flag, field, maxLength] of fields) {
|
|
1156
|
+
const index = args2.indexOf(flag);
|
|
1157
|
+
if (index < 0) continue;
|
|
1158
|
+
const value = args2[index + 1]?.trim();
|
|
1159
|
+
if (!value || value.startsWith("--") || value.length > maxLength || /[\u0000-\u001f\u007f-\u009f]|bfcli_[0-9a-f]{64}|--pair\s+[0-9a-f]{64}/i.test(value))
|
|
1160
|
+
throw new Error(`Provide ${flag} with a nonempty value of at most ${maxLength} characters without control characters or credentials.`);
|
|
1161
|
+
metadata[field] = value;
|
|
1162
|
+
}
|
|
1163
|
+
return metadata;
|
|
1164
|
+
}
|
|
1142
1165
|
function applicationGuid(appId) {
|
|
1143
1166
|
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(appId)) return appId.toLowerCase();
|
|
1144
1167
|
const match = /^app_([0-9a-f]{32})$/i.exec(appId);
|
|
@@ -1565,12 +1588,13 @@ async function main() {
|
|
|
1565
1588
|
break;
|
|
1566
1589
|
}
|
|
1567
1590
|
case "prompt": {
|
|
1568
|
-
if (args[0] !== "record" || !args.includes("--stdin")) throw new Error("Use backify prompt record --stdin --id <UUID> [--filename <name> ...]. Only user text and
|
|
1591
|
+
if (args[0] !== "record" || !args.includes("--stdin")) throw new Error("Use backify prompt record --stdin --id <UUID> [--filename <name> ...] [--model <model>] [--ai-tool <tool>] [--access-level <access>]. Only user text, filenames, and AI context metadata are sent.");
|
|
1569
1592
|
const id = option("--id");
|
|
1570
1593
|
if (!id || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)) throw new Error("Provide a UUID with --id; reuse it when retrying this prompt.");
|
|
1571
1594
|
const filenames = attachmentNames(args.flatMap((value, index) => value === "--filename" ? [args[index + 1] ?? ""] : []));
|
|
1595
|
+
const metadata = promptMetadata(args);
|
|
1572
1596
|
const text = await readPrompt(process.stdin);
|
|
1573
|
-
console.log(JSON.stringify(await call("/apps/" + applicationGuid(projectApplication()) + "/prompts", { method: "POST", body: JSON.stringify({ clientPromptId: id, text, filenames }) })));
|
|
1597
|
+
console.log(JSON.stringify(await call("/apps/" + applicationGuid(projectApplication()) + "/prompts", { method: "POST", body: JSON.stringify({ clientPromptId: id, text, filenames, ...metadata }) })));
|
|
1574
1598
|
break;
|
|
1575
1599
|
}
|
|
1576
1600
|
case "ship": {
|