@akanjs/cli 3.0.0-beta.3 → 3.0.0-beta.31
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/.build-stamp +1 -1
- package/CodeAgent-tbdpdjat.js +9 -0
- package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
- package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
- package/CodeTui-my2x5fah.js +1457 -0
- package/README.md +3 -0
- package/TunnelShare-cwh9ezsm.js +9 -0
- package/{agent.command-d2gfxfck.js → agent.command-vz60x05c.js} +8 -9
- package/akanCode.js +102 -0
- package/application.command-pxqfjrqm.js +241 -0
- package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-shnfyfdy.js} +121 -77
- package/buildBatch.proc.js +120 -32
- package/cloud.command-9v9tpgps.js +95 -0
- package/cloud.script-baqdthnz.js +20 -0
- package/code.command-13h14j25.js +154 -0
- package/commandManifest.json +1 -1
- package/consoleToStderr-h5bryj94.js +7 -0
- package/context.command-x1hbasm5.js +48 -0
- package/context.runner-kqbjjea1.js +21 -0
- package/{dependencyScanner-shs82ynp.js → dependencyScanner-06z2dmrr.js} +2 -2
- package/{devTui-40ggmd99.js → devTui-q7k7bakd.js} +122 -40
- package/fileSys-wzzrntkw.js +9 -0
- package/guideline.command-vfk11hpj.js +42 -0
- package/guidelines/agentRule/agentRule.instruction.md +209 -33
- package/guidelines/conventions/conventions.instruction.md +144 -41
- package/guidelines/fieldRule/fieldRule.instruction.md +1 -0
- package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
- package/guidelines/queryRule/queryRule.instruction.md +21 -7
- package/guidelines/runtimeRule/runtimeRule.instruction.md +271 -6
- package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
- package/guidelines/transportRule/transportRule.instruction.md +51 -0
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +20 -0
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
- package/incrementalBuilder.proc.js +564 -109
- package/{index-mak3cd28.js → index-1skctzbq.js} +137 -255
- package/{index-kcxmv48c.js → index-2ahj896a.js} +45 -79
- package/index-2wc41k5w.js +49 -0
- package/index-3hx1z96c.js +87 -0
- package/{index-hwkygn9s.js → index-48k96p55.js} +325 -36
- package/{index-q0y2jq9j.js → index-52w0fvh8.js} +21 -4
- package/index-7md2g9vw.js +6 -0
- package/index-7yf7rnjg.js +53 -0
- package/{index-gyd220p2.js → index-84r80zdx.js} +554 -577
- package/{index-zry5nz81.js → index-8psse8dw.js} +51 -30
- package/index-947t6zm4.js +1119 -0
- package/index-94s080qm.js +266 -0
- package/index-9dp031by.js +12 -0
- package/index-9s5zga3q.js +4300 -0
- package/{index-ws5e0j51.js → index-arnkqb6f.js} +43 -26
- package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
- package/index-c6eggbee.js +123 -0
- package/{index-4edzf1gr.js → index-cxafpw23.js} +77 -150
- package/index-d2242ksy.js +99 -0
- package/index-d5yn19ef.js +700 -0
- package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
- package/{index-2tv3fdx4.js → index-e52z7psd.js} +1212 -1458
- package/{index-a64esmtb.js → index-ew8dna9s.js} +523 -1022
- package/{index-7737gxcp.js → index-f50dy7yq.js} +107 -241
- package/index-f8q701fb.js +1003 -0
- package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
- package/{index-j9yhg404.js → index-ksq4t16z.js} +4 -7
- package/index-nhhrjvk1.js +187 -0
- package/index-p6pbz9n5.js +25 -0
- package/index-ptshj7y1.js +2729 -0
- package/{index-fz5q3gd7.js → index-q9q7x4zj.js} +10 -17
- package/{index-pnqbkf5p.js → index-qk9vv9hm.js} +6 -2
- package/{index-600zhnve.js → index-rqxa9r98.js} +75 -203
- package/{index-ne2qy0nk.js → index-smbecayj.js} +12 -12
- package/{index-ktb5njgy.js → index-vcdxpmsx.js} +49 -99
- package/index-wa5jbxj1.js +760 -0
- package/index-ymnqrsxm.js +69 -0
- package/{index-v0qh106m.js → index-zc90rh75.js} +961 -892
- package/{index-259dsnz3.js → index-zvr7wfyg.js} +5 -8
- package/{index-h7yw2z9n.js → index-zzvvc845.js} +8 -14
- package/index.js +23 -22
- package/{library.command-nbsky672.js → library.command-m52jqc0s.js} +4 -5
- package/{localRegistry.command-yeq57wjr.js → localRegistry.command-x5vs1z43.js} +23 -42
- package/{module.command-29vqzrh8.js → module.command-ty3k6rwd.js} +8 -11
- package/{package.command-axv0abmn.js → package.command-hphdh4g4.js} +6 -7
- package/package.json +15 -7
- package/{page.command-vs9s3zrh.js → page.command-5aq8mzvq.js} +4 -5
- package/{primitive.command-cbxmqbtc.js → primitive.command-adwj84kx.js} +9 -22
- package/prompter-76k56b37.js +8 -0
- package/{quality.command-gmbs7nws.js → quality.command-y10kea2f.js} +205 -377
- package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
- package/{repair.command-bqsjptsj.js → repair.command-v7mwqvjh.js} +11 -35
- package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
- package/{scalar.command-6k1vhe9s.js → scalar.command-pg3gneer.js} +7 -10
- package/skills/akan-code/SKILL.md +130 -0
- package/skills/akan-debug/SKILL.md +42 -0
- package/skills/akan-deps/SKILL.md +50 -0
- package/skills/akan-err/SKILL.md +39 -0
- package/skills/akan-module/SKILL.md +45 -0
- package/skills/akan-scaffold/SKILL.md +76 -0
- package/skills/akan-scalar/SKILL.md +52 -0
- package/skills/akan-service/SKILL.md +34 -0
- package/skills/akan-store/SKILL.md +67 -0
- package/skills/akan-ui/SKILL.md +63 -0
- package/skills/akan-validate/SKILL.md +44 -0
- package/{subspace.command-fwjfcts7.js → subspace.command-ejdmvbq7.js} +138 -67
- package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
- package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
- package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
- package/templates/appSample/lib/task/task.abstract.ts +12 -32
- package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
- package/templates/appSample/lib/task/task.signal.test.ts +15 -1
- package/templates/appSample/lib/task/task.signal.ts +1 -1
- package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
- package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
- package/templates/client.ts +7 -30
- package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
- package/templates/crudPages/[__model__Id]/page.tsx +2 -1
- package/templates/crudPages/new/page.tsx +2 -1
- package/templates/crudPages/page.tsx +2 -1
- package/templates/crudSinglePage/page.tsx +2 -1
- package/templates/lib/__lib/lib.dictionary.ts +0 -2
- package/templates/lib/__lib/lib.document.ts +0 -2
- package/templates/lib/sig.ts +8 -30
- package/templates/localDev/docker-compose.yaml.template +3 -14
- package/templates/module/__model__.signal.ts +12 -4
- package/templates/pkgRoot/tsconfig.json.template +2 -7
- package/templates/server.ts +1 -3
- package/templates/service/__model__.abstract.md.template +8 -0
- package/templates/workspaceRoot/.gitignore.template +0 -1
- package/templates/workspaceRoot/package.json.template +1 -3
- package/tunnel.command-rz9qf230.js +129 -0
- package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/workflow.command-6r809r2z.js +79 -0
- package/{workspace.command-8s050m0h.js → workspace.command-8g3cw7jd.js} +77 -109
- package/abstractCompactor-mjh5ppsq.js +0 -101
- package/application.command-pj2m7584.js +0 -204
- package/applicationReleasePackager-4yasxwv9.js +0 -244
- package/capacitorApp-36rbr858.js +0 -12
- package/cloud.command-jshwdq22.js +0 -93
- package/context.command-ez8a0zyz.js +0 -80
- package/devTuiView-c08ccbat.js +0 -9
- package/getDirname-dr3jz1xg.js +0 -7
- package/guideline.command-xmqwx8zm.js +0 -359
- package/guidelines/agentRule/agentRule.generate.json +0 -31
- package/guidelines/componentRule/componentRule.generate.json +0 -31
- package/guidelines/conventions/conventions.generate.json +0 -25
- package/guidelines/cssRule/cssRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
- package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
- package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
- package/guidelines/enumConstant/enumConstant.generate.json +0 -31
- package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
- package/guidelines/fieldRule/fieldRule.generate.json +0 -31
- package/guidelines/framework/framework.generate.json +0 -32
- package/guidelines/mcpRule/mcpRule.generate.json +0 -35
- package/guidelines/modelConstant/modelConstant.generate.json +0 -32
- package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
- package/guidelines/modelDocument/modelDocument.generate.json +0 -31
- package/guidelines/modelService/modelService.generate.json +0 -31
- package/guidelines/modelSignal/modelSignal.generate.json +0 -31
- package/guidelines/modelStore/modelStore.generate.json +0 -31
- package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
- package/guidelines/modelUnit/modelUnit.generate.json +0 -31
- package/guidelines/modelUtil/modelUtil.generate.json +0 -31
- package/guidelines/modelView/modelView.generate.json +0 -31
- package/guidelines/modelZone/modelZone.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
- package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
- package/guidelines/queryRule/queryRule.generate.json +0 -31
- package/guidelines/recipeRule/recipeRule.generate.json +0 -31
- package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
- package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
- package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
- package/guidelines/scalarModule/scalarModule.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
- package/guidelines/ssrRule/ssrRule.generate.json +0 -31
- package/guidelines/transportRule/transportRule.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
- package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
- package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
- package/index-2hq52jq3.js +0 -465
- package/index-47pj3aee.js +0 -76
- package/index-6wwzs1bc.js +0 -7
- package/index-8pm30m73.js +0 -841
- package/index-kn1h7p1x.js +0 -560
- package/index-meh558jy.js +0 -65
- package/index-rwg2aa4f.js +0 -229
- package/index-w8kmx1b6.js +0 -2176
- package/index-wt7qrtd4.js +0 -1516
- package/templates/__scalar/__model__/__model__.abstract.md +0 -28
- package/templates/module/__model__.abstract.md +0 -28
- package/templates/service/__model__.abstract.md +0 -28
- package/templates/workspaceRoot/patches/react-dom@19.2.7.patch.template +0 -62
- package/workflow.command-nwpcdc8p.js +0 -107
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import"./index-52w0fvh8.js";
|
|
3
|
+
import {
|
|
4
|
+
GlobalConfig
|
|
5
|
+
} from "./index-94s080qm.js";
|
|
6
|
+
import {
|
|
7
|
+
Workspace,
|
|
8
|
+
command
|
|
9
|
+
} from "./index-1skctzbq.js";
|
|
10
|
+
import"./index-e52z7psd.js";
|
|
11
|
+
import {
|
|
12
|
+
PlatformTestRun
|
|
13
|
+
} from "./index-947t6zm4.js";
|
|
14
|
+
import"./index-48k96p55.js";
|
|
15
|
+
import"./index-f8q701fb.js";
|
|
16
|
+
import"./index-zvr7wfyg.js";
|
|
17
|
+
import"./index-zc90rh75.js";
|
|
18
|
+
import"./index-7md2g9vw.js";
|
|
19
|
+
import"./index-2ahj896a.js";
|
|
20
|
+
import"./index-arnkqb6f.js";
|
|
21
|
+
import {
|
|
22
|
+
CloudScript2
|
|
23
|
+
} from "./index-8psse8dw.js";
|
|
24
|
+
import"./index-ksq4t16z.js";
|
|
25
|
+
|
|
26
|
+
// pkgs/@akanjs/cli/cloud/cloud.command.ts
|
|
27
|
+
var localRegistryUrl = () => process.env.AKAN_NPM_REGISTRY ?? "http://127.0.0.1:4873";
|
|
28
|
+
var resolveRegistryUrl = (registry) => registry === "local" ? localRegistryUrl() : undefined;
|
|
29
|
+
|
|
30
|
+
class CloudCommand extends command("cloud", [CloudScript2], ({ public: target }) => ({
|
|
31
|
+
login: target({ desc: "Login to Akan Cloud services" }).option("host", String, { desc: "host of the cloud", default: GlobalConfig.akanCloudHost }).with(Workspace).exec(async function(host, workspace) {
|
|
32
|
+
await this.cloudScript.login(workspace, host);
|
|
33
|
+
}),
|
|
34
|
+
logout: target({ desc: "Logout from Akan Cloud services" }).option("host", String, { desc: "host of the cloud", default: GlobalConfig.akanCloudHost }).with(Workspace).exec(async function(host, workspace) {
|
|
35
|
+
await this.cloudScript.logout(workspace, host);
|
|
36
|
+
}),
|
|
37
|
+
deployAkan: target({ devOnly: true, desc: "Deploy Akan.js framework to cloud (internal use)" }).option("test", Boolean, { desc: "test the deployment", default: true }).option("registry", String, {
|
|
38
|
+
desc: "registry target for publishing Akan packages",
|
|
39
|
+
ask: "Select a registry target",
|
|
40
|
+
enum: [
|
|
41
|
+
{ label: "local", value: "local" },
|
|
42
|
+
{ label: "npm", value: "npm" }
|
|
43
|
+
]
|
|
44
|
+
}).option("platforms", String, {
|
|
45
|
+
desc: "platforms to test on besides this machine, comma-separated: linux, windows (none to skip)",
|
|
46
|
+
default: "linux,windows"
|
|
47
|
+
}).with(Workspace).exec(async function(test, registry, platforms, workspace) {
|
|
48
|
+
await this.cloudScript.deployAkan(workspace, {
|
|
49
|
+
test,
|
|
50
|
+
registryUrl: resolveRegistryUrl(registry),
|
|
51
|
+
platforms: PlatformTestRun.parsePlatforms(platforms)
|
|
52
|
+
});
|
|
53
|
+
}),
|
|
54
|
+
testPlatforms: target({
|
|
55
|
+
devOnly: true,
|
|
56
|
+
desc: "Run the Akan package suites on Linux (Docker) and Windows (SSH) against a snapshot of this tree"
|
|
57
|
+
}).option("platforms", String, {
|
|
58
|
+
desc: "platforms to test on, comma-separated: linux, windows",
|
|
59
|
+
default: "linux,windows"
|
|
60
|
+
}).option("pkgs", String, {
|
|
61
|
+
flag: "k",
|
|
62
|
+
desc: "packages to test, comma-separated (default: every Akan package)",
|
|
63
|
+
nullable: true
|
|
64
|
+
}).with(Workspace).exec(async function(platforms, pkgs, workspace) {
|
|
65
|
+
await this.cloudScript.testPlatforms(workspace, {
|
|
66
|
+
platforms: PlatformTestRun.parsePlatforms(platforms),
|
|
67
|
+
pkgs: pkgs?.split(",").map((pkg) => pkg.trim()).filter(Boolean)
|
|
68
|
+
});
|
|
69
|
+
}),
|
|
70
|
+
update: target({ desc: "Update Akan.js framework to the latest version" }).with(Workspace).option("tag", String, {
|
|
71
|
+
desc: "tag of the update",
|
|
72
|
+
default: "latest",
|
|
73
|
+
enum: ["latest", "dev", "canary", "beta", "rc", "alpha"]
|
|
74
|
+
}).option("registry", String, {
|
|
75
|
+
desc: "registry target for resolving Akan packages",
|
|
76
|
+
ask: "Select a registry target",
|
|
77
|
+
enum: [
|
|
78
|
+
{ label: "npm", value: "npm" },
|
|
79
|
+
{ label: "local", value: "local" }
|
|
80
|
+
],
|
|
81
|
+
default: process.env.USE_AKANJS_PKGS === "true" ? undefined : "npm"
|
|
82
|
+
}).exec(async function(workspace, tag, registry) {
|
|
83
|
+
await this.cloudScript.update(workspace, tag, { registryUrl: resolveRegistryUrl(registry) });
|
|
84
|
+
}),
|
|
85
|
+
downloadEnv: target({ desc: "Download environment variables from cloud or SCP server" }).option("host", String, { desc: "host of the cloud to target", default: GlobalConfig.akanCloudHost }).with(Workspace).exec(async function(host, workspace) {
|
|
86
|
+
await this.cloudScript.downloadEnv(workspace, undefined, { host });
|
|
87
|
+
}),
|
|
88
|
+
uploadEnv: target({ desc: "Upload environment variables to cloud or SCP server" }).option("host", String, { desc: "host of the cloud to target", default: GlobalConfig.akanCloudHost }).with(Workspace).exec(async function(host, workspace) {
|
|
89
|
+
await this.cloudScript.uploadEnv(workspace, { host });
|
|
90
|
+
})
|
|
91
|
+
})) {
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
CloudCommand
|
|
95
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
CloudScript2
|
|
4
|
+
} from "./index-8psse8dw.js";
|
|
5
|
+
import"./index-947t6zm4.js";
|
|
6
|
+
import"./index-arnkqb6f.js";
|
|
7
|
+
import"./index-zc90rh75.js";
|
|
8
|
+
import"./index-ksq4t16z.js";
|
|
9
|
+
import"./index-zvr7wfyg.js";
|
|
10
|
+
import"./index-f8q701fb.js";
|
|
11
|
+
import"./index-94s080qm.js";
|
|
12
|
+
import"./index-1skctzbq.js";
|
|
13
|
+
import"./index-7md2g9vw.js";
|
|
14
|
+
import"./index-48k96p55.js";
|
|
15
|
+
import"./index-e52z7psd.js";
|
|
16
|
+
import"./index-2ahj896a.js";
|
|
17
|
+
import"./index-52w0fvh8.js";
|
|
18
|
+
export {
|
|
19
|
+
CloudScript2 as CloudScript
|
|
20
|
+
};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Workspace,
|
|
4
|
+
runner,
|
|
5
|
+
script,
|
|
6
|
+
command
|
|
7
|
+
} from "./index-1skctzbq.js";
|
|
8
|
+
import"./index-52w0fvh8.js";
|
|
9
|
+
import"./index-e52z7psd.js";
|
|
10
|
+
import {
|
|
11
|
+
akanCodeDefaultModel2,
|
|
12
|
+
CodeAgentStreamPrinter2
|
|
13
|
+
} from "./index-c6eggbee.js";
|
|
14
|
+
|
|
15
|
+
// pkgs/@akanjs/cli/code/code.runner.ts
|
|
16
|
+
import { codeAgentPresets, isCodeAgentPresetName } from "akanjs/common";
|
|
17
|
+
|
|
18
|
+
class CodeRunner extends runner("code") {
|
|
19
|
+
async serve(options, listen) {
|
|
20
|
+
await import("./consoleToStderr-h5bryj94.js");
|
|
21
|
+
const [{ CodeAgent }, { CodeAgentRpcHost }, { CodeAgentRpcListener }] = await Promise.all([
|
|
22
|
+
import("./CodeAgent-tbdpdjat.js"),
|
|
23
|
+
import("./CodeAgentRpcHost-p7h6n2hp.js"),
|
|
24
|
+
import("./CodeAgentRpcListener-7p7z5dd7.js")
|
|
25
|
+
]);
|
|
26
|
+
const address = listen ? CodeAgentRpcListener.parse(listen) : null;
|
|
27
|
+
const agent = await CodeAgent.create({ ...await CodeRunner.#agentOptions(options, true), mode: "rpc" });
|
|
28
|
+
if (!address)
|
|
29
|
+
return await new CodeAgentRpcHost(agent).serve();
|
|
30
|
+
const listener = new CodeAgentRpcListener(new CodeAgentRpcHost(agent, null), address).listen();
|
|
31
|
+
process.stderr.write(`akan code rpc listening on ${"unix" in address ? address.unix : `${address.hostname}:${listener.port}`}
|
|
32
|
+
`);
|
|
33
|
+
await listener.serve();
|
|
34
|
+
}
|
|
35
|
+
async tui(options, seed) {
|
|
36
|
+
const [{ CodeAgent }, { CodeTui }] = await Promise.all([
|
|
37
|
+
import("./CodeAgent-tbdpdjat.js"),
|
|
38
|
+
import("./CodeTui-my2x5fah.js")
|
|
39
|
+
]);
|
|
40
|
+
const agentOptions = await CodeRunner.#agentOptions(options, false);
|
|
41
|
+
let resume = options.resume;
|
|
42
|
+
let prompt = seed;
|
|
43
|
+
let notice;
|
|
44
|
+
for (;; ) {
|
|
45
|
+
const agent = await CodeAgent.create({ ...agentOptions, mode: "tui", ...resume ? { resume } : {} });
|
|
46
|
+
let next;
|
|
47
|
+
try {
|
|
48
|
+
next = await new CodeTui(agent, {
|
|
49
|
+
thinking: options.thinking,
|
|
50
|
+
...notice ? { notice } : {}
|
|
51
|
+
}).run(prompt);
|
|
52
|
+
} finally {
|
|
53
|
+
agent.dispose();
|
|
54
|
+
}
|
|
55
|
+
if (!next)
|
|
56
|
+
return;
|
|
57
|
+
resume = next.id;
|
|
58
|
+
notice = next.notice;
|
|
59
|
+
prompt = "";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async run(prompt, options) {
|
|
63
|
+
const { CodeAgent } = await import("./CodeAgent-tbdpdjat.js");
|
|
64
|
+
const agent = await CodeAgent.create(await CodeRunner.#agentOptions(options, false));
|
|
65
|
+
const printer = new CodeAgentStreamPrinter2({ json: options.json, thinking: options.thinking });
|
|
66
|
+
agent.on((event) => printer.print(event));
|
|
67
|
+
agent.announce();
|
|
68
|
+
try {
|
|
69
|
+
await agent.prompt(prompt);
|
|
70
|
+
await agent.waitForIdle();
|
|
71
|
+
} finally {
|
|
72
|
+
printer.finish();
|
|
73
|
+
agent.dispose();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
static async#agentOptions(options, hostAttached) {
|
|
77
|
+
const profile = CodeRunner.profileOf(options, { hostAttached });
|
|
78
|
+
return {
|
|
79
|
+
workspace: options.workspace,
|
|
80
|
+
cwd: profile.paths.root,
|
|
81
|
+
profile,
|
|
82
|
+
apps: options.app ? [options.app] : await options.workspace.getApps(),
|
|
83
|
+
model: CodeRunner.modelOf(options.model)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
static profileOf(options, { hostAttached }) {
|
|
87
|
+
if (!isCodeAgentPresetName(options.profile))
|
|
88
|
+
throw new Error(`Unknown profile: ${options.profile}. Use local, pod, review, or web.`);
|
|
89
|
+
const root = options.app ? `${options.workspace.workspaceRoot}/apps/${options.app}` : options.workspace.workspaceRoot;
|
|
90
|
+
const profile = codeAgentPresets[options.profile](root);
|
|
91
|
+
return { ...profile, ui: { ...profile.ui, canPrompt: CodeRunner.canPrompt(profile, hostAttached) } };
|
|
92
|
+
}
|
|
93
|
+
static canPrompt(profile, hostAttached) {
|
|
94
|
+
const forced = process.env.AKAN_CODE_CAN_PROMPT;
|
|
95
|
+
if (forced === "1")
|
|
96
|
+
return true;
|
|
97
|
+
if (forced === "0")
|
|
98
|
+
return false;
|
|
99
|
+
return hostAttached || profile.ui.canPrompt;
|
|
100
|
+
}
|
|
101
|
+
static modelOf(model) {
|
|
102
|
+
if (!model)
|
|
103
|
+
return;
|
|
104
|
+
const [provider, ...rest] = model.split("/");
|
|
105
|
+
if (!provider || !rest.length)
|
|
106
|
+
throw new Error(`Model must be "<provider>/<id>", e.g. ${akanCodeDefaultModel2.provider}/${akanCodeDefaultModel2.id}`);
|
|
107
|
+
return { provider, id: rest.join("/") };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// pkgs/@akanjs/cli/code/code.script.ts
|
|
112
|
+
class CodeScript extends script("code", [CodeRunner]) {
|
|
113
|
+
async run(workspace, prompt, options) {
|
|
114
|
+
const run = {
|
|
115
|
+
workspace,
|
|
116
|
+
...options.app ? { app: options.app } : {},
|
|
117
|
+
profile: options.profile,
|
|
118
|
+
...options.model ? { model: options.model } : {},
|
|
119
|
+
json: options.json,
|
|
120
|
+
thinking: options.thinking,
|
|
121
|
+
...options.resume ? { resume: options.resume } : {}
|
|
122
|
+
};
|
|
123
|
+
if (options.rpcListen)
|
|
124
|
+
return await this.codeRunner.serve(run, options.rpcListen);
|
|
125
|
+
if (options.rpc)
|
|
126
|
+
return await this.codeRunner.serve(run);
|
|
127
|
+
const interactive = options.interactive || !prompt.trim() && !options.json && !!process.stdout.isTTY;
|
|
128
|
+
if (interactive)
|
|
129
|
+
return await this.codeRunner.tui(run, prompt);
|
|
130
|
+
if (!prompt.trim())
|
|
131
|
+
throw new Error('akan code needs a prompt when it has no terminal: akan code "add a comment module"');
|
|
132
|
+
await this.codeRunner.run(prompt, run);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// pkgs/@akanjs/cli/code/code.command.ts
|
|
137
|
+
class CodeCommand extends command("code", [CodeScript], ({ public: target }) => ({
|
|
138
|
+
code: target({ desc: "Run the akan coding agent on a prompt" }).arg("prompt", String, { desc: "what the agent should do", nullable: true }).option("app", String, { desc: "narrow the agent to one app instead of the whole repo", nullable: true }).option("profile", String, { desc: "local, pod, review, or web", default: "local" }).option("model", String, { desc: "<provider>/<id>, e.g. deepseek/deepseek-flash", nullable: true }).option("json", Boolean, { desc: "print one event per line as JSON", default: false }).option("thinking", Boolean, { desc: "print the model's reasoning", default: false }).option("rpc", Boolean, { desc: "serve the agent over stdio for another process to drive", default: false }).option("rpcListen", String, {
|
|
139
|
+
desc: "serve the RPC wire on unix:<path> or tcp:[host:]<port> instead of stdio",
|
|
140
|
+
flag: "L",
|
|
141
|
+
nullable: true
|
|
142
|
+
}).option("resume", String, { desc: "continue a stored session by id", flag: "R", nullable: true }).option("interactive", Boolean, {
|
|
143
|
+
desc: "open the full-screen session even when a prompt is given",
|
|
144
|
+
flag: "i",
|
|
145
|
+
default: false
|
|
146
|
+
}).with(Workspace).exec(async function(prompt, app, profile, model, json, thinking, rpc, rpcListen, resume, interactive, workspace) {
|
|
147
|
+
const options = { app, profile, model, json, thinking, rpc, rpcListen, interactive, resume };
|
|
148
|
+
await this.codeScript.run(workspace, prompt ?? "", options);
|
|
149
|
+
})
|
|
150
|
+
})) {
|
|
151
|
+
}
|
|
152
|
+
export {
|
|
153
|
+
CodeCommand
|
|
154
|
+
};
|
package/commandManifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"byCommand":{"create-workspace":"workspace","generate-agent-rules":"workspace","lint":"workspace","lint-all":"workspace","sync-all":"workspace","init":"workspace","agent":"agent","create-application":"application","remove-application":"application","plan-slice":"application","sync":"application","
|
|
1
|
+
{"byCommand":{"create-workspace":"workspace","generate-agent-rules":"workspace","lint":"workspace","lint-all":"workspace","sync-all":"workspace","init":"workspace","agent":"agent","code":"code","create-application":"application","remove-application":"application","plan-slice":"application","sync":"application","script":"application","console":"application","logs":"application","build":"application","b":"application","typecheck":"application","t":"application","test":"application","build-ios":"application","bi":"application","build-android":"application","ba":"application","build-desktop":"application","bd":"application","start":"application","s":"application","start-ios":"application","si":"application","start-android":"application","sa":"application","start-desktop":"application","sd":"application","release-ios":"application","release-android":"application","pack-update":"application","update-keygen":"application","publish-update":"application","dbup":"application","db-export":"application","db-import":"application","dbdown":"application","create-library":"library","remove-library":"library","sync-library":"library","library-status":"library","install-library":"library","start-registry":"localRegistry","reset-registry":"localRegistry","smoke-registry":"localRegistry","version":"package","create-package":"package","remove-package":"package","sync-package":"package","build-package":"package","verify-dist-package":"package","verify-akan-publish-packages":"package","create-module":"module","remove-module":"module","create-service":"module","create-view":"module","create-unit":"module","create-template":"module","create-crud-page":"page","context":"context","doctor":"context","mcp-install":"context","mcp":"context","mcp-call":"context","login":"cloud","logout":"cloud","deploy-akan":"cloud","test-platforms":"cloud","update":"cloud","download-env":"cloud","upload-env":"cloud","subspace":"subspace","guideline":"guideline","create-scalar":"scalar","remove-scalar":"scalar","create-ui":"primitive","add-field":"primitive","add-enum-field":"primitive","quality":"quality","repair":"repair","workflow":"workflow","tunnel":"tunnel"}}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Workspace,
|
|
4
|
+
command
|
|
5
|
+
} from "./index-1skctzbq.js";
|
|
6
|
+
import"./index-52w0fvh8.js";
|
|
7
|
+
import"./index-e52z7psd.js";
|
|
8
|
+
import"./index-hj6w4ka1.js";
|
|
9
|
+
import"./index-84r80zdx.js";
|
|
10
|
+
import"./index-vcdxpmsx.js";
|
|
11
|
+
import"./index-rqxa9r98.js";
|
|
12
|
+
import"./index-f8q701fb.js";
|
|
13
|
+
import"./index-zzvvc845.js";
|
|
14
|
+
import"./index-q9q7x4zj.js";
|
|
15
|
+
import"./index-qk9vv9hm.js";
|
|
16
|
+
import"./index-nhhrjvk1.js";
|
|
17
|
+
import"./index-cxafpw23.js";
|
|
18
|
+
import"./index-7yf7rnjg.js";
|
|
19
|
+
import"./index-f50dy7yq.js";
|
|
20
|
+
import {
|
|
21
|
+
ContextScript
|
|
22
|
+
} from "./index-ymnqrsxm.js";
|
|
23
|
+
|
|
24
|
+
// pkgs/@akanjs/cli/context/context.command.ts
|
|
25
|
+
class ContextCommand extends command("context", [ContextScript], ({ public: target }) => ({
|
|
26
|
+
context: target({ desc: "Print agent-readable Akan workspace context" }).option("format", String, { desc: "output format", default: "markdown", enum: ["markdown", "json"] }).option("app", String, { desc: "app name to include", nullable: true }).option("module", String, { desc: "module name to include with abstract content", nullable: true }).with(Workspace).exec(async function(format, app, module, workspace) {
|
|
27
|
+
await this.contextScript.context(workspace, { format, app, module });
|
|
28
|
+
}),
|
|
29
|
+
doctor: target({ desc: "Report Akan workspace convention diagnostics" }).option("format", String, { desc: "output format", default: "text", enum: ["text", "json"] }).option("strict", Boolean, { desc: "treat recommended conventions as errors", default: false }).option("ios", Boolean, {
|
|
30
|
+
desc: "report iOS/native config diagnostics (placeholder bundle ids, etc.)",
|
|
31
|
+
default: false
|
|
32
|
+
}).with(Workspace).exec(async function(format, strict, ios, workspace) {
|
|
33
|
+
await this.contextScript.doctor(workspace, { format, strict, ios });
|
|
34
|
+
}),
|
|
35
|
+
mcpInstall: target({ desc: "Install the Akan MCP server config for Cursor, Claude Code, and Codex" }).arg("target", String, { desc: "cursor, claude, codex, or all", nullable: true }).option("force", Boolean, { desc: "overwrite an existing Akan MCP server entry", default: false }).option("mode", String, { desc: "MCP permission mode", default: "apply", enum: ["readonly", "plan", "apply"] }).with(Workspace).exec(async function(targetName, force, mode, workspace) {
|
|
36
|
+
await this.contextScript.mcpInstall(workspace, targetName, { force, mode });
|
|
37
|
+
}),
|
|
38
|
+
mcp: target({ desc: "Start the Akan MCP server over stdio", stdio: true }).option("mode", String, { desc: "MCP permission mode", default: "readonly", enum: ["readonly", "plan", "apply"] }).with(Workspace).exec(async function(mode, workspace) {
|
|
39
|
+
await this.contextScript.mcp(workspace, { mode });
|
|
40
|
+
}),
|
|
41
|
+
mcpCall: target({ desc: "Call one Akan MCP tool for debugging without stdio JSON-RPC" }).arg("tool", String, { desc: "MCP tool name" }).option("mode", String, { desc: "MCP permission mode", default: "readonly", enum: ["readonly", "plan", "apply"] }).option("args", String, { desc: "JSON object to pass as MCP tool arguments", nullable: true }).option("format", String, { desc: "output format", default: "json", enum: ["json"] }).with(Workspace).exec(async function(tool, mode, args, format, workspace) {
|
|
42
|
+
await this.contextScript.mcpCall(workspace, tool, { mode, args, format });
|
|
43
|
+
})
|
|
44
|
+
})) {
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
ContextCommand
|
|
48
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
ContextRunner2
|
|
4
|
+
} from "./index-rqxa9r98.js";
|
|
5
|
+
import"./index-f50dy7yq.js";
|
|
6
|
+
import"./index-7yf7rnjg.js";
|
|
7
|
+
import"./index-cxafpw23.js";
|
|
8
|
+
import"./index-q9q7x4zj.js";
|
|
9
|
+
import"./index-nhhrjvk1.js";
|
|
10
|
+
import"./index-qk9vv9hm.js";
|
|
11
|
+
import"./index-f8q701fb.js";
|
|
12
|
+
import"./index-vcdxpmsx.js";
|
|
13
|
+
import"./index-84r80zdx.js";
|
|
14
|
+
import"./index-zzvvc845.js";
|
|
15
|
+
import"./index-1skctzbq.js";
|
|
16
|
+
import"./index-e52z7psd.js";
|
|
17
|
+
import"./index-hj6w4ka1.js";
|
|
18
|
+
import"./index-52w0fvh8.js";
|
|
19
|
+
export {
|
|
20
|
+
ContextRunner2 as ContextRunner
|
|
21
|
+
};
|
|
@@ -1,37 +1,17 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "./index-
|
|
3
|
+
stripAnsi
|
|
4
|
+
} from "./index-7md2g9vw.js";
|
|
5
|
+
import {
|
|
6
|
+
writeClipboard
|
|
7
|
+
} from "./index-p6pbz9n5.js";
|
|
8
|
+
import {
|
|
9
|
+
openBrowser
|
|
10
|
+
} from "./index-9dp031by.js";
|
|
8
11
|
|
|
9
12
|
// pkgs/@akanjs/cli/application/devTui.tsx
|
|
10
13
|
import { render } from "ink";
|
|
11
14
|
|
|
12
|
-
// pkgs/@akanjs/cli/clipboard.ts
|
|
13
|
-
var clipboardCommands = () => {
|
|
14
|
-
if (process.platform === "darwin")
|
|
15
|
-
return [["pbcopy"]];
|
|
16
|
-
if (process.platform === "win32")
|
|
17
|
-
return [["clip"]];
|
|
18
|
-
return [["wl-copy"], ["xclip", "-selection", "clipboard"], ["xsel", "--clipboard", "--input"]];
|
|
19
|
-
};
|
|
20
|
-
var writeClipboard = async (text) => {
|
|
21
|
-
for (const command of clipboardCommands()) {
|
|
22
|
-
try {
|
|
23
|
-
const proc = Bun.spawn(command, {
|
|
24
|
-
stdin: new TextEncoder().encode(text),
|
|
25
|
-
stdout: "ignore",
|
|
26
|
-
stderr: "ignore"
|
|
27
|
-
});
|
|
28
|
-
if (await proc.exited === 0)
|
|
29
|
-
return true;
|
|
30
|
-
} catch {}
|
|
31
|
-
}
|
|
32
|
-
return false;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
15
|
// pkgs/@akanjs/cli/ui/DevTuiApp.tsx
|
|
36
16
|
import { Box, Text, useInput } from "ink";
|
|
37
17
|
import { useEffect, useState } from "react";
|
|
@@ -176,6 +156,8 @@ var DevTuiApp = ({ actions }) => {
|
|
|
176
156
|
actions.copyLines();
|
|
177
157
|
else if (input === "Y")
|
|
178
158
|
actions.copyPath();
|
|
159
|
+
else if (input === "s")
|
|
160
|
+
actions.copyShareUrl();
|
|
179
161
|
else if (input === "o")
|
|
180
162
|
actions.openSelected();
|
|
181
163
|
else if (input === "r")
|
|
@@ -236,12 +218,95 @@ var DevTuiApp = ({ actions }) => {
|
|
|
236
218
|
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(Text, {
|
|
237
219
|
dimColor: true,
|
|
238
220
|
wrap: "truncate",
|
|
239
|
-
children:
|
|
221
|
+
children: `${snapshot.hasShare ? "s share \xB7 " : ""}Tab next \xB7 1-9 app \xB7 \u2191\u2193 scroll (shift page) \xB7 G follow${snapshot.following ? "" : " (paused)"} \xB7 / grep${snapshot.grep ? ` (${snapshot.grep})` : ""} \xB7 e errors${snapshot.errorsOnly ? " on" : ""} \xB7 c clear \xB7 y copy \xB7 Y path \xB7 o open \xB7 r restart \xB7 q quit`
|
|
240
222
|
}, undefined, false, undefined, this)
|
|
241
223
|
]
|
|
242
224
|
}, undefined, true, undefined, this);
|
|
243
225
|
};
|
|
244
226
|
|
|
227
|
+
// pkgs/@akanjs/cli/application/devLogBuffer.ts
|
|
228
|
+
var plainTextOf = (lines, { withApp = false } = {}) => {
|
|
229
|
+
const width = withApp ? lines.reduce((max, line) => Math.max(max, line.app.length), 0) : 0;
|
|
230
|
+
return lines.map((line) => `${withApp ? `${line.app.padEnd(width)} \u2502 ` : ""}${stripAnsi(line.text)}`).join(`
|
|
231
|
+
`);
|
|
232
|
+
};
|
|
233
|
+
var HOST_SOURCE = "host";
|
|
234
|
+
var childPrefix = /^\[child:(\d+) ([a-z-]+)\] \[(?:stdout|stderr)\] /;
|
|
235
|
+
var sourceOf = (text) => {
|
|
236
|
+
const match = childPrefix.exec(text);
|
|
237
|
+
return match ? `#${match[1]} ${match[2]}` : HOST_SOURCE;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
class DevLogBuffer {
|
|
241
|
+
static defaultLimit = 5000;
|
|
242
|
+
#limit;
|
|
243
|
+
#lines = [];
|
|
244
|
+
#partial = new Map;
|
|
245
|
+
#sources = new Map;
|
|
246
|
+
#seq = 0;
|
|
247
|
+
constructor({ limit = DevLogBuffer.defaultLimit } = {}) {
|
|
248
|
+
this.#limit = Math.max(1, limit);
|
|
249
|
+
}
|
|
250
|
+
get size() {
|
|
251
|
+
return this.#lines.length;
|
|
252
|
+
}
|
|
253
|
+
sourcesOf(app) {
|
|
254
|
+
return [...this.#sources.get(app) ?? []];
|
|
255
|
+
}
|
|
256
|
+
push(app, kind, chunk) {
|
|
257
|
+
const key = `${app}:${kind}`;
|
|
258
|
+
const parts = `${this.#partial.get(key) ?? ""}${chunk}`.split(`
|
|
259
|
+
`);
|
|
260
|
+
this.#partial.set(key, parts.pop() ?? "");
|
|
261
|
+
return this.#append(app, kind, parts);
|
|
262
|
+
}
|
|
263
|
+
flushPartials() {
|
|
264
|
+
const flushed = [];
|
|
265
|
+
for (const [key, remainder] of [...this.#partial]) {
|
|
266
|
+
this.#partial.set(key, "");
|
|
267
|
+
if (!remainder)
|
|
268
|
+
continue;
|
|
269
|
+
const split = key.lastIndexOf(":");
|
|
270
|
+
const app = key.slice(0, split);
|
|
271
|
+
const kind = key.slice(split + 1) === "stderr" ? "stderr" : "stdout";
|
|
272
|
+
flushed.push(...this.#append(app, kind, [remainder]));
|
|
273
|
+
}
|
|
274
|
+
return flushed;
|
|
275
|
+
}
|
|
276
|
+
select({ app = null, source = null, grep, errorsOnly = false } = {}) {
|
|
277
|
+
const needle = grep?.trim().toLowerCase();
|
|
278
|
+
return this.#lines.filter((line) => {
|
|
279
|
+
if (app !== null && line.app !== app)
|
|
280
|
+
return false;
|
|
281
|
+
if (source !== null && line.source !== source)
|
|
282
|
+
return false;
|
|
283
|
+
if (errorsOnly && line.kind !== "stderr")
|
|
284
|
+
return false;
|
|
285
|
+
if (needle && !stripAnsi(line.text).toLowerCase().includes(needle))
|
|
286
|
+
return false;
|
|
287
|
+
return true;
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
clear(app = null) {
|
|
291
|
+
const kept = app === null ? [] : this.#lines.filter((line) => line.app !== app);
|
|
292
|
+
this.#lines.length = 0;
|
|
293
|
+
this.#lines.push(...kept);
|
|
294
|
+
}
|
|
295
|
+
#append(app, kind, texts) {
|
|
296
|
+
const known = this.#sources.get(app) ?? new Set;
|
|
297
|
+
this.#sources.set(app, known);
|
|
298
|
+
const added = texts.map((text) => {
|
|
299
|
+
const source = sourceOf(text);
|
|
300
|
+
known.add(source);
|
|
301
|
+
return { seq: ++this.#seq, app, source, kind, text };
|
|
302
|
+
});
|
|
303
|
+
this.#lines.push(...added);
|
|
304
|
+
if (this.#lines.length > this.#limit)
|
|
305
|
+
this.#lines.splice(0, this.#lines.length - this.#limit);
|
|
306
|
+
return added;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
245
310
|
// pkgs/@akanjs/cli/application/devLogWindow.ts
|
|
246
311
|
var windowOf = (lines, rows, anchor) => {
|
|
247
312
|
const height = Math.max(1, Math.trunc(rows));
|
|
@@ -313,6 +378,7 @@ class DevTui {
|
|
|
313
378
|
clear: this.#clear,
|
|
314
379
|
copyLines: this.#copyLines,
|
|
315
380
|
copyPath: this.#copyPath,
|
|
381
|
+
copyShareUrl: this.#copyShareUrl,
|
|
316
382
|
openSelected: this.#openSelected,
|
|
317
383
|
restartSelected: this.#restartSelected,
|
|
318
384
|
quit: this.#quit
|
|
@@ -348,7 +414,7 @@ class DevTui {
|
|
|
348
414
|
process.stdout.write(`${line.app} \u2502 ${line.text}
|
|
349
415
|
`);
|
|
350
416
|
for (const status of this.#statuses)
|
|
351
|
-
process.stdout.write(`${status.name} ${status.url} \u2014 ${status.state}
|
|
417
|
+
process.stdout.write(`${status.name} ${status.url}${status.shareUrl ? ` \xB7 ${status.shareUrl}` : ""} \u2014 ${status.state}
|
|
352
418
|
`);
|
|
353
419
|
const log = this.#supervisor.sessionLog;
|
|
354
420
|
for (const name of log.appNames)
|
|
@@ -403,12 +469,12 @@ class DevTui {
|
|
|
403
469
|
const logRows = Math.max(1, bodyHeight - DevTui.paneChromeRows);
|
|
404
470
|
const rows = this.#railRows();
|
|
405
471
|
const view = windowOf(this.#filtered(this.#target), logRows, this.#anchor);
|
|
406
|
-
const status = this.#
|
|
472
|
+
const status = this.#selectedStatus();
|
|
407
473
|
const railLabelWidth = rows.reduce((max, row) => Math.max(max, row.label.length + row.depth * 2), 0);
|
|
408
474
|
this.#cachedSnapshot = {
|
|
409
475
|
rows,
|
|
410
476
|
selected: this.#indexOfTarget(rows),
|
|
411
|
-
title: status ? `${status.name}${this.#target.source ? ` \xB7 ${this.#target.source}` : ""} \xB7 ${status.url} \xB7 ${status.state}${status.detail ? ` (${status.detail})` : ""}` :
|
|
477
|
+
title: status ? `${status.name}${this.#target.source ? ` \xB7 ${this.#target.source}` : ""}${status.shareUrl ? ` \xB7 \u25C8 ${status.shareUrl}` : ""} \xB7 ${status.url} \xB7 ${status.state}${status.detail ? ` (${status.detail})` : ""}` : this.#mergedTitle(),
|
|
412
478
|
lines: view.lines,
|
|
413
479
|
above: view.above,
|
|
414
480
|
below: view.below,
|
|
@@ -419,6 +485,7 @@ class DevTui {
|
|
|
419
485
|
errorsOnly: this.#errorsOnly,
|
|
420
486
|
editingGrep: this.#editingGrep,
|
|
421
487
|
notice: this.#notice,
|
|
488
|
+
hasShare: this.#statuses.some((candidate) => !!candidate.shareUrl),
|
|
422
489
|
readyCount: this.#statuses.filter((candidate) => candidate.state === "ready").length,
|
|
423
490
|
appCount: this.#statuses.length,
|
|
424
491
|
logRows,
|
|
@@ -467,8 +534,7 @@ class DevTui {
|
|
|
467
534
|
};
|
|
468
535
|
#setTarget(target) {
|
|
469
536
|
this.#target = { app: target.app ?? null, source: target.source ?? null };
|
|
470
|
-
this.#
|
|
471
|
-
this.#renderNow();
|
|
537
|
+
this.#follow();
|
|
472
538
|
}
|
|
473
539
|
#scroll = (delta) => {
|
|
474
540
|
this.#anchor = scrollAnchor(this.#filtered(this.#target), this.#snapshot().logRows, this.#anchor, delta);
|
|
@@ -480,8 +546,7 @@ class DevTui {
|
|
|
480
546
|
};
|
|
481
547
|
#setGrep = (grep) => {
|
|
482
548
|
this.#grep = grep;
|
|
483
|
-
this.#
|
|
484
|
-
this.#renderNow();
|
|
549
|
+
this.#follow();
|
|
485
550
|
};
|
|
486
551
|
#setEditingGrep = (editing) => {
|
|
487
552
|
this.#editingGrep = editing;
|
|
@@ -489,13 +554,11 @@ class DevTui {
|
|
|
489
554
|
};
|
|
490
555
|
#toggleErrorsOnly = () => {
|
|
491
556
|
this.#errorsOnly = !this.#errorsOnly;
|
|
492
|
-
this.#
|
|
493
|
-
this.#renderNow();
|
|
557
|
+
this.#follow();
|
|
494
558
|
};
|
|
495
559
|
#clear = () => {
|
|
496
560
|
this.#buffer.clear(this.#target.app ?? null);
|
|
497
|
-
this.#
|
|
498
|
-
this.#renderNow();
|
|
561
|
+
this.#follow();
|
|
499
562
|
};
|
|
500
563
|
#copyLines = () => {
|
|
501
564
|
const lines = this.#filtered(this.#target);
|
|
@@ -520,6 +583,25 @@ class DevTui {
|
|
|
520
583
|
const app = this.#target.app;
|
|
521
584
|
return (app ? [app] : log.appNames).map((name) => log.relativePathOf(name));
|
|
522
585
|
}
|
|
586
|
+
#copyShareUrl = () => {
|
|
587
|
+
const urls = this.#shareUrls();
|
|
588
|
+
if (urls.length === 0) {
|
|
589
|
+
this.#setNotice("no public share \u2014 start with --share");
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
writeClipboard(urls.join(`
|
|
593
|
+
`)).then((copied) => {
|
|
594
|
+
this.#setNotice(copied ? `copied ${urls.join(" \xB7 ")}` : urls.join(" \xB7 "));
|
|
595
|
+
});
|
|
596
|
+
};
|
|
597
|
+
#shareUrls() {
|
|
598
|
+
const app = this.#target.app;
|
|
599
|
+
return this.#statuses.filter((status) => app === null || status.name === app).map((status) => status.shareUrl).filter((url) => !!url);
|
|
600
|
+
}
|
|
601
|
+
#mergedTitle() {
|
|
602
|
+
const urls = this.#shareUrls();
|
|
603
|
+
return urls.length === 0 ? "all apps" : `all apps \xB7 \u25C8 ${urls.join(" \xB7 ")}`;
|
|
604
|
+
}
|
|
523
605
|
#setNotice(text) {
|
|
524
606
|
this.#notice = text;
|
|
525
607
|
if (this.#noticeTimer)
|