@iceinvein/agent-skills 0.1.39 → 0.2.0

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.
Files changed (148) hide show
  1. package/README.md +18 -2
  2. package/dist/cli/index.js +105 -28
  3. package/package.json +1 -1
  4. package/skills/index.json +14 -2
  5. package/skills/magpie/README.md +2 -1
  6. package/skills/magpie/SKILL.md +138 -45
  7. package/skills/magpie/bin/magpie.ts +43 -0
  8. package/skills/magpie/fixtures/example-pr/brief.json +18 -0
  9. package/skills/magpie/fixtures/fake-gh-nodiff.sh +38 -0
  10. package/skills/magpie/fixtures/fake-gh.sh +14 -0
  11. package/skills/magpie/package.json +1 -1
  12. package/skills/magpie/references/peer-review.md +7 -2
  13. package/skills/magpie/references/scout.md +90 -0
  14. package/skills/magpie/references/specialists.md +117 -6
  15. package/skills/magpie/scripts/__tests__/cli.test.ts +101 -1
  16. package/skills/magpie/scripts/__tests__/dedupe-cmd.test.ts +187 -0
  17. package/skills/magpie/scripts/__tests__/diff-chunks.test.ts +51 -0
  18. package/skills/magpie/scripts/__tests__/filter-diff-preservation.test.ts +54 -0
  19. package/skills/magpie/scripts/__tests__/findings-files.test.ts +35 -0
  20. package/skills/magpie/scripts/__tests__/gh.test.ts +90 -0
  21. package/skills/magpie/scripts/__tests__/git-diff.test.ts +83 -0
  22. package/skills/magpie/scripts/__tests__/helpers/git-fixture.ts +47 -0
  23. package/skills/magpie/scripts/__tests__/path-filter.test.ts +27 -0
  24. package/skills/magpie/scripts/__tests__/preview-cmd.test.ts +16 -0
  25. package/skills/magpie/scripts/__tests__/refresh.test.ts +45 -0
  26. package/skills/magpie/scripts/__tests__/render-cmd.test.ts +173 -1
  27. package/skills/magpie/scripts/__tests__/render-findings.test.ts +151 -1
  28. package/skills/magpie/scripts/__tests__/render-progress.test.ts +42 -0
  29. package/skills/magpie/scripts/__tests__/setup-cmd.test.ts +83 -1
  30. package/skills/magpie/scripts/__tests__/shard.test.ts +165 -0
  31. package/skills/magpie/scripts/__tests__/skill-lint.test.ts +207 -7
  32. package/skills/magpie/scripts/__tests__/types.test.ts +47 -0
  33. package/skills/magpie/scripts/dedupe-cmd.ts +58 -3
  34. package/skills/magpie/scripts/diff-chunks.ts +28 -0
  35. package/skills/magpie/scripts/findings-files.ts +32 -0
  36. package/skills/magpie/scripts/gh.ts +68 -14
  37. package/skills/magpie/scripts/git-diff.ts +111 -0
  38. package/skills/magpie/scripts/path-filter.ts +9 -5
  39. package/skills/magpie/scripts/preview-cmd.ts +11 -1
  40. package/skills/magpie/scripts/refresh.ts +32 -3
  41. package/skills/magpie/scripts/render-cmd.ts +35 -11
  42. package/skills/magpie/scripts/render-findings.ts +78 -2
  43. package/skills/magpie/scripts/render-progress.ts +6 -1
  44. package/skills/magpie/scripts/setup-cmd.ts +38 -1
  45. package/skills/magpie/scripts/shard.ts +171 -0
  46. package/skills/magpie/scripts/status-cmd.ts +7 -4
  47. package/skills/magpie/scripts/types.ts +50 -0
  48. package/skills/magpie/skill.json +2 -2
  49. package/skills/magpie/templates/styles.css +66 -0
  50. package/skills/migrate/README.md +194 -0
  51. package/skills/migrate/SKILL.md +197 -0
  52. package/skills/migrate/bin/migrate +15 -0
  53. package/skills/migrate/bin/migrate.ts +309 -0
  54. package/skills/migrate/biome.json +35 -0
  55. package/skills/migrate/bun.lock +24 -0
  56. package/skills/migrate/docs/architecture.md +294 -0
  57. package/skills/migrate/docs/reference.md +590 -0
  58. package/skills/migrate/fixtures/tiny-express/GROUND-TRUTH.md +39 -0
  59. package/skills/migrate/fixtures/tiny-express/app.js +29 -0
  60. package/skills/migrate/fixtures/tiny-express/cron.js +6 -0
  61. package/skills/migrate/fixtures/tiny-express/reports/daily-users.json +6 -0
  62. package/skills/migrate/fixtures/tiny-express/schema.sql +12 -0
  63. package/skills/migrate/fixtures/tiny-express/settings.json +4 -0
  64. package/skills/migrate/fixtures/tiny-express/views/users.html +9 -0
  65. package/skills/migrate/fixtures/tiny-webforms/Controllers/UsersController.cs +68 -0
  66. package/skills/migrate/fixtures/tiny-webforms/Default.aspx +7 -0
  67. package/skills/migrate/fixtures/tiny-webforms/Default.aspx.cs +14 -0
  68. package/skills/migrate/fixtures/tiny-webforms/GROUND-TRUTH.md +50 -0
  69. package/skills/migrate/fixtures/tiny-webforms/Integrations/BillingClient.cs +16 -0
  70. package/skills/migrate/fixtures/tiny-webforms/Jobs/NightlyDigestJob.cs +33 -0
  71. package/skills/migrate/fixtures/tiny-webforms/Reports/DailyUsers.rdl +11 -0
  72. package/skills/migrate/fixtures/tiny-webforms/Schema.sql +12 -0
  73. package/skills/migrate/fixtures/tiny-webforms/Site.master +16 -0
  74. package/skills/migrate/fixtures/tiny-webforms/Users.aspx +8 -0
  75. package/skills/migrate/fixtures/tiny-webforms/Users.aspx.cs +14 -0
  76. package/skills/migrate/fixtures/tiny-webforms/web.config +10 -0
  77. package/skills/migrate/install.sh +68 -0
  78. package/skills/migrate/package.json +17 -0
  79. package/skills/migrate/references/phases/enumerate.md +291 -0
  80. package/skills/migrate/references/phases/extract.md +652 -0
  81. package/skills/migrate/references/phases/parity.md +275 -0
  82. package/skills/migrate/references/phases/probe.md +135 -0
  83. package/skills/migrate/references/phases/queue.md +242 -0
  84. package/skills/migrate/references/phases/seam.md +416 -0
  85. package/skills/migrate/references/recipes/README.md +116 -0
  86. package/skills/migrate/references/recipes/aspnet.md +287 -0
  87. package/skills/migrate/references/run-ops.md +280 -0
  88. package/skills/migrate/scripts/__tests__/census.test.ts +775 -0
  89. package/skills/migrate/scripts/__tests__/check.test.ts +458 -0
  90. package/skills/migrate/scripts/__tests__/citations.test.ts +156 -0
  91. package/skills/migrate/scripts/__tests__/cli.test.ts +183 -0
  92. package/skills/migrate/scripts/__tests__/concurrency.test.ts +164 -0
  93. package/skills/migrate/scripts/__tests__/config.test.ts +112 -0
  94. package/skills/migrate/scripts/__tests__/e2e-express.test.ts +1093 -0
  95. package/skills/migrate/scripts/__tests__/e2e-webforms.test.ts +1276 -0
  96. package/skills/migrate/scripts/__tests__/e2e.test.ts +320 -0
  97. package/skills/migrate/scripts/__tests__/ids.test.ts +38 -0
  98. package/skills/migrate/scripts/__tests__/import.test.ts +155 -0
  99. package/skills/migrate/scripts/__tests__/init.test.ts +192 -0
  100. package/skills/migrate/scripts/__tests__/leaks.test.ts +176 -0
  101. package/skills/migrate/scripts/__tests__/lock.test.ts +183 -0
  102. package/skills/migrate/scripts/__tests__/paths.test.ts +129 -0
  103. package/skills/migrate/scripts/__tests__/phase-cmd.test.ts +151 -0
  104. package/skills/migrate/scripts/__tests__/phases.test.ts +70 -0
  105. package/skills/migrate/scripts/__tests__/queue.test.ts +475 -0
  106. package/skills/migrate/scripts/__tests__/report.test.ts +150 -0
  107. package/skills/migrate/scripts/__tests__/run-state.test.ts +136 -0
  108. package/skills/migrate/scripts/__tests__/status-reset.test.ts +318 -0
  109. package/skills/migrate/scripts/__tests__/store.test.ts +132 -0
  110. package/skills/migrate/scripts/__tests__/validate.test.ts +54 -0
  111. package/skills/migrate/scripts/census-cmd.ts +109 -0
  112. package/skills/migrate/scripts/census.ts +342 -0
  113. package/skills/migrate/scripts/check-cmd.ts +24 -0
  114. package/skills/migrate/scripts/check.ts +376 -0
  115. package/skills/migrate/scripts/citations.ts +92 -0
  116. package/skills/migrate/scripts/config.ts +237 -0
  117. package/skills/migrate/scripts/ids.ts +31 -0
  118. package/skills/migrate/scripts/import-cmd.ts +141 -0
  119. package/skills/migrate/scripts/init-cmd.ts +118 -0
  120. package/skills/migrate/scripts/leaks.ts +184 -0
  121. package/skills/migrate/scripts/lock.ts +188 -0
  122. package/skills/migrate/scripts/paths.ts +103 -0
  123. package/skills/migrate/scripts/phase-cmd.ts +63 -0
  124. package/skills/migrate/scripts/phases.ts +113 -0
  125. package/skills/migrate/scripts/queue-cmd.ts +98 -0
  126. package/skills/migrate/scripts/queue.ts +258 -0
  127. package/skills/migrate/scripts/report-cmd.ts +47 -0
  128. package/skills/migrate/scripts/report.ts +131 -0
  129. package/skills/migrate/scripts/reset-cmd.ts +120 -0
  130. package/skills/migrate/scripts/status-cmd.ts +52 -0
  131. package/skills/migrate/scripts/store.ts +159 -0
  132. package/skills/migrate/scripts/types.ts +137 -0
  133. package/skills/migrate/scripts/validate.ts +221 -0
  134. package/skills/migrate/skill.json +33 -0
  135. package/skills/migrate/templates/config.toml +27 -0
  136. package/skills/migrate/templates/queue-item.md +17 -0
  137. package/skills/migrate/tsconfig.json +18 -0
  138. package/skills/migrate/uninstall.sh +31 -0
  139. package/skills/sluice/SKILL.md +82 -0
  140. package/skills/sluice/references/deep-channel.md +94 -0
  141. package/skills/sluice/references/finish.md +35 -0
  142. package/skills/sluice/references/intent.md +29 -0
  143. package/skills/sluice/references/review.md +42 -0
  144. package/skills/sluice/references/root-cause.md +38 -0
  145. package/skills/sluice/references/show-or-say.md +36 -0
  146. package/skills/sluice/references/test-first.md +35 -0
  147. package/skills/sluice/references/verify.md +26 -0
  148. package/skills/sluice/skill.json +32 -0
