@specific.dev/cli 0.1.110 → 0.1.112
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/admin/404/index.html +1 -1
- package/dist/admin/404.html +1 -1
- package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +1 -1
- package/dist/admin/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/__next._full.txt +1 -1
- package/dist/admin/__next._head.txt +1 -1
- package/dist/admin/__next._index.txt +1 -1
- package/dist/admin/__next._tree.txt +1 -1
- package/dist/admin/_not-found/__next._full.txt +1 -1
- package/dist/admin/_not-found/__next._head.txt +1 -1
- package/dist/admin/_not-found/__next._index.txt +1 -1
- package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/admin/_not-found/__next._not-found.txt +1 -1
- package/dist/admin/_not-found/__next._tree.txt +1 -1
- package/dist/admin/_not-found/index.html +1 -1
- package/dist/admin/_not-found/index.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/databases/__next._full.txt +1 -1
- package/dist/admin/databases/__next._head.txt +1 -1
- package/dist/admin/databases/__next._index.txt +1 -1
- package/dist/admin/databases/__next._tree.txt +1 -1
- package/dist/admin/databases/index.html +1 -1
- package/dist/admin/databases/index.txt +1 -1
- package/dist/admin/fullscreen/__next._full.txt +1 -1
- package/dist/admin/fullscreen/__next._head.txt +1 -1
- package/dist/admin/fullscreen/__next._index.txt +1 -1
- package/dist/admin/fullscreen/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +1 -1
- package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._full.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._index.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/index.html +1 -1
- package/dist/admin/fullscreen/databases/index.txt +1 -1
- package/dist/admin/fullscreen/index.html +1 -1
- package/dist/admin/fullscreen/index.txt +1 -1
- package/dist/admin/index.html +1 -1
- package/dist/admin/index.txt +1 -1
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +1 -1
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +1 -1
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/mail/__next._full.txt +1 -1
- package/dist/admin/mail/__next._head.txt +1 -1
- package/dist/admin/mail/__next._index.txt +1 -1
- package/dist/admin/mail/__next._tree.txt +1 -1
- package/dist/admin/mail/index.html +1 -1
- package/dist/admin/mail/index.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
- package/dist/admin/workflows/__next._full.txt +1 -1
- package/dist/admin/workflows/__next._head.txt +1 -1
- package/dist/admin/workflows/__next._index.txt +1 -1
- package/dist/admin/workflows/__next._tree.txt +1 -1
- package/dist/admin/workflows/index.html +1 -1
- package/dist/admin/workflows/index.txt +1 -1
- package/dist/cli.js +56 -5
- package/dist/docs/temporal.md +11 -40
- package/package.json +1 -1
- /package/dist/admin/_next/static/{XxrIhY0Ur2j5au9Vfy8af → HqmZIQRPGu1hRxFYqbizq}/_buildManifest.js +0 -0
- /package/dist/admin/_next/static/{XxrIhY0Ur2j5au9Vfy8af → HqmZIQRPGu1hRxFYqbizq}/_clientMiddlewareManifest.json +0 -0
- /package/dist/admin/_next/static/{XxrIhY0Ur2j5au9Vfy8af → HqmZIQRPGu1hRxFYqbizq}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -373041,6 +373041,43 @@ function performLogin(options2 = {}) {
|
|
|
373041
373041
|
});
|
|
373042
373042
|
});
|
|
373043
373043
|
}
|
|
373044
|
+
async function performNonInteractiveLogin() {
|
|
373045
|
+
try {
|
|
373046
|
+
writeLog("auth", "Starting non-interactive login flow");
|
|
373047
|
+
const deviceAuth = await initiateDeviceAuthorization();
|
|
373048
|
+
console.log(`To authenticate, visit: ${deviceAuth.verification_uri_complete}`);
|
|
373049
|
+
console.log(`Your code: ${deviceAuth.user_code}`);
|
|
373050
|
+
console.log("");
|
|
373051
|
+
console.log("To complete login after approving, run:");
|
|
373052
|
+
console.log(` specific login --device-code ${deviceAuth.device_code}`);
|
|
373053
|
+
return { success: true };
|
|
373054
|
+
} catch (err) {
|
|
373055
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
373056
|
+
console.error(`Error: ${message}`);
|
|
373057
|
+
return { success: false, error: new Error(message) };
|
|
373058
|
+
}
|
|
373059
|
+
}
|
|
373060
|
+
async function performDeviceCodeLogin(deviceCode) {
|
|
373061
|
+
try {
|
|
373062
|
+
writeLog("auth", "Completing login with device code");
|
|
373063
|
+
console.log("Waiting for authentication...");
|
|
373064
|
+
const token = await pollUntilToken(
|
|
373065
|
+
{ device_code: deviceCode, interval: 5, expires_in: 600 },
|
|
373066
|
+
() => false
|
|
373067
|
+
);
|
|
373068
|
+
if (!token) {
|
|
373069
|
+
console.error("Error: Authentication timed out. Please try again.");
|
|
373070
|
+
return { success: false, error: new Error("Authentication timed out") };
|
|
373071
|
+
}
|
|
373072
|
+
await saveCredentialsFromToken(token);
|
|
373073
|
+
console.log(`\u2713 Logged in as ${token.user.email}`);
|
|
373074
|
+
return { success: true, userEmail: token.user.email };
|
|
373075
|
+
} catch (err) {
|
|
373076
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
373077
|
+
console.error(`Error: ${message}`);
|
|
373078
|
+
return { success: false, error: new Error(message) };
|
|
373079
|
+
}
|
|
373080
|
+
}
|
|
373044
373081
|
|
|
373045
373082
|
// src/lib/auth/credentials.ts
|
|
373046
373083
|
function getUserCredentialsDir() {
|
|
@@ -373200,7 +373237,7 @@ function trackEvent(event, properties) {
|
|
|
373200
373237
|
event,
|
|
373201
373238
|
properties: {
|
|
373202
373239
|
...properties,
|
|
373203
|
-
cli_version: "0.1.
|
|
373240
|
+
cli_version: "0.1.112",
|
|
373204
373241
|
platform: process.platform,
|
|
373205
373242
|
node_version: process.version,
|
|
373206
373243
|
project_id: getProjectId()
|
|
@@ -376768,11 +376805,25 @@ function cleanCommand(instanceKey) {
|
|
|
376768
376805
|
}
|
|
376769
376806
|
|
|
376770
376807
|
// src/commands/login.tsx
|
|
376771
|
-
async function loginCommand() {
|
|
376808
|
+
async function loginCommand(options2 = {}) {
|
|
376772
376809
|
if (isLoggedIn()) {
|
|
376773
376810
|
console.log("Already logged in.");
|
|
376774
376811
|
return;
|
|
376775
376812
|
}
|
|
376813
|
+
if (options2.deviceCode) {
|
|
376814
|
+
const result2 = await performDeviceCodeLogin(options2.deviceCode);
|
|
376815
|
+
if (!result2.success) {
|
|
376816
|
+
process.exitCode = 1;
|
|
376817
|
+
}
|
|
376818
|
+
return;
|
|
376819
|
+
}
|
|
376820
|
+
if (!isInteractive()) {
|
|
376821
|
+
const result2 = await performNonInteractiveLogin();
|
|
376822
|
+
if (!result2.success) {
|
|
376823
|
+
process.exitCode = 1;
|
|
376824
|
+
}
|
|
376825
|
+
return;
|
|
376826
|
+
}
|
|
376776
376827
|
const result = await performLogin();
|
|
376777
376828
|
if (!result.success) {
|
|
376778
376829
|
process.exitCode = 1;
|
|
@@ -376911,7 +376962,7 @@ function compareVersions(a, b) {
|
|
|
376911
376962
|
return 0;
|
|
376912
376963
|
}
|
|
376913
376964
|
async function checkForUpdate() {
|
|
376914
|
-
const currentVersion = "0.1.
|
|
376965
|
+
const currentVersion = "0.1.112";
|
|
376915
376966
|
const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
|
|
376916
376967
|
if (!response.ok) {
|
|
376917
376968
|
throw new Error(`Failed to check for updates: HTTP ${response.status}`);
|
|
@@ -377179,7 +377230,7 @@ async function projectListCommand() {
|
|
|
377179
377230
|
var program = new Command();
|
|
377180
377231
|
var env = "production";
|
|
377181
377232
|
var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
|
|
377182
|
-
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.
|
|
377233
|
+
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.112").enablePositionalOptions();
|
|
377183
377234
|
program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").addHelpText("after", `
|
|
377184
377235
|
Examples:
|
|
377185
377236
|
$ specific init
|
|
@@ -377252,7 +377303,7 @@ Examples:
|
|
|
377252
377303
|
});
|
|
377253
377304
|
program.command("beta").description("Manage beta feature flags").action(betaCommand);
|
|
377254
377305
|
program.command("update").description("Update Specific CLI to the latest version").action(updateCommand);
|
|
377255
|
-
program.command("login").description("Log in to Specific").action(loginCommand);
|
|
377306
|
+
program.command("login").description("Log in to Specific").option("--device-code <code>", "Complete login using a device code from a previous non-interactive login").action((options2) => loginCommand(options2));
|
|
377256
377307
|
program.command("logout").description("Log out of Specific").action(logoutCommand);
|
|
377257
377308
|
var commandName = process.argv[2] || "help";
|
|
377258
377309
|
trackEvent("cli_command_invoked", { command: commandName });
|
package/dist/docs/temporal.md
CHANGED
|
@@ -36,11 +36,11 @@ service "worker" {
|
|
|
36
36
|
|
|
37
37
|
Each `temporal` block exposes the following reference attributes:
|
|
38
38
|
|
|
39
|
-
| Attribute | Description | Dev value |
|
|
40
|
-
|
|
41
|
-
| `temporal.<name>.url` | gRPC address of the Temporal server | `localhost:<port>` |
|
|
42
|
-
| `temporal.<name>.namespace` | Temporal namespace | `default` |
|
|
43
|
-
| `temporal.<name>.api_key` | API key for authentication | `""` (empty, no auth in dev) |
|
|
39
|
+
| Attribute | Description | Dev value | Production value |
|
|
40
|
+
|-----------|-------------|-----------|------------------|
|
|
41
|
+
| `temporal.<name>.url` | gRPC address of the Temporal server | `localhost:<port>` | Temporal Cloud gRPC address |
|
|
42
|
+
| `temporal.<name>.namespace` | Temporal namespace | `default` | Managed namespace ID |
|
|
43
|
+
| `temporal.<name>.api_key` | API key for authentication | `""` (empty, no auth in dev) | Auto-generated API key |
|
|
44
44
|
|
|
45
45
|
These attributes can be used in service `env` blocks, both as standalone values and inside interpolated strings.
|
|
46
46
|
|
|
@@ -58,41 +58,12 @@ The `api_key` attribute returns an empty string in dev since the Temporal dev se
|
|
|
58
58
|
|
|
59
59
|
## Production
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
Running `specific deploy` automatically provisions a managed [Temporal Cloud](https://temporal.io/cloud) namespace for each `temporal` block. No manual setup is required — the same configuration works in both dev and production:
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
secret "temporal_api_key" {
|
|
68
|
-
dev {
|
|
69
|
-
required = false
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
service "worker" {
|
|
74
|
-
build = build.app
|
|
75
|
-
command = "node worker.js"
|
|
76
|
-
|
|
77
|
-
env = {
|
|
78
|
-
# Use built-in temporal block for dev
|
|
79
|
-
TEMPORAL_NAMESPACE = temporal.tasks.namespace
|
|
80
|
-
|
|
81
|
-
# Override address and API key for production via config/secret
|
|
82
|
-
TEMPORAL_ADDRESS = config.temporal_address
|
|
83
|
-
TEMPORAL_API_KEY = secret.temporal_api_key
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
dev {
|
|
87
|
-
command = "node --watch worker.js"
|
|
88
|
-
env = {
|
|
89
|
-
# In dev, use the local Temporal server
|
|
90
|
-
TEMPORAL_ADDRESS = temporal.tasks.url
|
|
91
|
-
TEMPORAL_API_KEY = temporal.tasks.api_key
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
```
|
|
63
|
+
1. A dedicated Temporal Cloud namespace is created
|
|
64
|
+
2. A service account with write access is provisioned
|
|
65
|
+
3. An API key is generated for authentication
|
|
66
|
+
4. Credentials are securely injected into your services
|
|
96
67
|
|
|
97
|
-
|
|
68
|
+
The reference attributes (`temporal.<name>.url`, `.namespace`, `.api_key`) resolve to the Temporal Cloud values in production, so no environment-specific overrides are needed.
|
|
98
69
|
<!-- /beta:temporal -->
|
package/package.json
CHANGED
/package/dist/admin/_next/static/{XxrIhY0Ur2j5au9Vfy8af → HqmZIQRPGu1hRxFYqbizq}/_buildManifest.js
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/admin/_next/static/{XxrIhY0Ur2j5au9Vfy8af → HqmZIQRPGu1hRxFYqbizq}/_ssgManifest.js
RENAMED
|
File without changes
|