@@ -0,0 +1,12 @@
1
+ CREATE TABLE users (
2
+ id INTEGER PRIMARY KEY,
3
+ email TEXT NOT NULL,
4
+ is_active INTEGER NOT NULL DEFAULT 1
5
+ );
6
+
7
+ CREATE TABLE audit_log (
8
+ id INTEGER PRIMARY KEY,
9
+ user_id INTEGER NOT NULL,
10
+ action TEXT NOT NULL,
11
+ created_at TEXT NOT NULL
12
+ );
@@ -0,0 +1,4 @@
1
+ {
2
+ "welcomeEmailEnabled": true,
3
+ "maxUsersPerPage": 50
4
+ }
@@ -0,0 +1,9 @@
1
+ <!doctype html>
2
+ <html>
3
+ <body>
4
+ <h1>Users</h1>
5
+ <ul>
6
+ <li data-bind="email"></li>
7
+ </ul>
8
+ </body>
9
+ </html>
@@ -0,0 +1,68 @@
1
+ using System;
2
+ using System.Configuration;
3
+ using System.Data.SqlClient;
4
+ using System.Web;
5
+ using System.Web.Http;
6
+ using TinyWebForms.Integrations;
7
+
8
+ namespace TinyWebForms.Controllers
9
+ {
10
+ [RoutePrefix("api/users")]
11
+ public class UsersController : ApiController
12
+ {
13
+ private readonly BillingClient _billing = new BillingClient();
14
+
15
+ private SqlConnection OpenConnection()
16
+ {
17
+ var connStr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
18
+ var conn = new SqlConnection(connStr);
19
+ conn.Open();
20
+ return conn;
21
+ }
22
+
23
+ [HttpGet]
24
+ [Route("")]
25
+ public IHttpActionResult GetUsers()
26
+ {
27
+ using (var conn = OpenConnection())
28
+ {
29
+ var cmd = new SqlCommand("SELECT Id, Email FROM [dbo].[Users] WHERE IsActive = 1", conn);
30
+ return Ok(cmd.ExecuteReader());
31
+ }
32
+ }
33
+
34
+ /*
35
+ * Historical note: an earlier draft issued a raw UPDATE LegacyUsers SET
36
+ * migrated = 1 statement here before the API layer replaced it.
37
+ */
38
+ [HttpPost]
39
+ [Route("")]
40
+ public IHttpActionResult CreateUser(UserSignupRequest request)
41
+ {
42
+ using (var conn = OpenConnection())
43
+ {
44
+ var cmd = new SqlCommand("INSERT INTO Users (Email, IsActive) VALUES (@email, 1)", conn);
45
+ cmd.Parameters.AddWithValue("@email", request.Email);
46
+ cmd.ExecuteNonQuery();
47
+ }
48
+ var id = DateTime.UtcNow.Ticks;
49
+ HttpContext.Current.Session["PendingWelcome_" + id] = request.Email;
50
+ return Ok(new { id });
51
+ }
52
+
53
+ [HttpGet]
54
+ [Route("{id}/welcome")]
55
+ public IHttpActionResult GetWelcomeStatus(long id)
56
+ {
57
+ var email = HttpContext.Current.Session["PendingWelcome_" + id] as string;
58
+ var enabled = ConfigurationManager.AppSettings["WelcomeEmailEnabled"];
59
+ if (enabled == "true" && email != null) _billing.NotifyActivation(id);
60
+ return Ok(new { sent = email != null });
61
+ }
62
+ }
63
+
64
+ public class UserSignupRequest
65
+ {
66
+ public string Email { get; set; }
67
+ }
68
+ }
@@ -0,0 +1,7 @@
1
+ <%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.master" CodeFile="Default.aspx.cs" Inherits="TinyWebForms.DefaultPage" %>
2
+ <!-- Workflow step 1: signup screen, posts toward POST api/users, hands off to Users.aspx. -->
3
+ <asp:Content ContentPlaceHolderID="MainContent" runat="server">
4
+ <h1>Sign up</h1>
5
+ <asp:TextBox ID="EmailBox" runat="server" />
6
+ <asp:Button ID="SignupButton" runat="server" Text="Sign up" OnClick="SignupButton_Click" />
7
+ </asp:Content>
@@ -0,0 +1,14 @@
1
+ using System;
2
+ using TinyWebForms.Controllers;
3
+
4
+ namespace TinyWebForms
5
+ {
6
+ public partial class DefaultPage : System.Web.UI.Page
7
+ {
8
+ protected void SignupButton_Click(object sender, EventArgs e)
9
+ {
10
+ new UsersController().CreateUser(new UserSignupRequest { Email = EmailBox.Text });
11
+ Response.Redirect("~/Users.aspx");
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,50 @@
1
+ # Ground truth for tiny-webforms
2
+
3
+ Sixteen elements across all eight default surfaces. Any enumeration run over
4
+ this fixture must find exactly these, and the census must balance at these
5
+ totals: 5 routes, 2 tables, 1 job, 1 report, 2 screens, 1 integration, 1
6
+ workflow, 3 settings.
7
+
8
+ | surface | id | element |
9
+ | --- | --- | --- |
10
+ | routes | route-get-api-users | GET api/users |
11
+ | routes | route-post-api-users | POST api/users |
12
+ | routes | route-get-api-users-id-welcome | GET api/users/{id}/welcome |
13
+ | routes | route-default-aspx | Default.aspx |
14
+ | routes | route-users-aspx | Users.aspx |
15
+ | tables | table-users | Users |
16
+ | tables | table-audit-log | AuditLog |
17
+ | jobs | job-nightly-digest | nightly purge of AuditLog rows older than the configured cutoff |
18
+ | reports | report-daily-users | daily active users report |
19
+ | screens | screen-default | signup screen (Default.aspx) |
20
+ | screens | screen-users | users list and welcome screen (Users.aspx) |
21
+ | integrations | integration-billing-sync | outbound call to the billing system on activation |
22
+ | workflows | workflow-signup-welcome | two-page signup then welcome workflow |
23
+ | settings | setting-welcome-email-enabled | WelcomeEmailEnabled |
24
+ | settings | setting-nightly-digest-cutoff-days | NightlyDigestCutoffDays |
25
+ | settings | setting-default-connection | DefaultConnection |
26
+
27
+ ## Element-to-element touches
28
+
29
+ Eight of these elements touch another element already in this table, the
30
+ kind of touch `references/phases/enumerate.md`'s Procedure (step 4) tells a
31
+ lens to record as a `{"kind": "ledger", "id": ...}` ref, and the only edge
32
+ data `references/phases/seam.md`'s surface-affinity clustering has to
33
+ build a graph from. Kept here as prose, not as a fourth table column,
34
+ because unlike the census columns above nothing parses this: the e2e test
35
+ records these refs by hand against the ids above, the same way a real
36
+ lens would, rather than by reading this section.
37
+
38
+ - `route-get-api-users` reads `table-users`.
39
+ - `route-post-api-users` writes `table-users`.
40
+ - `route-get-api-users-id-welcome` notifies `integration-billing-sync`.
41
+ - `job-nightly-digest` purges `table-audit-log`.
42
+ - `report-daily-users` queries `table-users`.
43
+ - `workflow-signup-welcome` spans `route-post-api-users`,
44
+ `route-get-api-users-id-welcome`, and `setting-welcome-email-enabled`.
45
+ - `screen-default` posts to `route-post-api-users`: `Default.aspx.cs`'s
46
+ signup button handler calls `UsersController.CreateUser` directly, the
47
+ screen-that-posts-to-a-route example `enumerate.md`'s step 4 names as its
48
+ own canonical case.
49
+ - `screen-users` checks `route-get-api-users-id-welcome`: `Users.aspx.cs`'s
50
+ `Page_Load` calls `UsersController.GetWelcomeStatus` directly.
@@ -0,0 +1,16 @@
1
+ using System.Net.Http;
2
+
3
+ namespace TinyWebForms.Integrations
4
+ {
5
+ // Notifies the external billing system once a signed-up user is activated.
6
+ public class BillingClient
7
+ {
8
+ private readonly HttpClient _client = new HttpClient();
9
+
10
+ public void NotifyActivation(long userId)
11
+ {
12
+ var body = new StringContent("{\"userId\":" + userId + "}");
13
+ _client.PostAsync("https://billing.example.com/activations", body).Wait();
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,33 @@
1
+ using System;
2
+ using System.Configuration;
3
+ using System.Data.SqlClient;
4
+ using Quartz;
5
+
6
+ namespace TinyWebForms.Jobs
7
+ {
8
+ // Nightly purge of AuditLog rows older than the configured cutoff.
9
+ public class NightlyDigestJob : IJob
10
+ {
11
+ public void Execute(IJobExecutionContext context)
12
+ {
13
+ var cutoffDays = int.Parse(ConfigurationManager.AppSettings["NightlyDigestCutoffDays"]);
14
+ var connStr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
15
+ using (var conn = new SqlConnection(connStr))
16
+ {
17
+ var cmd = new SqlCommand("DELETE FROM dbo.AuditLog WHERE CreatedAt < @cutoff", conn);
18
+ cmd.Parameters.AddWithValue("@cutoff", DateTime.UtcNow.AddDays(-cutoffDays));
19
+ conn.Open();
20
+ cmd.ExecuteNonQuery();
21
+ }
22
+ }
23
+ }
24
+
25
+ public static class NightlyDigestJobScheduler
26
+ {
27
+ public static void Register(IScheduler scheduler)
28
+ {
29
+ var job = JobBuilder.Create<NightlyDigestJob>().WithIdentity("nightly-digest").Build();
30
+ scheduler.ScheduleJob(job, TriggerBuilder.Create().WithCronSchedule("0 0 2 * * ?").Build());
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition">
3
+ <DataSets>
4
+ <DataSet Name="DailyUsers">
5
+ <Query>
6
+ <CommandText>SELECT COUNT(*) AS ActiveUsers FROM Users WHERE IsActive = 1</CommandText>
7
+ </Query>
8
+ </DataSet>
9
+ </DataSets>
10
+ <Description>Daily count of active users</Description>
11
+ </Report>
@@ -0,0 +1,12 @@
1
+ CREATE TABLE Users (
2
+ Id INT PRIMARY KEY,
3
+ Email NVARCHAR(200) NOT NULL,
4
+ IsActive BIT NOT NULL DEFAULT 1
5
+ );
6
+
7
+ CREATE TABLE AuditLog (
8
+ Id INT PRIMARY KEY,
9
+ UserId INT NOT NULL,
10
+ Action NVARCHAR(100) NOT NULL,
11
+ CreatedAt DATETIME NOT NULL
12
+ );
@@ -0,0 +1,16 @@
1
+ <%@ Master Language="C#" %>
2
+ <!-- Nav lives here, not in a sitemap or _Layout.cshtml: the WebForms half of this mixed app. -->
3
+ <!DOCTYPE html>
4
+ <html>
5
+ <head><title>Tiny WebForms</title></head>
6
+ <body>
7
+ <form runat="server">
8
+ <nav>
9
+ <asp:HyperLink runat="server" NavigateUrl="~/Default.aspx">Home</asp:HyperLink>
10
+ <asp:HyperLink runat="server" NavigateUrl="~/Users.aspx">Users</asp:HyperLink>
11
+ <a href="~/Reports/DailyUsers">Daily active users report</a>
12
+ </nav>
13
+ <asp:ContentPlaceHolder ID="MainContent" runat="server" />
14
+ </form>
15
+ </body>
16
+ </html>
@@ -0,0 +1,8 @@
1
+ <%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.master" CodeFile="Users.aspx.cs" Inherits="TinyWebForms.UsersPage" %>
2
+ <!-- Workflow step 2: lands here after signup, checks api/users/{id}/welcome. -->
3
+ <asp:Content ContentPlaceHolderID="MainContent" runat="server">
4
+ <h1>Users</h1>
5
+ <asp:Repeater ID="UsersList" runat="server">
6
+ <ItemTemplate><%# Eval("Email") %></ItemTemplate>
7
+ </asp:Repeater>
8
+ </asp:Content>
@@ -0,0 +1,14 @@
1
+ using System;
2
+ using TinyWebForms.Controllers;
3
+
4
+ namespace TinyWebForms
5
+ {
6
+ public partial class UsersPage : System.Web.UI.Page
7
+ {
8
+ protected void Page_Load(object sender, EventArgs e)
9
+ {
10
+ var id = long.Parse(Request.QueryString["id"] ?? "0");
11
+ new UsersController().GetWelcomeStatus(id);
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <configuration>
3
+ <appSettings>
4
+ <add key="WelcomeEmailEnabled" value="true" />
5
+ <add key="NightlyDigestCutoffDays" value="30" />
6
+ </appSettings>
7
+ <connectionStrings>
8
+ <add name="DefaultConnection" connectionString="Data Source=.;Initial Catalog=TinyWebForms;Integrated Security=True" providerName="System.Data.SqlClient" />
9
+ </connectionStrings>
10
+ </configuration>
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # This script is run by agent-skills as a postinstall step after the migrate
5
+ # skill bundle has been written to disk. Its only job is to put the migrate
6
+ # CLI on PATH and record where it linked, so uninstall.sh can clean up.
7
+
8
+ SOURCE_DIR="$(cd "$(dirname "$0")" && pwd)"
9
+ BIN_SOURCE="$SOURCE_DIR/bin/migrate"
10
+ STATE_FILE="$SOURCE_DIR/.installed-cli-path"
11
+
12
+ if [ ! -f "$BIN_SOURCE" ]; then
13
+ echo "migrate postinstall: bin/migrate missing at $BIN_SOURCE" >&2
14
+ exit 1
15
+ fi
16
+
17
+ chmod +x "$BIN_SOURCE" || true
18
+
19
+ install_link() {
20
+ local dest_dir="$1"
21
+ local dest="$dest_dir/migrate"
22
+
23
+ if [ ! -d "$dest_dir" ]; then
24
+ mkdir -p "$dest_dir" 2>/dev/null || return 1
25
+ fi
26
+ if [ ! -w "$dest_dir" ]; then
27
+ return 1
28
+ fi
29
+ if [ -e "$dest" ] && [ ! -L "$dest" ]; then
30
+ echo " skipping $dest_dir (a non-symlink migrate already exists there)"
31
+ return 2
32
+ fi
33
+
34
+ ln -snf "$BIN_SOURCE" "$dest"
35
+ echo " linked $dest -> $BIN_SOURCE"
36
+ printf '%s\n' "$dest" > "$STATE_FILE"
37
+ return 0
38
+ }
39
+
40
+ echo "Installing migrate CLI on PATH:"
41
+
42
+ CLI_INSTALL_DIR=""
43
+ if install_link "/usr/local/bin"; then
44
+ CLI_INSTALL_DIR="/usr/local/bin"
45
+ elif install_link "$HOME/.local/bin"; then
46
+ CLI_INSTALL_DIR="$HOME/.local/bin"
47
+ else
48
+ echo " Could not write to /usr/local/bin or ~/.local/bin."
49
+ echo " Add this alias to your shell rc instead:"
50
+ echo " alias migrate='bun $BIN_SOURCE.ts'"
51
+ fi
52
+
53
+ if [ -n "$CLI_INSTALL_DIR" ]; then
54
+ case ":$PATH:" in
55
+ *":$CLI_INSTALL_DIR:"*) ;;
56
+ *)
57
+ echo ""
58
+ echo " Note: $CLI_INSTALL_DIR is not on your PATH."
59
+ echo " Add this to ~/.zshrc or ~/.bashrc:"
60
+ echo " export PATH=\"$CLI_INSTALL_DIR:\$PATH\""
61
+ ;;
62
+ esac
63
+ fi
64
+
65
+ echo ""
66
+ echo "Verify:"
67
+ echo " migrate --version"
68
+ echo " migrate --help"
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "migrate",
3
+ "version": "0.2.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "test": "bun test",
8
+ "lint": "biome check .",
9
+ "lint:fix": "biome check --write .",
10
+ "typecheck": "tsc --noEmit"
11
+ },
12
+ "dependencies": {},
13
+ "devDependencies": {
14
+ "@types/bun": "^1.2.0",
15
+ "typescript": "^5.9.0"
16
+ }
17
+ }